我需要将下面的 __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/