第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 ,则低 31/63 位是 ordinal,否则为地址 .

xp sp3 中的 notepad.exe 中看一下(因为使用的是服务包sp3,系统文件会被重建,会硬编入准确地址):

再看一下 INT :

目前来看,INT 中最高位都是 0 ;  而 IAT 中,最高位都不是1 (最高位为1,则值最小为: 0x80000000 ),并且 IAT 中是硬编码函数地址.

 

 

 

因为:该程序是系统程序,我们找到的函数都是系统DLL函数,系统DLL都固定了位置。

在 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时,此时一定表示函数的导入序号.其它情况则分情况判定.

 

posted @ 2020-08-17 17:03  Rev_omi  阅读(524)  评论(0编辑  收藏  举报