摘要:上一小节中,我们分别使用两种方法将磁盘PE文件加载到内存中。从中我们可以得知, PE文件被分为几个大块的节区,然后再将节区划分为多个小的区块。磁盘上的PE文件是以200H(512)字节为单位对齐,而内存中的PE文件是以1000H(4KB)为单位对齐。PE文件头
上一小节中,我们分别使用两种方法将磁盘PE文件加载到内存中。从中我们可以得知, PE文件被分为几个大块的节区,然后再将节区划分为多个小的区块。磁盘上的PE文件是以200H(512)字节为单位对齐,而内存中的PE文件是以1000H(4KB)为单位对齐。PE文件头部作为一个节区单独存在,剩余部分就是各个节区。节区的数量、大小,以及在磁盘文件和内存中对齐后的大小和位置在节区表中都有详细的记录。我们据此在PE磁盘文件中找到各个节区,并将其加载到内存。PE磁盘文件与内存映像的结构图如图3-22所示。
图3-22 PE磁盘文件与内存映像结构图
接下来我们做两个实验,实际观察一下加载到内存中的PE映像文件的结构。
实验二十一:使用WinHex工具观察PE内存映像
使用WinHex打开PE磁盘文件和该文件在内存中运行的进程,观察异同。
●PE磁盘文件
我们以notepad32.exe记事本程序为例,将其拖入WinHex内,默认显示磁盘二进制文件格式如下:
00000000 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 MZ............
00000010 B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 ?......@.......
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000030 00 00 00 00 00 00 00 00 00 00 00 00 E0 00 00 00 ............?..
00000040 0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68 ..?.???L?Th
00000050 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F is program canno
00000060 74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20 t be run in DOS
00000070 6D 6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00 mode....$.......
00000080 EC 85 5B A1 A8 E4 35 F2 A8 E4 35 F2 A8 E4 35 F2 靺[〃?颞?颞??
00000090 6B EB 3A F2 A9 E4 35 F2 6B EB 55 F2 A9 E4 35 F2 k?颟?騥險颟??
000000A0 6B EB 68 F2 BB E4 35 F2 A8 E4 34 F2 63 E4 35 F2 k雋蚧?颞?騝??
000000B0 6B EB 6B F2 A9 E4 35 F2 6B EB 6A F2 BF E4 35 F2 k雓颟?騥雑蚩??
000000C0 6B EB 6F F2 A9 E4 35 F2 52 69 63 68 A8 E4 35 F2 k雘颟?騌ichㄤ5?
000000D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000E0 50 45 00 00 4C 01 03 00 87 52 02 48 00 00 00 00 PE..L...嘡.H....
000000F0 00 00 00 00 E0 00 0F 01 0B 01 07 0A 00 78 00 00 ....?.......x..
●PE内存映像
运行notepad32.exe,然后点击菜单“工具”>“打开RAM内存”,弹出窗口如图3-23所示。点击“确定”,观察一下WinHex窗口显示内容如下:
图3-23 WinHex查看进程内存窗口
01000000 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 MZ............
01000010 B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 ?......@.......
01000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
01000030 00 00 00 00 00 00 00 00 00 00 00 00 E0 00 00 00 ............?..
01000040 0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68 ..?.???L?Th
01000050 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F is program canno
01000060 74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20 t be run in DOS
01000070 6D 6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00 mode....$.......
01000080 EC 85 5B A1 A8 E4 35 F2 A8 E4 35 F2 A8 E4 35 F2 靺[〃?颞?颞??
01000090 6B EB 3A F2 A9 E4 35 F2 6B EB 55 F2 A9 E4 35 F2 k?颟?騥險颟??
010000A0 6B EB 68 F2 BB E4 35 F2 A8 E4 34 F2 63 E4 35 F2 k雋蚧?颞?騝??
010000B0 6B EB 6B F2 A9 E4 35 F2 6B EB 6A F2 BF E4 35 F2 k雓颟?騥雑蚩??
010000C0 6B EB 6F F2 A9 E4 35 F2 52 69 63 68 A8 E4 35 F2 k雘颟?騌ichㄤ5?
010000D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
010000E0 50 45 00 00 4C 01 03 00 87 52 02 48 00 00 00 00 PE..L...嘡.H....
010000F0 00 00 00 00 E0 00 0F 01 0B 01 07 0A 00 78 00 00 ....?.......x..
总结
1.观察一下offset偏移地址,在内存中的地址为VA地址(基址ImageBase+RVA)。
2.节区以1000H为单位地址对齐,其中PE文件头部占据4KB空间。
PE文件头部内存地址区间为:01000000H~01000FFF,大小为1000H。
.text节区内存地址区间为:01001000H~01008FFFH,大小为8000H。
.data节区内存地址区间为:01009000H~0100AFFFH,大小为2000H。
.rsrc节区内存地址区间为:0100B000H~01012FFFH,大小为8000H。
这与节表中记录的数据完全一致。
实验二十二:使用DTDebug调试器观察内存中的PE映像文件
我们同样以notepad32.exe记事本程序为例,将其拖入DTDebug调试器内,打开内存映射窗口,如图3-24所示:
图3-24 DTDebug调试器观察PE内存映像
总结
1. 观察DTDebug调试器的内存映射窗口。内存中的映射文件被分为PE文件头、.text、.data和.rsrc 四个部分。
2. 内存地址为VA地址,节区的大小为对齐后的大小,类型为Image映像文件,访问类型为“R”可读类型。
【注意】notepad32.exe映像文件的下方为系统DLL映像文件,以同样的方式显示。
下一章我们将详细分析主要节区的内容,包括导入表、导出表、重定位表和资源表,其他节区我们将做简要介绍。
来源:it科技之光