2011-01-28 4 views
1

난 __usercall 함수 아래의 포장을 필요로 _ 으로 cdecl/ _stdcall :usercall 함수에 대한 내 stdcall 래퍼가 올바 릅니까?

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

A1은 정수, A2 실제로하는 int이 배열이다 ("INT 인수 [10])

이 올바른지? sub_4017B0 뒤에있는 <al>의 의미는 무엇입니까?

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); 
+0

이 표준이 없기 때문에 컴파일러, 버전, 플랫폼, 모든 세부 정보를 지정하는 것이 좋습니다. –

+0

Windows 7 32 비트, MinGW g ++ (최신 안정) 또는 Visual C++ 2008 –

+1

왜 C 대신 어셈블리에서 래퍼를 작성하겠습니까? "잘못된"규칙에 따라 함수를 호출하는 적절한 서명을 사용하여 새 함수를 작성할 수 있습니다. – sharptooth

답변

3

이 기능은 실제 int*을 않거나은 va_arg의 걸립니까 :
래퍼는이 서명을해야합니까? 이 경우에는 원래 호출 코드를 제공해야합니다. 내가 무엇을 수집 할 수 있습니다에서

, 래퍼는 (I 스택 프레임을 사용하지 않는,하지만 당신은 반환하기 전에하지 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 
    } 
} 

당신이 nake 기능이없는 그것을 할 수있는, 기존의 FUNC은 꽤 간단 호출을하지만, 정말 알몸 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 
    } 
} 
+0

사실, C 코드는 : intptr_t CL_CgameSystemCalls (intptr_t * args) {...}, 그리고 IMHO, va_arg 또는 int *인지 여부는 분명하지 않습니다. 나는 단지 시험해야 할 것이다. –

+0

고맙습니다. 이 함수를 호출하는 래퍼 (나에게 함수를 '받는'래퍼)를 제공 할 수 있습니까? –

+1

@Quandary : 확실히, 단순한 것으로 봅니다. 지진을 안다면, 그것들은'int *'로 꽤 확실합니다, 왜냐하면 그들은 vm 코드에서'va_args'에서'int *'로 변환되기 때문입니다. – Necrolis