PE6.0格式研究 (4)

作者:陆麟
转载请征得作者同意.
1999.8.28
PATCHED 1999.9.29


太忙,太忙,实在没空写程序,但是还是要搞点东西出来.
PE文件在COFF头之后就是可选头.在可选头里的第一个项,上次已经讲过了.在整个可选头里,尽管PE32和PE32+的结构是不同的,但还是有少量字段是相同的,写个结构,可以在写程序的时候省点力气.下面给出PE32和PE32+相同的部分.
typedef struct {
 WORD Magic; //0x10b if pe32,0x20b if pe64,0x107 if rom image
 BYTE MajorLinkerVersion; //
 BYTE MinorLinkerVersion; //
 DWORD SizeOfCode; //
 DWORD SizeOfInitializedData; //
 DWORD SizeOfUninitializedData; //BSS section's size
 DWORD AddressOfEntryPoint; //Entrypoint relative to image base
 DWORD BaseOfCode; //
 __int64 ImageBase; //If pe32, ImageBase>>32 is BaseOfData,
      //Imagebase&0xffff is ImageBase.
 DWORD SectionAlign; //When load into memory, each section align to
 DWORD FileAlign; //File alignment in byte.
 WORD MajorOSV; //Major Target OS Version
 WORD MinorOSV; //Minor Target OS Version
 WORD MajorImageVer; //
 WORD MinorImageVer; //
 WORD MajorSV; //Major subsystem version
 WORD MinorSV; //Minor subsystem version
 DWORD UNKNOW;
 DWORD SizeOfImage; //
 DWORD SizeOfHeards; //Size of dos-stub+PE header+section headers
 DWORD CheckSum; //
 WORD Subsystem;
 WORD DLL_Characteristics;
}_CommOptHead,*pCommOptHead;
结果应该没什么问题,因为我已经加了英文注解.其中唯一需要强调的是ImageBase字段.这个数据在PE32+里是个64位数据(__int64是MS VC编译器提供的便捷方法,标注一个64位值),在PE32里是2个值:DWORD BASEOFDATA,  DWORD IMAGEBASE. 由于BASEOFDATA数据并没有什么用,所以在规范里被删除了.其实老实说,连BASEOFCODE也没什么用的.因为PE LOADER会自动识别所有的SECTION.因为在SECTION HEADER里含有所有有关程序运作的必须描述.关于如何使用IMAGEBASE的方法,我在结构里的说明里已经写了,请自己看.结构中AddressOfEntryPoint是真正的程序入口点.通常情况下,它指向CRTL的启动代码库.当然,可以手工修改.具体方法请参照所用的编译器的说明.CIH病毒就是更改了这里,指向病毒代码,使自己被加载.当自己被加载后,才跳转到原代码开始处.

这回就说到这里,且听下会分解.