作者:陆麟
转载请征得作者同意.
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病毒就是更改了这里,指向病毒代码,使自己被加载.当自己被加载后,才跳转到原代码开始处.
这回就说到这里,且听下会分解.