特尔;博士:
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 知道函数调用不会破坏寄存器?
我记得以前修过,所以有个办法,就是想不起来到底是什么了……
此外,最好在项目级别配置它,而不是为每个函数定义自定义调用约定。