我的用户调用函数的 stdcall 包装器是否正确?

发布于 2024-10-14 09:43:03 字数 1152 浏览 5 评论 0原文

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

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

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

这是正确的吗? 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);

I need to wrap the below __usercall function to _cdecl/_stdcall:

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

a1 is integer,
a2 is actually an arry of ints ('int args[10]')

Is this correct? What does the <al> mean behind 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
}}

How would a wrapper look like for calling sub_4017B0 ?
The wrapper should have this signature:

int sub_4017B0_wrapper(int callnum, int* args);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(1

素手挽清风 2024-10-21 09:43:03

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

据我所知,您的包装器应该如下所示(我不使用堆栈帧,但您的框架是错误的,因为您在返回之前没有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 函数的情况下完成它,但实际上我更喜欢裸函数:)

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
    }
}

does the function take an actual int* or does it take va_args? in cases like this you need to provide the original calling code to.

from what I can gather, your wrapper should look like this(I don't use stack frames, but your frame is wrong as you don't pop ebp before returning):

__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
    }
}

should it be va_args you can do something like this:

__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
    }
}

Calling the old func is pretty simple too, you can do it without a nake function, but really I prefer 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
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文