IDA不能提供函数名怎么办?

逆向工程 艾达 拆卸
2021-07-09 04:52:35

为了学习(和娱乐),我一直在使用 IDA Pro 分析文本编辑器应用程序。在查看反汇编时,我注意到许多函数调用是通过显式调用函数名称进行的。例如,我注意到 IDA 将大多数函数调用转换为以下两种格式。

call cs:CoCreateInstance

或者

call WinSqmAddToStream

但有时格式不使用函数名。下面的示例包含导致相关行的代码。第三行代码似乎“缺少”了函数名称。(评论是我自己的。)

mov rcx, [rsp+128h+var_D8]    // reg CX gets the address at stack pointer+128h+var_D8 bytes 
mov r8, [rcx]                 // the address at reg CX is stored to reg r8
call qword ptr [r8 + 18h]     // at address rax+18h, call function defined by qword bytes 

我的问题如下:

  1. 如何call qword ptr <address>在反汇编中建立和函数之间的连接

  2. 我知道 IDA 不能在这里使用函数名,因为它不知道存储在寄存器 R8 中的值……那么是什么原因造成的?开发人员是否使用了某种语法或约定?换句话说,开发人员是否WinSqmAddToStream以与 处的函数不同的方式调用该函数[r8+18h]

2个回答

要将间接调用连接到其目标(如果您知道),您可以执行以下操作:

  1. 添加自定义交叉引用 - 使用 IDC/Python,或从交叉引用子视图。如果您使用脚本,请不要忘记添加该XREF_USER标志,以便 IDA 在重新分析时不会将其删除。

  2. 使用“被调用者”插件(编辑→插件→更改被调用者地址,或Alt+ F11)。这将自动在呼叫旁边添加交叉引用和注释。

至于为什么在二进制文件中不存在显式调用,可以有很多解释。您显示的代码片段看起来像一个虚函数调用,它们通常仅以这种方式完成,以考虑在派生类中覆盖该方法的可能性。

诀窍是找到对象的构造函数。假设代码如下所示:

a = new CFoo();
a->bar();

编译器(我假设 MSVC,32 位)可能会产生如下内容:

push 12h ; size_t
call ??2@YXYXY@Z  ; operator new(uint)
mov [ebp+var_8], eax
mov esi, eax
test esi, esi
jz loc_1
  mov ecx, esi
  call ??0CFoo@@AAAA@AA ; CFoo::CFoo(void)
  mov [ebp+var_8], eax
  jmp loc_2
loc_1:
  mov [ebp+var_8], 0
loc_2:
...
...
...
mov eax, [ebp+var_8]
mov ecx, [eax]
mov ebx, ecx
mov ecx, [ebp+var_8]
call dword ptr [ebx+08h]

看着??0CFoo@@AAAA@AA,又名CFoo::CFoo():

...
mov esi, ecx
mov dword ptr [esi], unk_12345
...

unk_12345isCFoo的虚拟表偏移量:

unk_12345:
  dd offset sub_23456
  dd offset sub_34567
  dd offset sub_45678
  ...

而那个sub_45678at unk_12345+08h(在这种情况下将是第 3 个条目)就是所谓的,即CFoo::bar().