c - Ghidra 是否误解了函数调用?

标签 c x86 reverse-engineering decompiling ghidra

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

调用双字指针 [EBX*0x4 + 0x402ac0]=>DAT_00402abc

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

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

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

所以我想知道这是什么意思以及程序应该用这个调用做什么?有没有可能吉德拉彻底搞砸了?如果是这样,我应该如何解释该指令?

最佳答案

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

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

0x402ac0处有一个函数地址表;正在调用该表中的第 EBX 条目。我不知道 DAT_00402abc 是什么意思,但如果您在地址 0x0402ac0 处检查双字大小的 block 中的内存,您应该会找到合理的函数地址。 [编辑: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 指令本身不会改变。

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

关于c - Ghidra 是否误解了函数调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69666383/

相关文章:

c++ - IR LLVM 形式与汇编

来自汇编的 C 循环代码

reverse-engineering - 搜索跳转时 WinDbg 范围错误

c - 如何开始使用 ARM 处理器?

c - 将用户输入读取到数组中,直至达到其最大大小

linux - 英特尔处理器如何访问 Branch Trace Store 缓冲区?

hibernate - 为什么 hibernate 在映射多对多关系时会生成额外的实体?

c - 将 fread 与 struct 一起使用时出现奇怪的错误

使用C从存储在数组中的数字创建一个数字

c++ - MOV x86 指令是否实现 C++11 memory_order_release 原子存储?