第二节.PE文件结构
2.1 文件头(File Header)
PE文件包换两个头部文件: DOS Header 和PE Header 在讲述文件头部之前.先介绍专业术语,VA和RVA
VA (Virual Addrss) 是虚拟内存地址. RVA (Relative Virual Address) 就是相对虚拟地址.是虚拟空间中到参考点的一段距离,这有点像平时遇到的绝对路径,相对路径等概念.VA就是绝对的.RVA就是相对的.举例说明.如果PE文件装入虚拟地址空间的400000h(VA)处.且进程从虚地址401000h开始执行.可以说进程执行起始地址在1000h(RVA),每个RVA都是相对于当前可执行模块的起始地址.
2.1.1 DOS Header
DOS Header (DOS 文件头部) 的结构名是IMAGE_DOS_HEADER,其在Delphi中的完整定义是这样的.
PimageDosHeader =^TImageDosHeader;
_IMAGE_DOS_HEADER = Packed record
e_magic:word; {常设为"MZ"}
e_cblp:word; {Bytes on last page of file}
e_cp:word; {pages in file }
e_crlc:word; {relocation }
e_cparhdr:word; {Size of header in paragraph}
e_minalloc:word; {Minimum extra paragraphs needed}
e_maxalloc:word; {Maximum extra paragraphs needed}
e_ss:word; {initial (relative) SS value}
e_sp:word; {initial SP value}
e_csum:word; {Checksum}
e_ip:word; {initial IP value}
e_cs:word; {initial (relative) CS value}
e_ifarlc :word; {File Address of relocation table}
e_ovno:word; {overlay number}
e_res:array[0..3] of word; {reserved word;s}
e_oemid:word; {OEM identifier (for e oeminfo)}
e_oeminfo:word; {OEM information ; e_oemid specific}
e_res2:array[0..9] of word; {reserved words}
_ifanew ongInt; {PE header 在文件中的偏移量}
end;
TLmageDosHeader = _IMAGE_DOS_HEADER;
其中只有两个域比较重要.e_magic 包含字符串"MZ"(即IMAGE_DOS_SIGNATURE,或$5A4D), ifanew包含PE header在文件中的偏移量.比较e_magic是否等于IMAGE_DOS_SIGNATURE来验证是否为有效的DOS header
为了定位到PE header (PE文件头部),移动文件指针到ifanew所指向的偏移
2.1.2 PE Header
在PE header 和DOS header 之间的是DOS stub可执行代码.(也叫插桩程序.用于在纯DOS下显示错误的提示信息."This Program requires Windows").由于该插桩程序是运行自定义的.代码长度也不确定.所以在DOS Header的_ifanew域中指明了PE header 的偏移量.可以轻松的定位到PE header
以下是PE header 在delphi中的完整定义.
PImageNtHeaders =^TIMageNtHeaders;
_IMAGE_NT_HEADERS= packed record;
Signature WORD;
FileHeader:TImageFileHeader;
OptionalHeader :TImageOptionalHeader;
end;
{$EXTERNALSYM_IMAGE_NT_HEADER}
TLmageNtHeaders=_IMAGE_NT_HEADERS;
以下对其中的三个域做一说明.
Signature是PE 标记.值恒为$50,$45,$00,$00(即IMAGE_NT_SIGNATURE,$00004550或" E\0\0")
FileHeader包含了关于PE文件物理分布的一般信息
OptionHeader包含了关于PE文件逻辑分布的信息.
1.PE基本信息(File header)
在这里对PE基本信息(File Header)结构进行深入的剖析.下面看看文件结构的定义
PImageFileHeader = ^TImageFileHeader;
_IMAGE_FILE_HEADER = packed record;
Machine:word;
NumbeiOfSection:word;
TimeDateStamp WORD;
PointerToSymbolTable WORD;
NumberOdSymbols WORD;
SizeOfOptionHeader:word;
Characteristics : Word;
end;
{$EXTERNALSYM_IMAGE_FILE_HEADER}
TImageFileHeader = _IMAGE_FILE_HEADER;
TImageFileHeader各个域的意义如下.
Machine :该文件运行所要求的CPU.对于Intel平台.该值是IMAGE_FILE_MACHINE_I386(14CH).可以利用此值禁止程序执行.但对于编程来说没有太大的帮助.
NumberOfSection:文件中节的个数.如果要在文件中增加或删除一个节.就需要修改这个值.如果要对文件加外壳.需要修改节的数目.
TimeDateStamp:文件创建日期和时间.
PointerToSymbolTable:指向符号表.用于调试.
NumbeiOfSymbols:存放符号表的数目.
SizeOfOptionalHeader:只是紧随本结构后的IMAGE_OPTIONAL_HEADER 结构大小
Characteristics:关于文件信息的标记 下面做详细说明.
当其值为
$1 表示 重定位信息被删除
$2 文件可执行
$4 行号被删除
$8 符号被删除
$80 机器的字节为低位在前.高位在后
$100 属于32位机器
$200 已删去调试信息
$400 如果是映像文件是在可移动媒体中,则复制到将换文件才运行.
$800 如果是网络影响文件.则复制到交换文件才运行.
$1000 系统文件
$2000 DLL动态链接库文件
$4000 只能运行于单处理器上
$8000 机器字节为高位在前低位在后 |