PE文件的内存映射IAT中u1.AddressOfData开头的2个字节是什么?

What are the 2 bytes in the beginning of u1.AddressOfData in the memory mapped IAT of PE files?

因此,为了解析 PE 进程内存中的 IAT table 并获取导入函数的名称,我们必须遍历每个模块的函数,并为每个函数使用 thunkData ->u1.AddressOfData + 2 到达函数名称字符串的开头(我不想开始解释这些指针是什么,因为我假设任何知道答案的人都已经知道了。而 u1 是Windows 具有的预定义结构,并且其中始终包含 AddressOfData)

所以基本上对于 IAT 中的每个函数,我们必须使用 u1.AddressOfData + 2 来获取字符串开头的地址,但我不知道它的开头 2 个字节是什么? Microsoft 文档对此没有解释:

https://docs.microsoft.com/en-us/windows/win32/debug/pe-format

(查找延迟导入名称 Table)

我尝试调试它并查看它们开头的值是什么,它们是 0x8600 和 0xe700 之类的东西,所以通常是 1 个字节的数据和一个字节的 00

这是什么?

IMAGE_THUNK_DATA 结构中,如果函数地址尚未解析且函数未按序号对齐 - AddressOfData 指向 PIMAGE_IMPORT_BY_NAME(如果在 [=22= 中查看则可见) ]winnt.h and/or ntimage.h )

typedef struct _IMAGE_IMPORT_BY_NAME {
    USHORT  Hint;
    CHAR   Name[1];
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;

名称前的前 2 个字节 - 这是 AddressOfNames 中的提示索引 - 导出的名称 table(查找 IMAGE_EXPORT_DIRECTORY)。此 table 名称按字母顺序排序,以便按名称进行快速二进制搜索功能。用于快速检查的提示,在进入二进制搜索之前。如何使用我们可以在 wrk src 代码

中查看
    //
    // Lookup Name in NameTable
    //

    NameTableBase = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNames);
    NameOrdinalTableBase = (PUSHORT)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNameOrdinals);

    //
    // Before dropping into binary search, see if
    // the hint index results in a successful
    // match. If the hint index is zero, then
    // drop into binary search.
    //

    HintIndex = ((PIMAGE_IMPORT_BY_NAME)NameThunk->u1.AddressOfData)->Hint;
    if ((ULONG)HintIndex < ExportDirectory->NumberOfNames &&
        !strcmp((PSZ)((PIMAGE_IMPORT_BY_NAME)NameThunk->u1.AddressOfData)->Name,
         (PSZ)((PCHAR)DllBase + NameTableBase[HintIndex]))) {
        OrdinalNumber = NameOrdinalTableBase[HintIndex];

    }
    else {

        //
        // Lookup the import name in the name table using a binary search.
        //

但是这个索引通常只能在系统映像中有效。如果我们自己构建图像 - 在 best cast 中,这个提示只能对一个 windows 版本有效(我们从 lib 文件中获得提示) - 当新版本 windows已创建 - 通常添加了新的导出 api,因为 table 是按字母顺序排序的 - 索引是 [可以] 更改的