Является ли моя оболочка stdcall для функции usercall правильной? - PullRequest
1 голос
/ 28 января 2011

Мне нужно добавить следующую функцию __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);

1 Ответ

3 голосов
/ 28 января 2011

действительно ли функция принимает 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, но на самом деле я предпочитаю голые 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
    }
}
...