[英]C++ __usercall hooking
你好在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
的调用约定, __usercall
处在于,调用者负责清理堆栈。 但是,查看您已发布IDA的其他代码,很可能提供了错误的参数数量和错误的调用约定。 我建议您通过在call CALL_ORGIGINAL
的位置放置一个断点来验证这一点,并在调用之前和之后观察ESP的值。 如果ESP在返回时不同,则CALL_ORIGINAL
正在清理堆栈,您无需执行其他任何操作。 如果CALL_ORIGINAL
确实清除了堆栈,则可以通过将差除以4(假设每个参数为32位)来确定传递的参数数量。
另一个问题是您不应该将eax
推入堆栈(根据编辑中包含的调用代码)。 调用此函数的现有代码将第一个参数放在eax
但不会将其压入堆栈。
根据您问题中的代码,并假设参数数量正确,您的hook函数应类似于以下示例。
__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在CALL_ORIGINAL
之前和之后均应具有相同的值。 如果不是,您将需要进行更多调查以确定正确的调用约定和参数。
简而言之,除非您亲自进行验证,否则请不要相信什么IDA。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.