【问题标题】:JUMP Table close to the end of the .text sectionJUMP 表接近 .text 部分的末尾
【发布时间】:2021-04-19 16:46:40
【问题描述】:

我编写了以下非常简单的程序:

#include <Windows.h>
#include <stdio.h>

int wmain(void) {
    DWORD dwProcId = GetCurrentProcessId();
    HANDLE hProc = OpenProcess(0x0400, FALSE, dwProcId);
    wprintf(L"Process handle is %p\n.", hProc);

    return 0;
}

当我在 x64dbg(或任何其他调试器)上打开它时,我可以看到 IAT 位于 .rdata 部分的开头,它确实包含我使用的函数 GetCurrentProcessIdOpenProcess,和其他人。

但是,在接近文本部分的末尾,我看到了这段代码,它似乎也类似于跳转表: What is this table?

我也可以看到在 IAT 中导入的似乎被调用的函数,但是在我阅读的任何 PE 指南中都找不到对该表的任何引用。

这个表是什么?如何通过 PE 部分或结构以编程方式引用它?

【问题讨论】:

  • 看起来像是对动态 C rtl dll 的引用。
  • 当我点击/输入任何跳转时,我确实进入了vcruntime140.dllucrtbase.dll。编译器或链接器把它放在那里?有没有办法通过 PE 部分以编程方式引用它?

标签: c disassembly portable-executable reversing


【解决方案1】:

这个表确实叫跳表。请记住,当您编译代码时,编译器对内存中外部符号(如 GetCurrentProcessId)的地址一无所知。因此调用的操作码将类似于 0xE8 00000000(E8 是调用的操作码,但您可以看到地址为空)。但是,编译器会在目标文件中创建一个符号表,这对链接器(例如 Microsoft 链接器)非常有用。

当您链接代码时,链接器会读取符号表并读取所有外部符号(如 API 调用),然后通常在 .text 部分的末尾创建一个跳转表(如您所拥有的)。跳转表的形式为:

jmp dword ptr ds:[Address of the FirstThunk in IMAGE_IMPORT_DESCRIPTOR]

然后,链接器会修改代码中的所有call 指令,以调用跳转表中的相应条目。

当您将二进制文件加载到内存中时,加载器(例如 Windows 加载器)负责在导入表中使用适当的值填充 FirstThunk 字段。

通过这种方法以及编译器、链接器和加载器之间的协作,您可以成功地使用外部 API 和函数。您可以阅读this 的帖子以更好地了解跳转表。

如何通过 PE 部分或结构以编程方式引用它?

我不认为你可以。该表是 .text 部分的一部分,标题中没有关于它的信息。但是,在普通的 PE 文件中(未打包或混淆),您可以反汇编 .text 部分(甚至无需将二进制文件加载到内存中),并以 0xFF25XXXXXXXX 的形式查找所有指令,其中 XXXXXXXX 是其中之一您的 IMPORT_IMAGE_DESCRIPTOR 中的 FirstThunks。

【讨论】:

  • 如果我能支持你的回答就好了:)。我明白你所说的一切。只有以 FF25 开头的指令感兴趣吗?为什么不是其他 JMP 或 CALL 操作码?这里列出了很多:c9x.me/x86/html/file_module_x86_id_26.html。对于跳转表的跳转操作码,我应该认为这是理所当然的吗?
猜你喜欢
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-08
  • 2013-11-20
相关资源
最近更新 更多