如何在 eax 和 esi 中调用带有参数的函数。 GCC C++

Posted

技术标签:

【中文标题】如何在 eax 和 esi 中调用带有参数的函数。 GCC C++【英文标题】:how call a function with parameters in eax and esi. gcc c++ 【发布时间】:2012-03-21 10:54:34 【问题描述】:

我需要使用 gcc 调用我无法在 c++ 中 typedef 的函数指针。我不擅长 asm,所以我很感谢你的帮助。

该函数在 eax 中传递 arg1,在 esi 中传递 arg2。 args 从右向左推送,调用者清理堆栈

signed int __usercall o_Fkt<eax>(int a1<eax>, int a2<esi>, int a3, int a4, int a5)

编辑: 谢谢威廉。我成功地这样称呼它:

    int callfn(void* a1, void* a2, int a3, int a4, void* a5 )
    
        int result;
        unsigned long fktAddr = 0x0092FE40;
        __asm volatile(
                "push %[a5]\n\t"
                "push %[a4]\n\t"
                "push %[a3]\n\t"
                "call edx\n\t"
                "add esp, 12"
                : "=a" (result)
                :  "d" (fktAddr), "a" (a1), "S" (a2) , [a5] "r" (a5), [a4] "r" (a4), [a3] "r" (a3)
                : "memory"
        );
        return result;
    

edit2:将“内存”添加到clobber列表中

【问题讨论】:

为什么需要 typedef?为什么不简单地将函数指针声明为int (*fun_ptr)(int,int,int,int)=some_func;并将其称为fun_ptr(x,y,z,a);? 我通常 typedef 我正在调用的函数如下: typedef int(__thiscall* tFunc(void* pThis, ...); tFunc pFunc = addr; 然后我调用它。但用于设置 eax 和esi 我必须使用 asm 并在调用不成功之前设置这两个。 【参考方案1】:

类似的东西 - 我没有测试它,但我认为编译器输出看起来不错。

int oFkt(int a1);
int callfn(int a1, int a2, int a3, int a4, int a5)

    int result;
    __asm (
            "push %[a5]\n\t"
            "push %[a4]\n\t"
            "push %[a3]\n\t"
            "call oFkt\n\t"
            "add  esp, 12"
            : "=a" (result)
            : "a" (a1), "S" (a2), [a5] "r" (a5), [a4] "r" (a4), [a3] "r" (a3)
    );
    return result;

=a 输出约束导致返回值被复制到resulta 输入约束将a1 加载到eax 中,Sa2 加载到esi 中 其余的只是推动其他论点。

【讨论】:

感谢威廉的回答!它让我很好地了解了它的外观。你的解释也为我指明了一些有趣的阅读方向。在看到你的例子之前,我对语法有点不知所措。

以上是关于如何在 eax 和 esi 中调用带有参数的函数。 GCC C++的主要内容,如果未能解决你的问题,请参考以下文章

系统调用的API以及汇编代码实现

如何在汇编程序 x86 函数调用中传递参数?

调用约定

汇编之 eax, ebx, ecx, edx, esi, edi, ebp, esp??

CDECL 调用函数内。获得参数个数。

Windows 逆向OD 调试器工具 ( 分析 OD 硬件断点处的关键代码 | 添加硬件断点 | 关键代码 | MOV 指令 | EAX 寄存器值分析 | 使用命令查看 esi+0cc 地址 )(代码