如何使用microsoft detours挂钩__usercall函数

逆向工程 艾达 C++ 函数挂钩
2021-06-21 19:30:33

我需要挂钩一个 __usercall 函数,特别是我只需要读取第一个参数:

char __usercall sub_4F3E6D@<al>(char *Src@<ecx>, int a2@<edx>, int a3, int a4, char a5, char a6, char a7, char a8, int a9)
{
  int v9; // edi
  char v10; // bl
  char *v11; // esi
  unsigned __int8 v12; // al
  signed int v13; // edx
  int v14; // eax
  signed int v15; // eax
  signed int v16; // edi
  char *v17; // eax
  char *v18; // esi
  float v20; // xmm1_4
  size_t v21; // ST04_4
  float v22; // [esp+18h] [ebp-A8h]
  int v23; // [esp+1Ch] [ebp-A4h]
  char v24; // [esp+24h] [ebp-9Ch]
  int v25; // [esp+2Ch] [ebp-94h]
  char Dst; // [esp+40h] [ebp-80h]
  int v27; // [esp+98h] [ebp-28h]
  int v28; // [esp+9Ch] [ebp-24h]
  float v29; // [esp+ACh] [ebp-14h]
  float v30; // [esp+B0h] [ebp-10h]

  v9 = a2;
  v10 = 0;
  v11 = Src;
  v23 = a2;
  if ( a9 )
    *(_DWORD *)a9 = 0;
  if ( !dword_897628 || !Src || !*Src )
    return 0;
  if ( a6 )
  {
    v12 = *((_BYTE *)dword_8CF880 + 2232);
  }
  else if ( a7 )
  {
    v12 = *((_BYTE *)dword_8CF880 + 2234);
  }
  else
  {
    v12 = a8 ? *((_BYTE *)dword_8CF880 + 2233) : *((_BYTE *)dword_8CF880 + 2252);
  }
  v22 = (float)v12 * 0.0099999998;
  if ( v22 < 0.0099999998 && a2 != 1481317962 )
    return 0;
  if ( sub_4F4463(a2, 0) )
    return 0;
  memset(&Dst, 0, 0x78u);
  sub_410BA2(&Dst, 3);
  if ( a6 )
  {
    v28 = 9;
  }
  else if ( a7 )
  {
    v27 |= 4u;
  }
  else if ( !a8 )
  {
    v27 |= 0x40000u;
  }
  v13 = 1;
  if ( a5 || a6 )
  {
    v14 = v27 | 1;
    v27 |= 1u;
    if ( a6 )
      v27 = v14 | 8;
  }
  if ( *(float *)&a3 > 0.0099999998 )
    sub_4F0812(&Dst, 1);
  sub_4F0855(&Dst, v13);
  v27 |= 0x40u;
  *(_DWORD *)a4 = 0;
  v30 = fminf(fmaxf(v22, 0.0), 1.0);
  v29 = v30;
  sub_410B78(&v24);
  v15 = v25;
  if ( a5 )
    v15 = 1;
  v25 = v15;
  v16 = v9 == 1481317962 ? 2147483646 : sub_4F353D(&v24, 0);
  if ( !(unsigned __int8)sub_4F349C(v16) )
    return 0;
  v17 = sub_4F1BBB(v11, v23, 0, (int)&Dst);
  v18 = v17;
  if ( !v17 )
    return 0;
  if ( dword_897628 )
    v10 = sub_4F11D7(v17, &v24);
  if ( !v10 )
  {
    sub_4F3A95(v18);
    return 0;
  }
  if ( v18[34] )
    v20 = 9999.0;
  else
    v20 = (float)*(signed int *)(*((_DWORD *)v18 + 3) + 172) / (float)*(unsigned int *)(*((_DWORD *)v18 + 3) + 156);
  *(float *)a4 = v20;
  v21 = dword_897634;
  *((_DWORD *)v18 + 5) = v16;
  qsort(dword_897650, v21, 4u, sub_4F37D5);
  if ( a9 )
    *(_DWORD *)a9 = *(_DWORD *)v18;
  return 1;
}

这里是汇编:

.text:004F3E6D ; =============== S U B R O U T I N E =======================================
.text:004F3E6D
.text:004F3E6D ; Attributes: bp-based frame
.text:004F3E6D
.text:004F3E6D ; int __usercall sub_4F3E6D@<eax>(char *Src@<ecx>, int, int, char, char, char, char, int)
.text:004F3E6D sub_4F3E6D      proc near               ; CODE XREF: StartAudio2D(char const * const,float,float,float,bool,bool)+3B↑p
.text:004F3E6D                                         ; sub_4EDCE9+14E↑p ...
.text:004F3E6D
.text:004F3E6D var_B0          = dword ptr -0B0h
.text:004F3E6D var_AC          = dword ptr -0ACh
.text:004F3E6D var_A8          = dword ptr -0A8h
.text:004F3E6D var_A4          = dword ptr -0A4h
.text:004F3E6D var_A0          = dword ptr -0A0h
.text:004F3E6D var_9C          = byte ptr -9Ch
.text:004F3E6D var_94          = dword ptr -94h
.text:004F3E6D Dst             = byte ptr -80h
.text:004F3E6D var_28          = dword ptr -28h
.text:004F3E6D var_24          = dword ptr -24h
.text:004F3E6D var_14          = dword ptr -14h
.text:004F3E6D var_10          = dword ptr -10h
.text:004F3E6D var_4           = dword ptr -4
.text:004F3E6D arg_0           = dword ptr  8
.text:004F3E6D arg_4           = dword ptr  0Ch
.text:004F3E6D arg_8           = byte ptr  10h
.text:004F3E6D arg_C           = byte ptr  14h
.text:004F3E6D arg_10          = byte ptr  18h
.text:004F3E6D arg_14          = byte ptr  1Ch
.text:004F3E6D arg_18          = dword ptr  20h
.text:004F3E6D
.text:004F3E6D                 push    ebp
.text:004F3E6E                 mov     ebp, esp
.text:004F3E70                 and     esp, 0FFFFFFF8h
.text:004F3E73                 sub     esp, 0B4h
.text:004F3E79                 mov     eax, ___security_cookie
.text:004F3E7E                 xor     eax, esp
.text:004F3E80                 mov     [esp+0B4h+var_4], eax
.text:004F3E87                 mov     eax, [ebp+arg_4]
.text:004F3E8A                 push    ebx
.text:004F3E8B                 push    esi
.text:004F3E8C                 push    edi
.text:004F3E8D                 mov     [esp+0C0h+var_B0], eax
.text:004F3E91                 mov     edi, edx
.text:004F3E93                 mov     eax, [ebp+arg_18]
.text:004F3E96                 xor     ebx, ebx
.text:004F3E98                 movss   [esp+0C0h+var_AC], xmm3
.text:004F3E9E                 mov     esi, ecx
.text:004F3EA0                 mov     [esp+0C0h+var_A4], edi
.text:004F3EA4                 mov     [esp+0C0h+var_A0], eax
.text:004F3EA8                 test    eax, eax
.text:004F3EAA                 jz      short loc_4F3EAE
.text:004F3EAC                 mov     [eax], ebx
.text:004F3EAE
.text:004F3EAE loc_4F3EAE:                             ; CODE XREF: sub_4F3E6D+3D↑j
.text:004F3EAE                 cmp     dword_897628, ebx
.text:004F3EB4                 jz      loc_4F4093
.text:004F3EBA                 test    esi, esi
.text:004F3EBC                 jz      loc_4F4093
.text:004F3EC2                 cmp     [esi], bl
.text:004F3EC4                 jz      loc_4F4093
.text:004F3ECA                 mov     eax, dword_8CF880
.text:004F3ECF                 cmp     [ebp+arg_C], bl
.text:004F3ED2                 jz      short loc_4F3EDC
.text:004F3ED4                 mov     al, [eax+8B8h]
.text:004F3EDA                 jmp     short loc_4F3EFC
.text:004F3EDC ; ---------------------------------------------------------------------------
.text:004F3EDC
.text:004F3EDC loc_4F3EDC:                             ; CODE XREF: sub_4F3E6D+65↑j
.text:004F3EDC                 cmp     [ebp+arg_10], bl
.text:004F3EDF                 jz      short loc_4F3EE9
.text:004F3EE1                 mov     al, [eax+8BAh]
.text:004F3EE7                 jmp     short loc_4F3EFC
.text:004F3EE9 ; ---------------------------------------------------------------------------
.text:004F3EE9
.text:004F3EE9 loc_4F3EE9:                             ; CODE XREF: sub_4F3E6D+72↑j
.text:004F3EE9                 cmp     [ebp+arg_14], bl
.text:004F3EEC                 jz      short loc_4F3EF6
.text:004F3EEE                 mov     al, [eax+8B9h]
.text:004F3EF4                 jmp     short loc_4F3EFC
.text:004F3EF6 ; ---------------------------------------------------------------------------
.text:004F3EF6
.text:004F3EF6 loc_4F3EF6:                             ; CODE XREF: sub_4F3E6D+7F↑j
.text:004F3EF6                 mov     al, [eax+8CCh]
.text:004F3EFC
.text:004F3EFC loc_4F3EFC:                             ; CODE XREF: sub_4F3E6D+6D↑j
.text:004F3EFC                                         ; sub_4F3E6D+7A↑j ...
.text:004F3EFC                 movss   xmm1, ds:dword_82A2D8
.text:004F3F04                 movzx   eax, al
.text:004F3F07                 movd    xmm0, eax
.text:004F3F0B                 cvtdq2ps xmm0, xmm0
.text:004F3F0E                 mulss   xmm0, xmm1
.text:004F3F12                 comiss  xmm1, xmm0
.text:004F3F15                 movss   [esp+0C0h+var_A8], xmm0
.text:004F3F1B                 jbe     short loc_4F3F29
.text:004F3F1D                 cmp     edi, 584B1E4Ah
.text:004F3F23                 jnz     loc_4F4093
.text:004F3F29
.text:004F3F29 loc_4F3F29:                             ; CODE XREF: sub_4F3E6D+AE↑j
.text:004F3F29                 xor     edx, edx
.text:004F3F2B                 mov     ecx, edi
.text:004F3F2D                 call    sub_4F4463
.text:004F3F32                 test    eax, eax
.text:004F3F34                 jnz     loc_4F4093
.text:004F3F3A                 push    78h             ; Size
.text:004F3F3C                 lea     eax, [esp+0C4h+Dst]
.text:004F3F40                 push    ebx             ; Val
.text:004F3F41                 push    eax             ; Dst
.text:004F3F42                 call    memset
.text:004F3F47                 add     esp, 0Ch
.text:004F3F4A                 lea     ecx, [esp+0C0h+Dst] ; Dst
.text:004F3F4E                 push    3               ; int
.text:004F3F50                 call    sub_410BA2
.text:004F3F55                 mov     cl, [ebp+arg_C]
.text:004F3F58                 test    cl, cl
.text:004F3F5A                 jz      short loc_4F3F69
.text:004F3F5C                 mov     [esp+0C0h+var_24], 9
.text:004F3F67                 jmp     short loc_4F3F88
.text:004F3F69 ; ---------------------------------------------------------------------------
.text:004F3F69
.text:004F3F69 loc_4F3F69:                             ; CODE XREF: sub_4F3E6D+ED↑j
.text:004F3F69                 cmp     [ebp+arg_10], bl
.text:004F3F6C                 jz      short loc_4F3F78
.text:004F3F6E                 or      [esp+0C0h+var_28], 4
.text:004F3F76                 jmp     short loc_4F3F88
.text:004F3F78 ; ---------------------------------------------------------------------------
.text:004F3F78
.text:004F3F78 loc_4F3F78:                             ; CODE XREF: sub_4F3E6D+FF↑j
.text:004F3F78                 cmp     [ebp+arg_14], bl
.text:004F3F7B                 jnz     short loc_4F3F88
.text:004F3F7D                 or      [esp+0C0h+var_28], 40000h
.text:004F3F88
.text:004F3F88 loc_4F3F88:                             ; CODE XREF: sub_4F3E6D+FA↑j
.text:004F3F88                                         ; sub_4F3E6D+109↑j ...
.text:004F3F88                 xor     edx, edx
.text:004F3F8A                 inc     edx
.text:004F3F8B                 cmp     [ebp+arg_8], bl
.text:004F3F8E                 jnz     short loc_4F3F94
.text:004F3F90                 test    cl, cl
.text:004F3F92                 jz      short loc_4F3FB2
.text:004F3F94
.text:004F3F94 loc_4F3F94:                             ; CODE XREF: sub_4F3E6D+121↑j
.text:004F3F94                 mov     eax, [esp+0C0h+var_28]
.text:004F3F9B                 or      eax, edx
.text:004F3F9D                 mov     [esp+0C0h+var_28], eax
.text:004F3FA4                 test    cl, cl
.text:004F3FA6                 jz      short loc_4F3FB2
.text:004F3FA8                 or      eax, 8
.text:004F3FAB                 mov     [esp+0C0h+var_28], eax
.text:004F3FB2
.text:004F3FB2 loc_4F3FB2:                             ; CODE XREF: sub_4F3E6D+125↑j
.text:004F3FB2                                         ; sub_4F3E6D+139↑j
.text:004F3FB2                 movss   xmm1, [ebp+arg_0]
.text:004F3FB7                 comiss  xmm1, ds:dword_82A2D8
.text:004F3FBE                 jbe     short loc_4F3FC9
.text:004F3FC0                 lea     ecx, [esp+0C0h+Dst]
.text:004F3FC4                 call    sub_4F0812
.text:004F3FC9
.text:004F3FC9 loc_4F3FC9:                             ; CODE XREF: sub_4F3E6D+151↑j
.text:004F3FC9                 movss   xmm1, [esp+0C0h+var_AC]
.text:004F3FCF                 lea     ecx, [esp+0C0h+Dst]
.text:004F3FD3                 call    sub_4F0855
.text:004F3FD8                 movss   xmm0, [esp+0C0h+var_A8]
.text:004F3FDE                 lea     ecx, [esp+0C0h+var_9C]
.text:004F3FE2                 maxss   xmm0, ds:dword_82A218
.text:004F3FEA                 mov     eax, [esp+0C0h+var_B0]
.text:004F3FEE                 or      [esp+0C0h+var_28], 40h
.text:004F3FF6                 minss   xmm0, ds:dword_82A46C
.text:004F3FFE                 and     [eax], ebx
.text:004F4000                 movss   [esp+0C0h+var_10], xmm0
.text:004F4009                 movss   [esp+0C0h+var_14], xmm0
.text:004F4012                 call    sub_410B78
.text:004F4017                 cmp     [ebp+arg_8], bl
.text:004F401A                 mov     eax, [esp+0C0h+var_94]
.text:004F401E                 push    1
.text:004F4020                 pop     ecx
.text:004F4021                 cmovnz  eax, ecx
.text:004F4024                 mov     [esp+0C0h+var_94], eax
.text:004F4028                 cmp     edi, 584B1E4Ah
.text:004F402E                 jnz     short loc_4F4037
.text:004F4030                 mov     edi, 7FFFFFFEh
.text:004F4035                 jmp     short loc_4F404F
.text:004F4037 ; ---------------------------------------------------------------------------
.text:004F4037
.text:004F4037 loc_4F4037:                             ; CODE XREF: sub_4F3E6D+1C1↑j
.text:004F4037                 lea     eax, [esp+0C0h+var_9C]
.text:004F403B                 mov     ecx, offset unk_59D561C
.text:004F4040                 push    ebx
.text:004F4041                 push    eax
.text:004F4042                 lea     edx, [esp+0C8h+Dst]
.text:004F4046                 call    sub_4F353D
.text:004F404B                 pop     ecx
.text:004F404C                 pop     ecx
.text:004F404D                 mov     edi, eax
.text:004F404F
.text:004F404F loc_4F404F:                             ; CODE XREF: sub_4F3E6D+1C8↑j
.text:004F404F                 mov     ecx, edi
.text:004F4051                 call    sub_4F349C
.text:004F4056                 test    al, al
.text:004F4058                 jz      short loc_4F4093
.text:004F405A                 mov     edx, [esp+0C0h+var_A4]
.text:004F405E                 lea     eax, [esp+0C0h+Dst]
.text:004F4062                 push    eax             ; int
.text:004F4063                 push    ebx             ; int
.text:004F4064                 mov     ecx, esi        ; Src
.text:004F4066                 call    sub_4F1BBB
.text:004F406B                 mov     esi, eax
.text:004F406D                 pop     ecx
.text:004F406E                 pop     ecx
.text:004F406F                 test    esi, esi
.text:004F4071                 jz      short loc_4F4093
.text:004F4073                 cmp     dword_897628, ebx
.text:004F4079                 jz      short loc_4F4088
.text:004F407B                 lea     edx, [esp+0C0h+var_9C]
.text:004F407F                 mov     ecx, esi
.text:004F4081                 call    sub_4F11D7
.text:004F4086                 mov     bl, al
.text:004F4088
.text:004F4088 loc_4F4088:                             ; CODE XREF: sub_4F3E6D+20C↑j
.text:004F4088                 test    bl, bl
.text:004F408A                 jnz     short loc_4F40AA
.text:004F408C                 mov     ecx, esi
.text:004F408E                 call    sub_4F3A95
.text:004F4093
.text:004F4093 loc_4F4093:                             ; CODE XREF: sub_4F3E6D+47↑j
.text:004F4093                                         ; sub_4F3E6D+4F↑j ...
.text:004F4093                 xor     al, al
.text:004F4095
.text:004F4095 loc_4F4095:                             ; CODE XREF: sub_4F3E6D+2B2↓j
.text:004F4095                 mov     ecx, [esp+0C0h+var_4]
.text:004F409C                 pop     edi
.text:004F409D                 pop     esi
.text:004F409E                 pop     ebx
.text:004F409F                 xor     ecx, esp
.text:004F40A1                 call    @__security_check_cookie@4 ; __security_check_cookie(x)
.text:004F40A6                 mov     esp, ebp
.text:004F40A8                 pop     ebp
.text:004F40A9                 retn
.text:004F40AA ; ---------------------------------------------------------------------------
.text:004F40AA
.text:004F40AA loc_4F40AA:                             ; CODE XREF: sub_4F3E6D+21D↑j
.text:004F40AA                 cmp     byte ptr [esi+22h], 0
.text:004F40AE                 jnz     short loc_4F40E2
.text:004F40B0                 mov     eax, [esi+0Ch]
.text:004F40B3                 movd    xmm1, dword ptr [eax+0ACh]
.text:004F40BB                 mov     eax, [eax+9Ch]
.text:004F40C1                 cvtdq2ps xmm1, xmm1
.text:004F40C4                 movd    xmm0, eax
.text:004F40C8                 cvtdq2pd xmm0, xmm0
.text:004F40CC                 shr     eax, 1Fh
.text:004F40CF                 addsd   xmm0, ds:qword_82C2D0[eax*8]
.text:004F40D8                 cvtpd2ps xmm0, xmm0
.text:004F40DC                 divss   xmm1, xmm0
.text:004F40E0                 jmp     short loc_4F40EA
.text:004F40E2 ; ---------------------------------------------------------------------------
.text:004F40E2
.text:004F40E2 loc_4F40E2:                             ; CODE XREF: sub_4F3E6D+241↑j
.text:004F40E2                 movss   xmm1, ds:dword_82A910
.text:004F40EA
.text:004F40EA loc_4F40EA:                             ; CODE XREF: sub_4F3E6D+273↑j
.text:004F40EA                 mov     eax, [esp+0C0h+var_B0]
.text:004F40EE                 push    offset sub_4F37D5 ; PtFuncCompare
.text:004F40F3                 push    4               ; SizeOfElements
.text:004F40F5                 movss   dword ptr [eax], xmm1
.text:004F40F9                 push    dword_897634    ; NumOfElements
.text:004F40FF                 mov     [esi+14h], edi
.text:004F4102                 push    offset dword_897650 ; Base
.text:004F4107                 call    ds:qsort
.text:004F410D                 mov     edx, [esp+0D0h+var_A0]
.text:004F4111                 add     esp, 10h
.text:004F4114                 test    edx, edx
.text:004F4116                 jz      short loc_4F411C
.text:004F4118                 mov     ecx, [esi]
.text:004F411A                 mov     [edx], ecx
.text:004F411C
.text:004F411C loc_4F411C:                             ; CODE XREF: sub_4F3E6D+2A9↑j
.text:004F411C                 xor     eax, eax
.text:004F411E                 inc     eax
.text:004F411F                 jmp     loc_4F4095
.text:004F411F sub_4F3E6D      endp

这里有这个函数的一个外部参照:

int v6; // eax
  int v8; // [esp+1Ch] [ebp-8h]
  int v9; // [esp+20h] [ebp-4h]

  v9 = 0;
  v6 = sub_73A34B(a1, 0);
  sub_4F3E6D((char *)a1, v6, SLODWORD(a4), (int)&v9, a5, a6, 0, 0, (int)&v8);

我没有使用此代码尝试过的组装经验:

// char __usercall sub_4F3E6D@<al>(char *Src@<ecx>, int a2@<edx>, int a3, int a4, char a5, char a6, char a7, char a8, int a9)
    
    typedef char(__fastcall *HookFile) (char* src, int a2, int a3, int a4, char a5, char a6, char a7, char a8, int a9);
    
    __declspec(naked) char HookSoundFileSub(char* src, int a2, int a3, int a4, char a5, char a6, char a7, char a8, int a9)
    {
        HookFile originalFunction = (HookFile)AddressOfHookSoundFunction; // 0x4F4463
    
        __asm {
            mov ecx, src
            mov edx, a2
            call AddressOfHookSoundFunction
        }
    
    
        // Apply  my code
        // std::string FileName;
        // FileName = SC::To_String(src);
        // .....
        
        return originalFunction(src, a2,a3,a4,a5,a6,a7,a8,a9);
    }



   // DetourAttach(&(LPVOID&)AddressOfHookSoundFunction, &HookSoundFileSub);

但不能编译,因为裸函数似乎不允许在程序集之外添加代码。

你能帮我吗 ?

1个回答

正如您的问题所示,您需要将所有非汇编代码移出naked函数。尽管我之前从未真正使用过 Detours——我编写了自己的挂钩库——但我会做的是编写一个小存根,允许我__usercall使用普通的调用约定调用函数。

小心调用约定。很容易弄乱堆栈更正,导致崩溃。当你进入二进制挂钩时,调试这样的东西是工作的一部分。如果遇到崩溃,请在所有汇编序列的开始和结束处设置断点,并记下esp每个点处的值

像这样的东西:

// Here's your hook, the ASM part. It just redirects execution to the _C function below
// Note I removed the first two arguments, the ones in registers
__declspec(naked) __cdecl char HookSoundFileSub_ASM(int a3, int a4, char a5, char a6, char a7, char a8, int a9)
{
    __asm {
        push a9
        push a8
        push a7
        push a6
        push a5
        push a4
        push a3
        push edx // a2 in edx
        push ecx // src in ecx
        call HookSoundFileStub_C
        ret // Don't need to correct the stack here
    }
}

// Here's your hook, the C part. Do whatever you want in here
char __stdcall HookSoundFileStub_C(char* src, int a2, int a3, int a4, char a5, char a6, char a7, char a8, int a9)
{
    // Your original hook code
    // Apply  my code
    // std::string FileName;
    // FileName = SC::To_String(src);
    
    // Call the original function
    return CallOriginalFunction(src, a2, a3, a4, a5, a6, a7, a8, a9);
}

// We moved this outside of the naked function
DWORD AddressOfHookSoundFunction = 0x4F4463;

// This just allows us to call the original function from C code
__declspec(naked) __stdcall char CallOriginalFunction(char* src, int a2, int a3, int a4, char a5, char a6, char a7, char a8, int a9)
{
    __asm {
        mov ecx, src
        mov edx, a2
        push a9
        push a8
        push a7
        push a6
        push a5
        push a4
        push a3
        mov eax, AddressOfHookSoundFunction
        call eax
        add esp, 1ch // Target doesn't clear the stack, so do that
        retn 24h // Also clear the arguments passed to this function
    }
}

// DetourAttach(&(LPVOID&)AddressOfHookSoundFunction, &HookSoundFileSub_ASM);