第38章: PE32+

PE32+ 是 Windows OS 使用的可执行文件格式.

64位 Windows OS 中进程的虚拟内存为16TB,其中低位的8TB供用户模式使用.高位的8TB供内核模式使用.

IMAGE_NT_HEADERS

IMAGE_FILE_HEADER

x86 PE32 固定为 014C. x64 PE32+ 中则为 8664 ( IA-64 中为0200 ).

IMAGE_OPTIONAL_HEADER

1#. Magic  

PE32 中为 010B , PE32+ 中为 20B

2#. BaseOfData

PE32 中用作指示数据节的起始地址( RVA ), 而PE32+ 中删除了.

3#. ImageBase

有双字( Dword ) 变为 ULONGLONG (8字节).

4#. 堆&栈

与 堆(heah) 和 栈(stack) 有关的数据类型都变为 ULONGLONG 类型.

IMAGE_THUNK_DATA

先以32位为例:

这个结构体其实就是 INT IAT 所指向的结构体.

网上有:

第一种说法: Ordinal 的值用作判断 union 中哪个域发挥作用.若 Ordinal 值为0,则此时只有 AddressOfData (指向 Import_by_name )有效, 即为 INT .若 Ordinal 最高位为1,则为 IAT.

这种说法纯属离谱,Ordinal 和 AddressOfData 都占四字节,不可能出现上述情况。

第二种说法是: 按照 IMAGE_THUNK_DATA 的最高位来判断. 如果最高位为1 ,则是 IAT,否则为 INT .

xp sp3 中的 notepad.exe 中看一下:

再看一下 INT :

可以发现 INT 中,最高位都是 0 ;  而 IAT 中,最高位都不是1 (最高位为1,则值最小为: 0x80000000 ),并且 IAT 中是函数地址.

当然,首先要明确一点,确实 IAT 和 INT 中对应的值都是一样的,此时满足最高位为0,指向 INT .

在 Win 7 32位下,看一下 notepad.exe 的 IAT 信息:

INT 信息:

如图,最高字节的值有 77, 6F , 73 , 72 , 75 , 3F ,以及 80.

同时注意到一点, 前面提到:普通 Dll 的 ImageBase 为 0x10000000,即最高字节值为1. 当最高位为1时,此时为 0x80000000 , 而 00000000 - 7FFFFFFF 是用户空间,其它则是系统空间.因此最高位为1时,在用户模式下是不能表示函数地址的.

通过以上这些,可以做如下总结:

1#. 在 IAT 中, 只有两种值, ①表示函数地址 ②与 INT 相同,即指向 Import_by_name 结构体.

2#. 在 INT 中, 存在两种值, ①指向 Import_by_name 结构体 ② 最高位为1,表示这个函数是由导出序号导入的函数.

因此当 IMAGE_THUNK_DATA 的最高位为1时,此时一定表示函数的导入序号.其它情况则分情况判定.

  

IMAGE_TLS_Directory

ULONGLONG 都是改变了的字段,并且持有的都是 VA 值.

原文地址:https://www.cnblogs.com/Rev-omi/p/13515073.html