Hello in IDA i have a function
void __userpurge Test(int a1<eax>, int a2, int a3, int a4, char a5)
And i would like to hook/call it from my C++ injected dll This is how I have tried to call it but .exe crashes
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
}
}
And this is how the exe calls this function
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
Few times in function there appears to be
add esp, 24h
retn 10h
Which would mean there are more arguments or IDA got wrong argument types?
__userpurgefunctions use a calling convention similar to__usercallexcept that the caller is responsible for cleaning up the stack. However looking at the additional code you have posted IDA may very well be providing an incorrect number of parameters and an incorrect calling convention. I suggest that you verify this by placing a breakpoint at the location ofcall CALL_ORGIGINALand watch the value of ESP before and after the call. If ESP is different when it returns thenCALL_ORIGINALis cleaning up the stack and there is nothing more for you to do. IfCALL_ORIGINALdoes clean up the stack you can likely determine the number of parameters passed by dividing the difference by 4 (assuming each parameter is 32bits).Another problem is you should not be pushing
eaxonto the stack (according to the calling code included in your edit). The existing code that calls this function places the first parameter ineaxbut does not push it onto the stack.Based on the code in your question and assuming the number of parameters is correct your hook function should look something like the example below.
If the calling convention and number of parameters is correct ESP should be the same value before and after the all to
CALL_ORIGINAL. If it's not you will need to investigate it a bit more to determine the correct calling convention and parameters.In short, never trust what IDA unless you verify it yourself.