反汇编调用函数从 RIP 偏移

逆向工程 拆卸 视窗 聚乙烯 x86-64
2021-06-19 18:58:58

我正在编写一个程序,在其中映射.exe内存中PE 文件并“剖析”它。我正在.text使用distorm反汇编器反汇编目标可执行文件部分

CALL反汇编中的指令相对于RIP寄存器有一个偏移量,例如:CALL QWORD [RIP+0xf8e]

我也在阅读Import Descriptor Table,我可以在那里看到来自各种 .dll 的所有函数调用。

当使用 dumpbin.exe/section:.text /disasm反汇编相同的目标时.exe,虽然它显示相同的操作码ff 15 8e 0f 00 00,但它以某种方式将此 RIP 偏移量转换为正确(且正确)的 Win32 函数(在我的程序中GetCurrentProcessId()被调用call qword ptr [__imp_GetCurrentProcessId]

我的问题是如何将CALL我在反汇编中看到的每条指令“映射”/解析为特定的 Win32 API 调用,就像 dumpbin 那样,因为我不在调试器中运行这个程序,因此 IAT 不会被 Windows 覆盖加载程序以显示jmp调用 Windows API的正确指令。是反汇编的问题吗?我可以使用各种 PE 结构以某种方式扣除这一点吗?

1个回答

我找到了一个解决方案,并将其留在这里以备将来参考。

首先,您需要根据跳转的 RIP 偏移量计算线性地址(二进制文件在运行时将拥有的地址)。假设 RIP 偏移量为0x8fe. 你加上这个,指令本身的偏移量(从 .text 部分开始的偏移量)加上指令大小,你会得到一个数字。然后,您必须将此数字添加到 .text 部分的开头,但这一次,您需要SectionAlignment在计算中包括如果.textis0x400和 the SectionAlignmentis的 RVA 0x1000,则 的开始.text将在 Image Base + 0x1000

然后您从 ILT导入目录表中获取导入的函数名称您可以通过读取OriginalFirstThunk指向u1.Ordinal指针来完成此操作Name有关更多详细信息,请查看此处

执行此操作时,您知道每个 dll 导入函数的顺序。

现在,您需要获取FirstThunkRVA,当文件未加载时,它将指向 NULL 位置。但是,此 RVA 是 IAT(在运行时)的开始。每个导入的大小为 8 个字节。

例如,如果你看到 a CALL QWORD PTR [RIP+0xf8e],你计算这个数字,你得到(比如说)0x0000022D932D2008从 IAT 开始的 8 个字节,你知道这个调用调用了第二个导入的函数。既然知道了顺序,就知道是哪个函数了。