加载器如何找到 dll 中导出函数的准确位置?

发布于 2025-01-13 16:55:51 字数 759 浏览 1 评论 0原文

我在 PEView 中打开一个二进制文件。二进制文件的 .rdata 部分下有一个名为“导入名称表”的表。该表显示了从不同 DLL 导入的函数,但该表中有一个名为 DATA 的字段。该字段具有以下值,您可以在照片中看到它们。例如,GetCurrentProcessID 为 2596。

输入图片这里的描述

从Windbg角度查看上述信息:

在此处输入图像描述

但是当我们的二进制文件完全加载到内存中时,这个值 (2596) 会随着另一个 VA 的变化而变化您可以在下面的照片中看到。

输入图片description here

但是,我根本不明白这个值是什么?以及加载程序如何使用提示值来查找 DLL 中导出函数的确切位置?有人可以实际地逐步解释这一点吗(例如,在windbg中?)。

I open a binary in the PEView. There is a table which is called Import Name Table under .rdata section of the binary. This table show me imported functions from different DLLs but there is a field in this table which is called DATA. This field has following values which you can see them in the photo. for example 2596 for GetCurrentProcessID.

enter image description here

View of the above information from Windbg perspective:

enter image description here

But when our binary get loaded in the memory completely, this value (2596) changed with another VA which you can see in the following photo.

enter image description here

However, I couldn't understand what this value is at all? and also How hint value is used by loader to find out exact location of an exported function from a DLL? Could some explain this step by step practically (for example, in windbg?).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

(り薆情海 2025-01-20 16:55:51

PE 文件包含两个导入列表:查找表和地址表 (IAT)。这些的 RVA 位于 IMAGE_IMPORT_DESCRIPTOR 中。从技术上讲,我相信只允许有一个表,如果我没记错的话,旧的 Borland 工具可能会这样做。导入不能仅与一张表绑定。

查找表条目是指针大小的值,其中包含指向前向的序号或 RVA 或指向提示和函数名称的 RVA。 IAT 条目包含相同的值,或者如果绑定,则为实际地址。

当 PE 文件被加载时,加载器将 IAT 中的条目替换为导入函数的真实地址。另一个表没有改变。

加载器有 4 种解析导入函数地址的方法:

  1. 如果导入已绑定、时间戳匹配并且导入的库加载到其首选地址,则加载器无需执行任何工作即可完成。这意味着,在编译时使用 .lib 文件中的地址填充的 IAT 与运行时加载的导入库完美匹配。
  2. 如果按序号导入,可以直接找到地址,无需搜索名称。
  3. 使用提示。如果提示与导出匹配,它将使用此快捷方式而不搜索名称。该提示只是查看导出名称表中特定槽的一种方法。如果提示不匹配,则继续执行步骤 4。
  4. 搜索导出的名称表以查找函数索引。名称表已排序,因此加载程序可以执行二分搜索。

当您看到像 call DWORD PTR [_imp_Xyz] 这样的反汇编时,您正在查看调用导入函数的代码,并且实际地址是从 IAT 读取的。

A PE file contains two lists of imports, the lookup table and the address table (IAT). The RVAs to these are in IMAGE_IMPORT_DESCRIPTOR. Technically I believe it is allowed to only have a single table, older Borland tools might do this if I remember correctly. The imports cannot be bound with only one table.

The lookup table entries are pointer sized values that contains the ordinal or a RVA to a forward or a RVA to the hint and function name. The IAT entries contain the same values, or if bound, the actual address of the exported function.

When the PE file is loaded the loader replaces the entries in the IAT with the real address of the imported function. The other table is not changed.

The loader has 4 ways of resolving the imported function addresses:

  1. If the imports are bound, the timestamp matches and the imported library loaded at its preferred address, the loader is finished without doing any work. Meaning, the IAT that was filled at compile time with addresses from the .lib file perfectly matches the imported library that was loaded at run-time.
  2. If importing by ordinal it can find the address directly without searching for names.
  3. Using the hint. If the hint matches the export, it uses this shortcut without searching the names. The hint is simply a way to look at a specific slot in the exported names table. If the hint does not match, it continues to step 4.
  4. Search the exported names table to find the functions index. The names table is sorted so the loader can perform a binary search.

When you see disassembly like call DWORD PTR [_imp_Xyz] you are looking at code that calls an imported function and the real address is read from the IAT.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文