#if 0 https://scz.617.cn/windows/200701102106.txt 在某些时候可能你并不想用imagehlp!CheckSumMappedFile()去计算PE文件校验和, 这个函数或许用得上。网上ASM实现很多,C实现不好找吧。 最近因为要写个程序自动剁tcpip.sys,顺便折腾了一下PE文件校验和的计算。 #endif /* * RFC 1141 : Incremental Updating of the Internet Checksum * * 2007-01-10 21:06 scz * * PE首部的CheckSum是4字节的DWORD型,计算方法与IP首部校验和非常类似,其C语 * 言实现一直不太好找,这里给一个基于IP首部校验和C实现修改后的函数。已经处 * 理了奇偶。形参base_sum为旧的CheckSum,无论原值是否正确,不必将内存中的 * 该字段清零再计算,如果清零,则base_sum也要赋成零再计算。 * * 2007-01-29 15:30 scz * * 更正了一个BUG,注意sum的数据类型是64-bits的。 */ static unsigned int pe_cksum ( unsigned short int *addr, unsigned int len, unsigned long long base_sum ) { unsigned int nleft = len; /* * 这里不同,反码加一即取负,这种变态写法仅仅是为了避免一个编译警告。 * * LONGLONG * ULONG64 * unsigned long long */ unsigned long long sum = ~base_sum + 1; unsigned short int *w = addr; unsigned short int answer = 0; /* * Our algorithm is simple, using a 32 bit accumulator (sum), we add * sequential 16 bit words to it, and at the end, fold back all the * carry bits from the top 16 bits into the lower 16 bits. */ while ( nleft > 1 ) { sum += *w++; nleft -= 2; } /* * mop up an odd byte, if necessary */ if ( 1 == nleft ) { *( unsigned char * )( &answer ) = *( unsigned char * )w ; sum += answer; } /* * add back carry outs from top 16 bits to low 16 bits * * add hi 16 to low 16 */ sum = ( sum >> 16 ) + ( sum & 0xFFFF ); /* * add carry */ sum += ( sum >> 16 ); /* * truncate to 16 bits */ answer = ( unsigned short )( sum & 0xFFFF ); /* * 这里不同 * * add len */ sum = answer + len; return( ( unsigned int )sum ); } /* end of pe_cksum */