学PE结构很长时间了,开始是从加密与解密的书上学到的,后来又看了一些其他的书,对PE的结构已经基本的了解了。但是因为很少用,所以也经常忘,尤其是导入表与导出表,里面的具体结构经常混淆。
PE格式:
1。DOS Header
2.NT Header
3.Section Table
4.Section
DOS Header的最后一个标志e_lfanew指示了NT Header的位置
NT Header结构
1.Signature
2.File Header
3.Optional Header
在Optional Header中又有三十几项
其中最后一项是Data Directry,即数据目录表,该项有十六项,每一项是一个IMAGE_DATA_DIRECTORY结构
IMAGE_DATA_DIRECTORY STRUCT
VirtualAddress dd ?
isize dd ?
IMAGE_DATA_DIRECTORY ENDS
数据目录表的第一项指示了导出表,第二项指示了导入表
在第二项的VirtualAddress指向了IMAGE_IMPORT_DIRECPTOR数组的RVA
IMAGE_IMPORT_DESCRIPTOR STRUCT
union
Characteristics dd ?
OriginalFirstThunk dd ?
ends
TimeDateStamp dd ?
ForwarderChain dd ?
Name1 dd ?
FirstThunk dd ?
IMAGE_IMPORT_DESCRIPTOR ENDS
其中OriginalFirstThunk中存储的是一个IMAGE_THUNK_DATA数组的RVA,每个IMAGE_THUNK_DATA又指向IMAGE_IMPORT_BY_NAME
IMAGE_IMPORT_BY_NAME STRUCT
Hint dw ?
Name1 db ?
IMAGE_IMPORT_BY_NAME ENDS
Hint指示本函数在其所驻留DLL的引出表中的索引号。该域被PE装载器用来在DLL的引出表里快速查询函数。该值不是必须的,一些连接器将此值设为0。
Name1含有引入函数的函数名。函数名是一个ASCIIZ字符串。注意这里虽然将Name1的大小定义成字节,其实它是可变尺寸域,只不过我们没有更好方法来表示结构中的可变尺寸域。
在IMAGE_IMPORT_DIRECPTOR结构中的FirstThunk项,与OrignalFirstThunk类似,它也是一组IMAGE_THUNK_DATA的RVA,不过该项所指的内容可以改变,并且该项指示的是函数的地址(开始的时候并不指向函数地址,而是OrignalFirstThunk所指的IMAGE_THUNK_DATA中的值与FirstThunk所指的IMAGE_THUNK_DATA相同,在PE装载时,改变的,每个IMAGE_THUNK_DATA是一个函数的地址