C++自定义调用约定
在进行逆向工程时,我遇到了一个非常奇怪的程序,它使用一种调用约定,在 eax 中传递一个参数(非常奇怪的编译器??)。我现在想调用该函数,但不知道如何声明它,IDA 将其定义为
bool __usercall foo<ax>(int param1<eax>, int param2);
param1 在 eax 寄存器中传递的位置。我尝试过类似的方法
bool MyFoo(int param1, int param2)
{
__asm mov eax, param1;
return reinterpret_cast<bool(__stdcall *)(int)>(g_FooAddress)(param2);
}
,但是,不幸的是,我的编译器在将 param2 推入堆栈时使用了 eax 寄存器,有什么方法可以使其干净,而无需使用内联汇编器编写整个调用? (如果重要的话我正在使用 Visual Studio)
While reverse engineering I came around a very odd program that uses a calling convention that passes one argument in eax ( very odd compiler ?? ). I want to call that function now and I don't know how to declare it, IDA defines it as
bool __usercall foo<ax>(int param1<eax>, int param2);
where param1 is passed in the eax register. I tried something like
bool MyFoo(int param1, int param2)
{
__asm mov eax, param1;
return reinterpret_cast<bool(__stdcall *)(int)>(g_FooAddress)(param2);
}
However, unfortunately my compiler makes use of the eax register when pushing param2 on the stack, is there any way how I can make this clean without writing the whole call with inline assembler? (I am using Visual Studio if that matters)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
有通过寄存器传递参数的“正常”调用约定。例如,如果您使用 MSVC,
__fastcall< /代码>
。
http://en.wikipedia.org/wiki/X86_calling_conventions#fastcall
您无法定义您的自己的调用约定,但我建议您创建一个包装函数,该函数通过内联汇编进行自己的调用/清理。这可能是实现此效果的最实用的方法,尽管您也可以通过使用 __fastcall、进行一些寄存器交换,然后
jmp
到正确的函数来更快地实现。调用约定不仅仅是参数传递,因此选项 #1 可能是最好的,因为您将完全控制调用者的行为。
There are "normal" calling conventions which pass arguments via registers. If you are using MSVC for example,
__fastcall
.http://en.wikipedia.org/wiki/X86_calling_conventions#fastcall
You cannot define your own calling conventions, but I would suggest that you do create a wrapper function which does its own calling / cleanup via inline assembly. This is probably the most practical to achieve this effect, though you could also probably do it faster by using __fastcall, doing a bit of register swapping, then
jmp
to the correct function.There's more to a calling convention than argument passing though, so option #1 is probably the best as you'll get full control over how the caller acts.