繁体   English   中英

C ++ __用户调用挂钩

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM