代码之家  ›  专栏  ›  技术社区  ›  MikeO

挂接函数时,为什么覆盖前5个字节并不重要?

  •  0
  • MikeO  · 技术社区  · 8 年前

    当挂接一个函数时,需要覆盖原始函数的5个字节,堆栈框架的初始设置并不重要,因为签名和调用约定与替换函数的原始函数相同,但我没有得到的是覆盖了原始函数的前几个字节。55(push ebp)8B EC(mov ebp,esp),那么您还需要2个?为什么覆盖那些对函数至关重要的提取2字节并不重要?

    00440112                         ; int __cdecl function(int, FILE *)
    .text:00440112                         var_410         = byte ptr -410h
    .text:00440112                         var_310         = byte ptr -310h
    .text:00440112                         var_210         = byte ptr -210h
    .text:00440112                         var_110         = byte ptr -110h
    .text:00440112                         var_10          = byte ptr -10h
    .text:00440112                         var_4           = dword ptr -4
    .text:00440112                         arg_0           = dword ptr  8
    .text:00440112                         arg_4           = dword ptr  0Ch
    .text:00440112
    .text:00440112 55                                      push    ebp
    .text:00440113 8B EC                                   mov     ebp, esp
    .text:00440115 81 EC 10 04 00 00                       sub     esp, 410h
    .text:0044011B 53                                      push    ebx
    .text:0044011C 56                                      push    esi
    .text:0044011D 8B 75 0C                                mov     esi, [ebp+arg_4]
    .text:00440120 80 7E 04 00                             cmp     byte ptr [esi+4], 0
    .text:00440124 57                                      push    edi
    .text:00440125 C7 86 10 01 00 00 63 00+                mov     dword ptr [esi+110h], 63h
    .text:0044012F 74 0F                                   jz      short loc_440140
    .text:00440131 83 3D 7A 4E 4B 00 00                    cmp     dword_4B4E7A, 0
    .text:00440138 7F 06                                   jg      short loc_440140
    .text:0044013A 83 65 FC 00                             and     [ebp+var_4], 0
    .text:0044013E EB 07                                   jmp     short loc_440147
    

    拿着上面的组件。”E9“将替换“55 8B EC 81 EC”(“”是要跳转到的函数的地址),所以我认为,当调用的新函数在0x44011B跳转回原始函数时,不会在堆栈上为本地变量分配0x410;为什么这无关紧要?我不知道我错过了什么。

    如果您想重现允许您使用此方法挂接函数的功能代码,请参阅MyUsername112358的答案 HERE

    1 回复  |  直到 7 年前
        1
  •  2
  •   a3f    8 年前

    ia32hook ,它使用 OllyDbg disassembler 找出切断的地方。 The relevant snippet :

    #include "ollydisasm/disasm.h"
    
    static inline unsigned long CleanBiteOff(const unsigned char *ptr, size_t amount)
    {
        static t_disasm disasm;
        unsigned long size = 0;
        do {size += Disasm(ptr+size, 16, ptr+size, &disasm, DISASM_SIZE);} while(size < amount);
        return size;
    }
    

    这个 size returned是您需要复制的字节数。在蹦床的末尾,您复制这些字节时,会跳回 (char*)func+size 一切都好了。

    您链接的答案也没有刷新指令缓存,如果指令指针恰好指向您要修补的字节,则会出现严重问题。您应该暂停线程,并断言 eip 没有指向要修补的字节。

    如果这不是出于学习目的,请考虑使用以下解决方案 Microsoft Detours 相反