IDA Pro - 配置寄存器破坏

逆向工程 艾达 x86 登记 调用约定
2021-07-03 01:29:57

特尔;博士:

IDA Pro 中的 __fastcall 约定假设所有可用于传输参数的寄存器在调用后都被破坏(在 x86 上测试,被破坏的寄存器是eax, edx, ebx, ecx)。我想知道我怎样才能改变它。

完整解释:

我有一段代码(使用 Watcom名称 mangling):

cseg01:00062A6B                 mov     edx, [ebp+tng1]
cseg01:00062A6E                 mov     eax, [ebp+this1]
cseg01:00062A71                 call    W?MyMethod$_Whatever$n_x__pn$SubObject$$
cseg01:00062A76                 call    W?MySubMethod$_SubObject$n_pn$Thing$$_l
cseg01:00062A7B                 cmp     eax, 0Ah

这些功能是:

SubObject *__fastcall Whatever::MyMethod(Whatever *__hidden this);
int __fastcall SubObject::MySubMethod(SubObject *__hidden this, Thing *tng);

IDA Pro 产生:

(v3 = Whatever::MyMethod(this1), SubObject::MySubMethod(v3, v4) < 10)

所以正确的代码显然是:

(this1->MyMethod()->MySubMethod(tng1) < 10)

问题是——IDA 没有tng1用作——的第二个参数,MySubMethod()而是定义了一个v4带有未设置值的单独变量

因为我们__fastcall对这两个函数都使用,所以第一个 arg 通过eax,第二个通过edx代码碰巧edx在第一次调用之前设置了 的值,即使它实际上是第二次调用的参数。IDA 似乎假设MyMethod()覆盖了(或使用适当的命名法,破坏了)的值EDX

我尝试了 __usercall 和 __userpurge,它对代码没有影响——IDA 仍然假设EDX第一次调用就被破坏了。

有没有办法配置/更改该行为,让 IDA 知道函数调用不会破坏寄存器?

我记得以前修过,所以有个办法,就是想不起来到底是什么了……

此外,最好在项目级别配置它,而不是为每个函数定义自定义调用约定。

1个回答

在被__spoils调用函数的原型上没有明确声明的情况下,Hex-Rays 会根据为二进制文件选择的编译器来决定在调用站点上哪些寄存器应该被破坏,可以在 下查看和修改Options->Compiler您的第一步应该是确保Compiler下拉框显示“Watcom C++”。

Hex-Rays 的作者需要分别实现对每个编译器的 ABI 的支持。也就是说,如果您要对 Hex-Rays 中选择在整个调用分析中使用的标准破坏集的部分进行逆向工程,您会发现该逻辑使用了if检查数据库编译器设置的 - 语句(如上一段所述)。

不幸的是,截至上次我对 Hex-Rays 的那部分进行逆向工程时,他们还没有实现对 Watcom 的 ABI 的支持。这可能在此期间发生了变化——同样,您的第一步应该是将编译器设置为 Watcom,然后看看会发生什么。我的印象是他们可能在 7.3 中添加了它,基于以下更新日志

BUGFIX:类型:更正了 watcom 文件的损坏寄存器列表

但是,如果设置编译器不起作用,那么作为用户,您无法在不手动注释每个函数__spoils集的情况下修复此问题如果是这样,这将是使用您的许可证密钥联系 Hex-Rays 支持人员的好时机,如果可能,还需要一份二进制文件的副本,并询问他们是否可以在反编译器中实现对 Watcom 的 ABI 支持。它可能不会在下一个版本中发生,但如果有足够多的客户有足够多的涉及 Watcom 二进制文件的请求,它就会发生。毕竟,他们最终实现它可能没有那么多工作,而且开箱即用是一个很好的功能。