c++ - 我的 usercall 函数的 stdcall 包装器是否正确?

标签 c++ c assembly hook usercall

我需要将下面的 __usercall 函数包装到 _cdecl/_stdcall:

char __usercall sub_4017B0<al>(int a1<ebx>, int a2)

a1是整数, a2 实际上是一个整数数组 ('int args[10]')

这是正确的吗? <al> 是什么意思sub_4017B0 后面的意思?

int __stdcall func_hook_payload(int callnum, int* args);

// Wrapper for
// char __usercall sub_4017B0<al>(int callnum<ebx>, int a2)
__declspec(naked) void func_hook()
{__asm{
    push ebp
    mov ebp, esp

    push dword ptr[ebp + 0x28] // args[9]
    push dword ptr[ebp + 0x24] // args[8]
    push dword ptr[ebp + 0x20] // args[7]
    push dword ptr[ebp + 0x1C] // args[6]
    push dword ptr[ebp + 0x18] // args[5]
    push dword ptr[ebp + 0x14] // args[4]
    push dword ptr[ebp + 0x10] // args[3]
    push dword ptr[ebp + 0x0C] // args[2]
    push dword ptr[ebp + 0x08] // args[1]
    push dword ptr[ebp + 0x04] // args[0]
    push ebx // callnum
    call func_hook_payload
    leave
    ret // note: __usercall is cdecl-like
}}

调用 sub_4017B0 的包装器是什么样子的?
包装器应具有此签名:

int sub_4017B0_wrapper(int callnum, int* args);

最佳答案

该函数是采用实际的 int* 还是采用 va_arg?在这种情况下,您需要提供原始调用代码。

据我所知,你的包装器应该看起来像这样(我不使用堆栈框架,但你的框架是错误的,因为你在返回之前没有pop ebp):

__declspec(naked) void func_hook()
{
    __asm
    {
        push dword [esp + 4]    //int* - pArgs
        push ebx                //int - nArgs
        call func_hook_payload  //you can even just jump to this, the stack should clean itself up correctly
        retn
    }
}

如果是 va_args 你可以这样做:

__declspec(naked) void func_hook()
{
    __asm
    {
        lea eax,[esp + 4]       //int* - &nArg[0]: here we abuse the way the windows stack grows, creating a stack based buffer 
        push eax                //int* - pArgs
        push ebx                //int - nArgs
        call func_hook_payload
        retn
    }
}

调用旧的 func 也很简单,你可以不用 nake 函数,但我真的更喜欢 naked funcs :)

void __declspec(naked) __stdcall CallTheOldVMFunc(int nArgs, int* pArgs)
{
    __asm
    {
        push ebx                //save ebx, its not a scratch register
        mov ebx,[esp + 8]       //set the number of args
        push [esp + 12]         //push the arg ptr
        call TheOldVMFunc
        pop ebx                 //restore ebx
        retn 8                  //ret and cleanup
    }
}

关于c++ - 我的 usercall 函数的 stdcall 包装器是否正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4823649/

相关文章:

linux - 汇编 - 编译器看不到我的内联更改?

在没有编译器生成序言/结尾和 RET 指令的情况下创建 C 函数?

c - 疾病模拟器上的段错误

c - 通过函数的模式

assembly - 汇编中定时器的问题 [ATmega8]

c# - WPF : How to not block the GUI thread in HwndHost. BuildWindowCore 中的死锁?

c++ - 什么是 union ?

c++ - 从状态内的自定义函数(不是 Action ) boost MSM 调用 process_event?

c++ - 在 C++ 模板(对象)中重载 operator=

c++ - 数组指针算术题