#if 0
http://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 */