使用内联asm挂钩用户调用

时间:2012-01-12 08:41:12

标签: c++ assembly disassembly ida

我用IDA pro反汇编了一个可执行文件。我的目标是挂钩__usercall函数。我知道我需要在我的C ++代码中使用inine asm包装__usercall,因为我无法键入def函数。但我不确定这是如何运作的。

我知道该函数将对象作为参数,将* Vector3作为参数,其中将存储计算值。有没有一种简单的方法来判断哪个参数将是什么?

(对不起长代码)

char __usercall sub_572EA0<al>(int a1<ecx>, int a2<edx>, int a3<eax>, int a4)
{
  int v4; // edi@1                                                            
  int v5; // esi@1                                                            
  float v6; // eax@2                                                          
  char v7; // al@3                                                            
  int v8; // eax@5                                                            
  char result; // al@11                                                       
  int v10; // [sp+Ch] [bp-74h]@2                                              
  float v11; // [sp+10h] [bp-70h]@4                                           
  float v12; // [sp+14h] [bp-6Ch]@4                                           
  float v13; // [sp+18h] [bp-68h]@5                                           
  float v14; // [sp+1Ch] [bp-64h]@5                                           
  float v15; // [sp+20h] [bp-60h]@5                                           
  float v16; // [sp+24h] [bp-5Ch]@10                                          
  float v17; // [sp+28h] [bp-58h]@10                                          
  float v18; // [sp+2Ch] [bp-54h]@10                                          
  char v19; // [sp+30h] [bp-50h]@10                                           
  float v20; // [sp+3Ch] [bp-44h]@4                                           
  float v21; // [sp+40h] [bp-40h]@4                                           
  float v22; // [sp+44h] [bp-3Ch]@4                                           
  float v23; // [sp+54h] [bp-2Ch]@7                                           

  v4 = a3;                                                                    
  v5 = a1;                                                                    
  if ( a3 )                                                                   
  {                                                                           
     LODWORD(v6) = sub_55A920(*(_DWORD *)(a1 + 208));                         
     if ( !sub_53ADD0(                                                        
              v5,                                                             
              v6,                                                             
              v4,                                                             
              (int)&v10) )                                                    
     {                                                                        
        v7 = sub_4EC240(v4);                                                  
        sub_4E3ED0(                                                           
           1,                                                                 
           "Cannot find tag [%s]\n",           
           v7);                                                               
     }                                                                        
  }                                                                           
  else                                                                        
  {                                                                           
     sub_572BE0();                                                            
     *(float *)&v10 = *(float *)(v5 + 20) + v20;                              
     v11 = *(float *)(v5 + 24) + v21;                                         
     v12 = *(float *)(v5 + 28) + v22;                                         
  }                                                                           
  v8 = dword_8FF12C;                                                          
  v13 = flt_96A218;                                                           
  v14 = flt_96A21C;                                                           
  v15 = flt_96A220;                                                           
  if ( dword_8FF12C == 2047 )                                                 
     v8 = dword_8FF1D0;                                                       
  sub_462250(                                                                 
     &v23,                                                                    
     &v13,                                                                    
     &v10,                                                                    
     &unk_82D6A0,                                                             
     v8,                                                                      
     8400899);                                                                
  if ( 1.0 == v23                                                             
    || (unsigned __int16)sub_492C50(&v23) == *(_DWORD *)(v5 + 208)            
    || *(_UNKNOWN **)(v5 + 364) == &unk_FFFFFF                                
    && (v16 = v13                                                             
            + (*(float *)&v10 - v13)                                          
            * v23,                                                            
        v17 = (v11 - v14) * v23 + v14,                                        
        v18 = v23 * (v12 - v15) + v15,                                        
        sub_4C35B0(                                                           
           &v16,                                                              
           v5 + 20,                                                           
           v5 + 32,                                                           
           &v19),                                                             
        sub_432850(                                                           
           *(_DWORD *)(v5 + 348),                                             
           &v19)) )                                                           
     result = sub_550250(a4, &v13, &v10);                                     
  else                                                                        
     result = 0;                                                              
  return result;                                                              
}

ASM可能是错误的,这样的事情会接近吗?

// Don't know what params goes where, ie: where the Vec3 goes and where the object goes
int __stdcall func_hook(param1, param2, param3, param4);

// Where to put the address? -->> 0x572EA0

// char __usercall sub_572EA0<al>(int a1<ecx>, int a2<edx>, int a3<eax>, int a4);
__declspec(naked) void func_hook() 
{__asm{ 
    push ebp 
    mov ebp, esp 
    mov ecx param1
    mov edx param2
    mov eax param3
    push param4
    call func_hook 
    leave 
    ret 
}}

这段代码中缺少的一件事是用户调用的地址(0x572EA0)。不确定把它放在哪里......


这是程序调用函数的方式。电话在底部: http://i43.tinypic.com/2mez9c8.jpg

1 个答案:

答案 0 :(得分:2)

你挂钩的那个函数是Borland __fastcall,而不是__usercall(事实上实际上没有这样的约定,它只是IDA的“未知约定”的版本)。

在使用内联asm挂钩时,ECXEDXEAX是临时寄存器,所以我们不需要保留它们,并且调用很好我们不需要担心堆栈:

static DWORD the_hook_address = 0x572EA0;
//init this somewhere with the correct (Base + RVA) address in case of module relocation (from ASLR etc.)
__declspec(naked) bool __stdcall the_hook(int a1, int a2, int a3, int a3)
{
    __asm
   {
       MOV ECX,[ESP + 4]//a1
       MOV EDX,[ESP + 8]//a2
       MOV EAX,[ESP + 12]//a3
       PUSH [ESP + 16]//a4
       CALL the_hook_address
       RETN 16 //4 * 4 args
   }
}
  

我知道该函数将对象作为参数,将* Vector3作为参数   将存储计算值的参数。有没有   简单地告诉哪个参数将是什么?

'简单'取决于你在逆向工程方面的经验以及你正在使用的程序,在这种情况下我会说它是a1,因为你可以看到它移动到临时,然后被访问使用指针表示法(IDA表示未知结构的方式)来提取3 float s,这通常是大多数应用程序用于矢量组件的(并且大多数矢量都有3个组件)。如果您可以实际调试操作中的调用,查看params指针,查看函数调用站点等,它也会有很大帮助。因此我更喜欢使用ollydbg作为RE,用IDA执行流程图补充它以获得棘手的跳转序列(在函数中考虑20 + goto:&lt;)