尽管 DLL 导出函数,但导出目录中的名称和序数表指针为 NULL

逆向工程 dll 聚乙烯
2021-06-18 13:27:07

我正在尝试探索 profapi.dll 导出的函数,但遇到了无法解释的行为。

阅读有关 PE 二进制格式的信息,我发现导出表有 3 个表(数组):一个数组包含导出函数的函数指针,另一个包含导出函数的名称(字符串),第三个数组包含导出的整数序数职能。链接器需要名称和/或序数表中的信息来修补对其他 DLL 中导出函数的调用。如果 DLL 仅使用序数导出其函数,则名称表指针可以为 NULL。

但是,对于profapi.dll,我看到name table 和ordinal table 指针都是NULL;但 DLL 导出 6 个函数(使用 IDAPro 验证)。事实上,shell32.dll 使用其序号调用 profapi.dll 中的函数之一,链接器以某种方式解析地址。我不确定链接器如何解析 shell32.dll 中的调用。此外,我用来解析 DLL 的 Python 库 pefile 报告 profapi.dll 不导出任何函数,因为名称和序数表指针都是 NULL。我错过了什么?

我在 Windows 7 上使用 profapi.dll 版本 6.1.7600.16385 和 shell32.dll 版本 6.1.7601.2278。我使用 pefile 版本 1.2.10-139。

1个回答

“序数表”(也称为导出序数表或AddressOfNameOrdinals)与“名称表”(也称为导出名称指针表或AddressOfNames)结合使用,当且仅当函数按名称导出。

来自官方 PE-COFF 文档

导出名称指针表和导出序数表形成两个并行数组,它们分开以允许自然字段对齐。这两个表实际上作为一个表运行,其中“导出名称指针”列指向公共(导出)名称,而“导出序号”列给出该公共名称的相应序号。导出名称指针表的成员和导出序数表的成员通过在它们各自的数组中具有相同的位置(索引)来关联。

但是,如果没有按名称导出的函数,则没有导出名称指针表,如果没有导出名称指针表,则也需要导出序数表,这就是为什么两个字段都NULL在导出目录表中的原因。

事实上,shell32.dll 使用其序号调用 profapi.dll 中的函数之一,链接器以某种方式解析地址。

构建时链接器(编译器工具包的一部分)不解析地址;运行时加载程序(Windows 的一部分)解析地址。加载程序看到 shell32.dll 通过给定的序数(105例如,假设导入 profapi.dll 函数,因此它从序数中减去 profapi.dll 的序数基(假设101,例如)并使用结果(4在本例中)作为导出地址表的索引,以查找导入函数的 RVA。导出顺序表和导出名称指针表都不需要。

此外,我用来解析 DLL 的 Python 库 pefile 报告 profapi.dll 不导出任何函数,因为名称和序数表指针都是 NULL。我错过了什么?

正如此处所讨论的,pefile Python 库已损坏,或者至少已知它的旧版本在顺序处理方面已损坏。