int PE_(bin_pe_get_actual_checksum)(RBinPEObj* pe) {
	size_t i, j, checksum_offset = 0;
	ut64 computed_cs = 0;
	int remaining_bytes;
	int shift;
	ut32 cur;
	if (!pe || !pe->nt_header_offset) {
		return 0;
	}
	const size_t buf_sz = 0x1000;
	ut32 *buf = malloc (buf_sz);
	if (!buf) {
		return 0;
	}
	if (r_buf_read_at (pe->b, 0, (ut8 *)buf, buf_sz) < 0) {
		free (buf);
		return 0;
	}
	checksum_offset = pe->nt_header_offset + 4 + sizeof (PE_(image_file_header)) + 0x40;
	for (i = 0, j = 0; i < pe->size / 4; i++) {
		cur = r_read_at_ble32 (buf, j * 4, pe->endian);
		j++;
		// skip the checksum bytes
		if (i * 4 == checksum_offset) {
			continue;
		}

		computed_cs = (computed_cs & 0xFFFFFFFF) + cur + (computed_cs >> 32);
		if (computed_cs >> 32) {
			computed_cs = (computed_cs & 0xFFFFFFFF) + (computed_cs >> 32);
		}
		if (j == buf_sz / 4) {
			if (r_buf_read_at (pe->b, (i + 1) * 4, (ut8 *)buf, buf_sz) < 0) {
				break;
			}
			j = 0;
		}
	}

	// add resultant bytes to checksum
	remaining_bytes = pe->size % 4;
	i = i * 4;
	if (remaining_bytes != 0) {
		cur = r_buf_read8_at (pe->b, i);
		shift = 8;
		for (j = 1; j < remaining_bytes; j++, shift += 8) {
			cur |= r_buf_read8_at (pe->b, i + j) << shift;
		}
		computed_cs = (computed_cs & 0xFFFFFFFF) + cur + (computed_cs >> 32);
		if (computed_cs >> 32) {
			computed_cs = (computed_cs & 0xFFFFFFFF) + (computed_cs >> 32);
		}
	}

	// 32bits -> 16bits
	computed_cs = (computed_cs & 0xFFFF) + (computed_cs >> 16);
	computed_cs = (computed_cs) + (computed_cs >> 16);
	computed_cs = (computed_cs & 0xFFFF);

	// add filesize
	computed_cs += pe->size;
	free (buf);
	return computed_cs;
}
int PE_(bin_pe_get_actual_checksum)(RBinPEObj* pe) {
	size_t i, j, checksum_offset = 0;
	ut64 computed_cs = 0;
	int remaining_bytes;
	int shift;
	ut32 cur;
	if (!pe || !pe->nt_header_offset) {
		return 0;
	}
	const size_t buf_sz = 0x1000;
	ut32 *buf = malloc (buf_sz);
	if (!buf) {
		return 0;
	}
	if (r_buf_read_at (pe->b, 0, (ut8 *)buf, buf_sz) < 0) {
		free (buf);
		return 0;
	}
	checksum_offset = pe->nt_header_offset + 4 + sizeof (PE_(image_file_header)) + 0x40;
	for (i = 0, j = 0; i < pe->size / 4; i++) {
		cur = r_read_at_ble32 (buf, j * 4, pe->endian);
		j++;
		 
		if (i * 4 == checksum_offset) {
			continue;
		}

		computed_cs = (computed_cs & 0xFFFFFFFF) + cur + (computed_cs >> 32);
		if (computed_cs >> 32) {
			computed_cs = (computed_cs & 0xFFFFFFFF) + (computed_cs >> 32);
		}
		if (j == buf_sz / 4) {
			if (r_buf_read_at (pe->b, (i + 1) * 4, (ut8 *)buf, buf_sz) < 0) {
				break;
			}
			j = 0;
		}
	}

	 
	remaining_bytes = pe->size % 4;
	i = i * 4;
	if (remaining_bytes != 0) {
		cur = r_buf_read8_at (pe->b, i);
		shift = 8;
		for (j = 1; j < remaining_bytes; j++, shift += 8) {
			cur |= r_buf_read8_at (pe->b, i + j) << shift;
		}
		computed_cs = (computed_cs & 0xFFFFFFFF) + cur + (computed_cs >> 32);
		if (computed_cs >> 32) {
			computed_cs = (computed_cs & 0xFFFFFFFF) + (computed_cs >> 32);
		}
	}

	 
	computed_cs = (computed_cs & 0xFFFF) + (computed_cs >> 16);
	computed_cs = (computed_cs) + (computed_cs >> 16);
	computed_cs = (computed_cs & 0xFFFF);

	 
	computed_cs += pe->size;
	free (buf);
	return computed_cs;
}