返回列表 发帖

如何计算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.
;                                             
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

返回列表 回复 发帖