Hello在IDA中我有一个函数
void __userpurge Test(int a1<eax>, int a2, int a3, int a4, char a5)
我想钩/调用它从我的c++注入的dll这就是我试图调用它的方式,但是。exe崩溃了
DWORD CALL_ORIGINAL = 0x00EAF6D0;
__declspec(naked) void myHookedFunc(int a1,int a2,int a3,int a4,char a5) {
__asm
{
push a5
push a4
push a3
push a2
push eax
call CALL_ORGIGINAL //maybe use JMP?
retn
}
}
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得到错误的参数类型?
__userpurge
函数使用类似于__usercall
的调用约定,只是调用方负责清理堆栈。但是,查看您发布的IDA的附加代码很可能提供了错误数量的参数和,以及不正确的调用约定。我建议您通过在call CALL_ORGIGINAL
的位置放置一个断点来验证这一点,并在调用前后观察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在all到CALL_ORIGINAL
之前和之后应该是相同的值。如果不是,则需要进一步研究以确定正确的调用约定和参数。
总之,永远不要相信IDA,除非你自己验证过。