【问题标题】:What are the 2 bytes in the beginning of u1.AddressOfData in the memory mapped IAT of PE files?PE文件的内存映射IAT中u1.AddressOfData开头的2个字节是什么?
【发布时间】:2019-09-02 13:05:56
【问题描述】:

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

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

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

(查找延迟导入名称表)

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

这是什么?

【问题讨论】:

  • 这是IMAGE_IMPORT_BY_NAME - 第一个WORD(2 个字节)是Hint(在导入的模块的导出表中的提示索引)。真的这已经过时了。提示几乎总是包含错误值
  • 那么提示是这个函数被加载的模块的导出表的索引吗?为什么它总是包含错误的值,这是否意味着这2个字节是无用的,从未使用过?
  • 是的,这个字节没用。需要寻找当前的加载器实现 - 可能会使用,也可能不会。 Hint 是从哪里得到的?来自您在构建 pe 时使用的 lib。真正更新了系统映像(移动到下一个 Windows 版本时的最小值),导出表更改,索引更改。关于练习 提示通常是错误的。但这不会导致错误 - 这只是快速检查,如果未命中 - 按名称转到二进制搜索正确索引

标签: c windows winapi portable-executable


【解决方案1】:

IMAGE_THUNK_DATA结构中,如果函数地址尚未解析且函数未按序号捕捉 - AddressOfData 指向PIMAGE_IMPORT_BY_NAME(如果查看 winnt.h 和/则可见或 ntimage.h )

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

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

    //
    // 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.
        //

然而,这个索引通常只能在系统映像中有效。如果我们自己构建图像 - 在最佳情况下,此提示仅对一个 Windows 版本有效(我们从 lib 文件中获得提示) - 当创建新版本窗口时 - 通常添加新的导出 api,因为表是按字母顺序排序 - 索引 [可以] 更改

【讨论】:

  • @Anders - 你的意思是 wrk 代码? microsoft 自行使此代码 open src
  • @Anders - 我真的不知道这一切是如何正式合法的,也许你最好知道这一点。我怎么知道 - wrk 是合法的开源代码,不像 win2000 src 代码,它是泄漏
  • 我认为你应该有一些特殊的许可证,你不能就这样把它放在 GitHub 上。
  • @Anders - 所以我需要删除链接但留下代码 sn-p ?
  • WRK: "...可通过 MSDNAA 订阅者下载(参与部门的管理员可访问)或通过教师连接门户(需要登录)向符合条件的学术教师或工作人员。”所以,是的,我会删除链接。我不知道代码。
猜你喜欢
  • 2015-09-15
  • 2014-02-19
  • 1970-01-01
  • 1970-01-01
  • 2020-08-16
  • 2012-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多