I wrote this blog a long time ago, because it is now moved to cnblogs, and after sorting it out, I will try again.
I have been engaged in computer security/virus-related things (pure learning, do not do evil) for a few years before my work. The PE file format is required. Some PE files, such as drivers, are checked during loading to ensure the integrity of the driver files. There is a lot of information on how to verify PE files. Here is an article titled An Analysis of the Windows PE checksum algorithmChecksummappedfileFor reverse analysis. The Checksum Algorithm in Windows is similar to the IP protocol checksum algorithm. The IP address checksum algorithm implements rfc1071. If you are interested in other checksum algorithms, read error detection and correction on Wiki.
However, the implementation of checksummappedfile is a little complicated and not intuitive enough. Later, when I read the wrk code, I found that the checksum algorithm implemented by the Windows Kernel During driver loading is much more concise and intuitive. I would like to share it with you:
uint32_t calc_checksum(uint32_t checksum, void *data, int length) { if (length && data != nullptr) { uint32_t sum = 0; do { sum = *(uint16_t *)data + checksum; checksum = (uint16_t)sum + (sum >> 16); data = (char *)data + 2; } while (--length); } return checksum + (checksum >> 16);}uint32_t generate_pe_checksum(void *file_base, uint32_t file_size) { uint32_t file_checksum = 0; PIMAGE_NT_HEADERS nt_headers = ImageNtHeader(file_base); if (nt_headers) { uint32_t header_size = (uintptr_t)nt_headers - (uintptr_t)file_base + ((uintptr_t)&nt_headers->OptionalHeader.CheckSum - (uintptr_t)nt_headers); uint32_t remain_size = (file_size - header_size - 4) >> 1; void *remain = &nt_headers->OptionalHeader.Subsystem; uint32_t header_checksum = calc_checksum(0, file_base, header_size >> 1); file_checksum = calc_checksum(header_checksum, remain, remain_size); if (file_size & 1){ file_checksum += (uint16_t)*((char *)file_base + file_size - 1); } } return (file_size + file_checksum);}