(1)overview of the pe format
PE文件的整体概况:
DOS MZ HEADERS
DOS STUB
PE HEADER
SECTION TABLE
SETCTION 1
SETCTION 2
SETCTION n
1、当pe文件运行的时候,PE加载器检查DOS MZ的文件头去找到PE文件头的偏移地址,如若找到,则跳到PE文件头的开始部分。
2、PE加载器检查PE文件头的有效性,如若有效的,则跳到PE文件头的尾部,也即是节表的开始处。
3、PE加载器得到各个节的数据并使用内存文件映射的方法将它们映射到内存之中,同时根据各个节的属性赋予相应内存页的属性。
4、在PE文件被映射被内存之后,PE加载器开始关注PE文件的逻辑部分,即,导入表、导出表、重定位表等等。
(2)detecting a valid pe format
检查一个文件是否是一个有效的PE文件主要取决于你想要多么准确的查检。你可以查检相应于PE文件的每一个结构来确定,也可以仅仅检查一些关键的字段。
通过我们检查一些关键的字段来判断一个文件是否是一个有效的PE文件。如若关键字段已符合,那么我们就初步的断定此文件是一个有效的PE文件了。
有效性的检查针对PE文件头,下面我们给出PE文件的结构
IMAGE_NT_HEADERS STRUCT
Signature dd ?
FileHeader IMAGE_FILE_HEADER <>
OptionHeader IMAGE_OPTIONAL_HEADER32 <>
IMAGE_NT_HEADERS ENDS
对于一个有效有PE文件 Signature 字段为: 'PE',0,0.。为了方便起见,MS已将此值定义为一个常量IMAGE_NT_SIGNATURE
现在的问题在于,我们怎么得到PE文件头的位置。答案是:由DOS MZ 文件头给出,DOS MZ 文件头已被定义为IMAGE_DOS_HEADER结构,由此结构的e_lfanew字段
就可以得到PE文件头在文件中的偏移值。
===================================================================================
现在来总结一下检查一个文件是否为PE文件的步骤:
1、核实所给你的文件是否有一个有效的DOS 文件头,方法是:将文件的第一个字与IMAGE_DOS_SIGNAUTE作比较,如若两者相等,则取得成员e_lfanew字段的值
得到PE文件头的偏移,从而得到PE文件头在文件中的实际位置
2、比较PE文件头的第一个字是否与IMAGE_NT_SIGNATURE相等,
3、若两者都相等,则我们就可以初步的认为这是一个有效的PE文件了
now Here comes An EXAMPLE:
SEH STRUCT
PreLink
Hanlder
SafePlace
preEbp
preEsp
SEH ENDS
CheckPeFile proc lpMemory
local @seh:SEH
local @Valid
mov @Valid,FALSE
assume fs:nothing
push fs:[0]
pop @seh.PreLink
mov @seh.SafePlace,offset SafePlace
mov @seh.Hanlder,offset Handler
mov @seh.preEbp.ebp
mov @seh.preEsp,esp
lea eax,@seh
mov fs:[0],eax
mov edi,lpMemory
assume edi:ptr IMAGE_DOS_HEADER
.if [edi].e_magic==IMAGE_DOS_SIGNATURE