C++自定义调用约定

发布于 2024-12-08 21:06:27 字数 510 浏览 0 评论 0原文

在进行逆向工程时,我遇到了一个非常奇怪的程序,它使用一种调用约定,在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

思念满溢 2024-12-15 21:06:27

有通过寄存器传递参数的“正常”调用约定。例如,如果您使用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文