Ghidra 是不是误解了函数调用?

Posted

技术标签:

【中文标题】Ghidra 是不是误解了函数调用?【英文标题】:Is Ghidra misinterpreting a function call?Ghidra 是否误解了函数调用? 【发布时间】:2021-12-08 11:29:21 【问题描述】:

在分析 Ghidra 中的汇编列表时,我偶然发现了这条指令:

CALL dword ptr [EBX*0x4 + 0x402ac0]=>DAT_00402abc

我假设程序正在调用一个地址在DAT_00402abc 内的函数,我最初认为它是一个双字变量。事实上,当试图在 DAT_00402abc 所在的位置创建函数时,Ghidra 不会让我这样做。

反编译器向我显示这行代码来翻译该指令:

(*(code *)(&int2)[iVar2])();

所以我想知道,这是什么意思,程序应该如何处理这个调用? Ghidra有没有可能完全搞砸了?如果是这样,我应该如何解释该指令?

【问题讨论】:

【参考方案1】:

我对 Ghidra 一点也不熟悉,但我可以告诉你如何解释机器指令...

CALL dword ptr [EBX*0x4 + 0x402ac0]

0x402ac0有一个函数地址表;正在调用该表中的第 EBX 项。我不知道DAT_00402abc 是什么意思,但是如果你检查地址0x0402ac0 的双字大小的块中的内存,你应该会找到合理的函数地址。 [编辑:0x0040_2abc = 0x0040_2ac0 - 4。我怀疑这意味着 Ghidra 认为当控制达到这一点时 EBX 的值为 -1。它可能是错误的,或者程序可能有错误。当控制达到这一点时,人们会期望 EBX 具有 非负 值。]

对应于这条指令的自然 C 源代码会是这样的

extern void do_thing_zero(void);
extern void do_thing_one(void);
extern void do_thing_two(void);
extern void do_thing_three(void);

typedef void (*do_thing_ptr)(void);
const do_thing_ptr do_thing_table[4] = 
  do_thing_zero, do_thing_one, do_thing_two, do_thing_three
;

// ...

void do_thing_n(unsigned int n)

   if (n >= 4) abort();
   do_thing_table[n]();

如果表中的函数接受参数或返回值,您会在引用的 CALL 指令前后看到处理参数的代码,但 CALL 指令本身不会改变。

如果函数不都采用相同的参数集,您会看到一些不同且复杂得多的东西。

【讨论】:

以上是关于Ghidra 是不是误解了函数调用?的主要内容,如果未能解决你的问题,请参考以下文章

当我使用 Ghidra 反汇编 .so 文件时,啥是未定义函数?

简单的递归函数误解[关闭]

golang http.Redirect()函数容易误解的地方

在powershell-ise中怎么调用powershell中的函数

前端进击的巨人:知否知否,须知this

C/C++程序逆向-IDA切换到Ghidra说明