2

有人可以向我解释 x64 平台上的以下行为:如果我从可执行文件调用 x64 中另一个 dll 中的函数,则反汇编代码如下所示:

000000014000149E FF 15 34 CF 00 00  call  qword ptr [__imp_CFuncInDll (14000E3D8h)]

我意识到调试器会计算到这个绝对地址 14000E3C0h 的相对地址。但是,与 x86 代码不同,如果我将地址 14000E3D8h 反汇编,它看起来像垃圾:

__imp_CFuncInDll:
000000014000E3D8 19 10                sbb         dword ptr [rax],edx  
000000014000E3DA 25 FC FE 07 00       and         eax,7FEFCh  
000000014000E3DF 00 14 10             add         byte ptr [rax+rdx],dl  
000000014000E3E2 25 FC FE 07 00       and         eax,7FEFCh  
000000014000E3E7 00 00                add         byte ptr [rax],al  
....... 

当我进入通话时,我可以看到代码没有进入垃圾地址,而是跳转到了一个有效地址:

000007FEFC251019 E9 62 00 00 00       jmp         CFuncInDll (7FEFC251080h)  

我的问题:
当目标位于另一个模块中时,如何在 x64 上解码调用指令?在 x86 中此代码的调用目标:

FF 15 34 CF 00 00    call 

是:目标 = 下一条指令地址 + 0x0000CF34
而在 x64 上看起来情况并非如此。

4

2 回答 2

7

call qword ptr [__imp_CFuncInDll (14000E3D8h)]是通过指针的间接调用。指针的地址是 0x14000E3D8。如果您查看无意义反汇编的代码字节,它们会包含以下内容:

19 10 25 FC FE 07 00 00 

小端四字是:000007fe.fc251019-jmp CFuncInDll单步执行时到达的指令地址。

基本上,对导入函数的调用被组装为通过地址表中的条目对跳转到实际函数实现的小“thunk”的调用。

于 2012-07-11T05:40:30.150 回答
2

您正在尝试反汇编指向代码而不是代码的指针。

本指令

000000014000149E FF 15 34 CF 00 00 call qword ptr [__imp_CFuncInDll (14000E3D8h)]

reads a pointer from the address that is relative to the beginning of the instruction following it, that is, it adds 14000149EH, 6 (length of this call instruction) and 0CF34H, arrives at address 14000E3D8H, reads 8 bytes from there, and that (those 8 bytes: 19H, 10H, 25H, 0FCH, 0FEH, 7H, 0, 0) is the address 7FEFC251019H where this call transfers control.

You should be disassemblying at address 7FEFC251019H.

于 2012-07-11T05:42:54.837 回答