文章标题:浅谈PE结构与磁盘文件的映射关系。
文章作者:xunbu7
作者邮箱:xunbu7@163.com
使用工具:LoadPE.exe, HxD.exe, Photoshop,Windows画图工具
目标文件:XueTr.exe(0.45版本)
参考资料:加密与解密(第三版)
感谢: 期间“小金马”解答了我很多疑惑,也给了编辑此文的一些建议,表示感谢!
作者声明:本人是个新手,最近利用业余时间做了如下文章。希望和大家分享一下,如有错误之处,还请不吝赐教!
关于PE文件的学习,看雪论坛上已经有很经典的教程了,所以这篇文章注重的不是PE文件的详细结构。而是PE结构与磁盘文件的映射关系。
PE文件框架结构如下:
用HxD.exe打开 XueTr.exe。得到它在磁盘中的数据。如下图:
前面64个字节为DOS MZ Header,是一个IMAGE_DOS_HEADER结构。
其中,第一个成员和最后一个成员比较重要。
最后一个成员e_lfanew是PE文件头部的地址,我们看到其值为:00000110h。好,我们去这个地址处看看。
我们来到00000110h处,PE文件头部是一个IMAGE_NT_HEADERS结构,一共248个字节。如下图:
其中Signature 占4个字节,IMAGE_FILE_HEADER结构20个字节,IMAGE_OPTIONAL_HEADER32 共224个字节
数据目录表:IMAGE_DATA_DIRECTORY结构体数组共16个成员,共128个字节(蓝色部分)。我们现在关注的是第二个成员。它的值如下图(黄线部分),其中000C38B8h是IMAGE_IMPORT_DESCRIPTOR结构数组的RVA.
000C38B8h是内存中的偏移地址,我们的目的是找到它在磁盘中的地址。
磁盘文件和内存的映射关系如下图:
用LoadPE查看如下图:
我们看到000C38B8h位于.rdata段。.rdata段的偏移RVK = RVA – FileOffset = 000AD000h– 000ABE00h= 1200h
所以IMAGE_IMPORT_DESCRIPTOR在磁盘文件中的地址 = 000C38B8 h– 1200h= 000C26B8h.
我们来到000C26B8h处。如下图:
因为XueTr.exe引入了15个dll,加上对齐,所以IMAGE_IMPORT_DESCRIPTOR结构体数组有16个成员。图中黄线标记的是第13个成员(对应的是VERSION.dll)。
IMAGE_IMPORT_DESCRIPTOR的成员和内容下图中已经对应指出来了

接下来我们继续:
OriginalFirstThunk的值为000C418Ch,这个依然是内存中的偏移地址。我们要得到这个成员在磁盘文件中的地址。
我们计算,方法同上:
000C418Ch – 1200h = 000C2F8Ch。
我们来到000C2F8Ch处。如下图:
说明见下图:(为什么这里的这四个字节指的是PIMAGE_IMPORT_BY_NAME,而不是前面的三个成员,不清楚,有了解的,还请不吝赐教!)
IMAGE_THUNK_DATA的值为:000C52BAh。
000C52BAh – 1200h = 000C40BAh
我们来到000C40BAh处:
说明见下图:

另外,IMAGE_IMPORT_DESCRIPTOR中
Name1的值为:000C52D4h,
000C52D4h – 1200h = 000C40D4h。
我们来到000C40D4h处,如下图:
我们看到,000C40D4h处放的是VERSION.dll字符串。
FirstThunk处的值为000AD7A8h,
000AD7A8h– 1200h= 000AC5A8h。如下图:
我们看到,它的内容和OriginalFirstThunk所指的内容完全一样。当PE加载器将PE文件加载到内存之后,FirstThunk所指的IMAGE_THUNK_DATA结构会被GetProcessAddress(”函数名”)返回的地址填充,具体过程(不清楚),同样求赐教!
编撰此文期间,发现此文对结构体、数组、结构体数组、指针、联合体等数据类型的理解有更直观的理解体验!
PE文件结构博大精深,这里只是粗略地给了一个框架,具体字段的作用和属性等问题的研究,还任重而道远。互勉!
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课