C++ C++__用户呼叫挂接
你好,艾达,我有一个函数C++ C++__用户呼叫挂接,c++,assembly,wrapper,reverse-engineering,usercall,C++,Assembly,Wrapper,Reverse Engineering,Usercall,你好,艾达,我有一个函数 void __userpurge Test(int a1<eax>, int a2, int a3, int a4, char a5) exe就是这样调用这个函数的 mov eax, [ebp+arg_4] add esp, 8 push eax push ecx mov ecx, [edi+2138h] mov edx, [ecx+4] mov ecx, [edx+30h] mov edx, [
void __userpurge Test(int a1<eax>, int a2, int a3, int a4, char a5)
exe就是这样调用这个函数的
mov eax, [ebp+arg_4]
add esp, 8
push eax
push ecx
mov ecx, [edi+2138h]
mov edx, [ecx+4]
mov ecx, [edx+30h]
mov edx, [ecx]
mov eax, esp
mov [eax], edx
mov eax, [edi+20h]
mov [esp+40h+var_24], esp
push eax
push eax
mov eax, edi
call Test
pop edi
pop esi
retn
在功能上,似乎有几次
add esp, 24h
retn 10h
这意味着有更多的参数或IDA得到了错误的参数类型?
\uuuu userpurge
函数使用类似于\uu usercall
的调用约定,只是调用方负责清理堆栈。但是,查看您发布的其他代码,很可能提供了错误数量的参数和错误的调用约定。我建议您通过在call call\u original
的位置放置一个断点来验证这一点,并在调用前后观察ESP的值。如果ESP返回时不一样,则CALL_ORIGINAL
正在清理堆栈,您无需再做其他事情。如果CALL_ORIGINAL
确实清理了堆栈,则可以通过将差值除以4(假设每个参数为32位)来确定传递的参数数
另一个问题是您不应该将eax
推到堆栈上(根据编辑中包含的调用代码)。调用此函数的现有代码将第一个参数放置在eax
中,但不会将其推送到堆栈上
根据问题中的代码,并假设参数的数量正确,您的钩子函数应该与下面的示例类似
__declspec(naked) void myHookedFunc(int a1,int a2,int a3,int a4,char a5) {
__asm
{
push a5
push a4
push a3
push a2
// eax is not pushed onto the stack
call CALL_ORGIGINAL
retn
}
}
如果调用约定和参数数量正确,则ESP在“全部调用”之前和之后的值应相同。如果不是,您将需要进一步研究它,以确定正确的调用约定和参数
简而言之,永远不要相信IDA,除非你自己验证。不要相信IDA的函数签名。有时,IDA无法生成正确的签名。你需要手动分析它。函数中有几次是add esp,24h retn 10h,所以我猜有更多的参数,IDA是错误的?@user1422473这是一个很好的假设。我编辑了我的答案,以反映您发布的附加代码。注意
调用测试之后的行,以确保正确清理堆栈。如果你能在调用后包含代码,我会在必要时更新我的答案。我检查了函数,它的第一行是sub esp,24小时,这意味着它会清理堆栈本身
__declspec(naked) void myHookedFunc(int a1,int a2,int a3,int a4,char a5) {
__asm
{
push a5
push a4
push a3
push a2
// eax is not pushed onto the stack
call CALL_ORGIGINAL
retn
}
}