用 CPU 寄存器挂钩裸函数

逆向工程 C++ 函数挂钩 汇编
2021-06-18 10:55:31

我需要挂钩这个功能:

.text:005589CB sub_5589CB      proc near               ; CODE XREF: AddHealth(int,long)+1A↑j
.text:005589CB                                         ; sub_5328D8+98E↑p ...
.text:005589CB
.text:005589CB var_4           = dword ptr -4
.text:005589CB
.text:005589CB                 xorps   xmm0, xmm0
.text:005589CE                 ucomiss xmm1, xmm0
.text:005589D1                 lahf
.text:005589D2                 test    ah, 44h
.text:005589D5                 jnp     short locret_558A1D
.text:005589D7                 movss   xmm2, dword ptr [ecx+564h]
.text:005589DF                 comiss  xmm2, xmm0
.text:005589E2                 jbe     short locret_558A1D
.text:005589E4                 cmp     ecx, dword_89A288
.text:005589EA                 jnz     short loc_5589FF
.text:005589EC                 comiss  xmm1, xmm0
.text:005589EF                 ja      short loc_5589FF
.text:005589F1                 mov     eax, dword_8CF880
.text:005589F6                 cmp     byte ptr [eax+4BBh], 0
.text:005589FD                 jnz     short locret_558A1D
.text:005589FF
.text:005589FF loc_5589FF:                             ; CODE XREF: sub_5589CB+1F↑j
.text:005589FF                                         ; sub_5589CB+24↑j
.text:005589FF                 movss   xmm0, dword ptr [ecx+560h]
.text:00558A07                 mov     eax, [ecx]
.text:00558A09                 addss   xmm0, xmm1
.text:00558A0D                 push    ecx
.text:00558A0E                 minss   xmm0, xmm2
.text:00558A12                 movss   [esp+4+var_4], xmm0
.text:00558A17                 call    dword ptr [eax+144h]
.text:00558A1D
.text:00558A1D locret_558A1D:                          ; CODE XREF: sub_5589CB+A↑j
.text:00558A1D                                         ; sub_5589CB+17↑j ...
.text:00558A1D                 retn
.text:00558A1D sub_5589CB      endp
.text:00558A1D
.text:00558A1E ; ---------------------------------------------------------------------------
.text:00558A1E                 mov     eax, [ecx+420h]
.text:00558A24                 retn

这里IDA伪代码:

void *__usercall sub_5589CB@<eax > (float *a1@<ecx > , char a2@<efl > , float a3@<xmm1 > )

过去,我用这样的代码毫无问题地连接了其他裸函数:

__declspec(naked)  void *  HookFunction(float *a1 , char a2, float  a3)
{
    __asm
    {

        pushad // backup general purpose registers
    }

    MyExternalFunction();

    __asm
    {
        popad // restore general purpose registers
            
        jmp AddressOfHookFunction
    }

}

但这次有一些 CPU 寄存器,如“xmm1”,没有被 pushad/popad 覆盖,结果是如果我调用“MyExternalFunction”,该函数会丢失注册表的值。

有没有办法备份/恢复 efl 和 xmm1 寄存器?

谢谢 !

1个回答

没有推送xmm寄存器的说明,但您可以执行以下操作:

__asm
{
    sub     esp, 16
    movdqu  [esp], xmm0
    sub     esp, 16
    movdqu  [esp], xmm1

    pushad
}

MyExternalFunction();

__asm
{
    popad

    movdqu  xmm1, [esp]
    add     esp, 16
    movdqu  xmm0, [esp]
    add     esp, 16

    jmp AddressOfHookFunction
}