; 如何計算PE頭部校驗和
;
;
;你應該已經見過LoadPE的校正PE頭checksum的功能,想給你自己的工具加一個這種功能?
;yes,it's
easy!let's GO!GO!GO!
;
;PE checksum計算演算法:
;PE檔案修改的時候一般可不用計算checksum,但是由於OS對系統檔案校驗其checksum
;因此修改PE的時候有時會需要更新其checksum值,一般可以用imagehelp.dll中的函式
;進行計算,不過實際上這玩意很簡單,我們完全可以自己來做.假設PE檔案大小x,若為奇數
;位元組則用0補足檔案使x為偶數,然後取檔案中所有的字進行帶進位加法操作(adc),最後和
;檔案大小進行帶進位加法操作(adc)得到結果即為checksum結果.當然在計算前應置pe.CheckSum域為0.
;具體見下面的cal_checksum例程.
;enjoy it.
;
YJ.Hume.冷雨
include
'%fasinc%/win32a.inc'
include '%fasinc%/pestruc.h'
struc OPENFILENAME
{
.lStructSize dd
?
.hwndOwner dd
?
.hInstance dd
?
.lpstrFilter dd ?
.lpstrCustomFilter dd ?
.nMaxCustFilter
dd ?
.nFilterIndex
dd ?
.lpstrFile
dd ?
.nMaxFile
dd ?
.lpstrFileTitle dd
?
.nMaxFileTitle dd
?
.lpstrInitialDir dd ?
.lpstrTitle dd ?
.Flags
dd ?
.nFileOffset dw ?
.nFileExtension
dw ?
.lpstrDefExt
dd ?
.lCustData
dd ?
.lpfnHook
dd ?
.lpTemplateName dd
?
.size=$-.lStructSize
}
virtual
at 0
ofn OPENFILENAME
end virtual
;-----------------------------------------
.data
opf OPENFILENAME
lpStrFilter db "PE Files",0,"*.exe;*.dll",0
db "WDM Files",0,"*.sys",0,0
zTit db "Hume's PE checkSum 計算器,2K2",0
initial_dir db ".",0
ms000
db "File OPERATION ERR!",0
fmt
db "The PE-CheckSum of Current file IS:%X",0
buf:
rb 256
.code
StArT:
mov
[opf.lStructSize],ofn.size
mov
[opf.lpstrFile],buf
mov [opf.nMaxFile],256
mov [opf.lpstrFilter],lpStrFilter
mov [opf.lpstrTitle],zTit
mov [opf.lpstrInitialDir],initial_dir
mov [opf.Flags],81000h
invoke GetOpenFileName,opf
or eax,eax
je
exit
mov eax,ofn.lpstrFile
invoke
CreateFile,[opf.lpstrFile],0x80000000,0,0,3,0,0
inc eax
je
err
dec eax
push eax
invoke
GetFileSize,eax,0
push
eax
push eax
invoke VirtualAlloc,0,eax,1000h,4
or eax,eax
je err
pop
ecx
push eax
mov esi,eax
mov edx,[esp+8]
invoke ReadFile,edx,eax,ecx,esp,0
mov edi,[esi+3ch]
add edi,esi
mov dword [edi+peh.CheckSum],0
mov ecx,[esp+4]
inc ecx
shr
ecx,1
xor ebp,ebp
clc
cal_checksum:
adc bp,word [esi]
inc
esi
inc esi
loop cal_checksum
mov ebx,[esp+4]
add
ebp,ebx
pop
eax
invoke VirtualFree,eax,ebx,4000h
pop
eax
pop eax
invoke CloseHandle,eax
invoke wsprintf,buf,fmt,ebp
invoke MessageBox,0,buf,zTit,40h
exit:
invoke ExitProcess,0
err:
invoke MessageBox,0,ms000,zTit,20h
jmp byte exit
.end StArT