美文网首页
HOOK原理分析

HOOK原理分析

作者: 我家有个小太阳 | 来源:发表于2016-05-19 20:22 被阅读2226次

    先把用来HOOK的函数贴出来,然后逐过程解释
    LPVOID DetourFunc(BYTE *src, const BYTE *dst, int len, int TYPE, PMEMORYINFO lpMemInfo) { if (lpMemInfo) { lpMemInfo->dwAddr = (DWORD)src; lpMemInfo->len = len; lpMemInfo->lpOriginCode = (PBYTE)malloc(len + 0x5); memcpy_m(lpMemInfo->lpOriginCode, src, len); lpMemInfo->IsHook = TRUE; } DWORD lpOld; VirtualProtect(src, len, PAGE_EXECUTE_READWRITE, &lpOld); switch (TYPE) { case DETOUR_TYPE_JMP: src[0] = 0xE9; break; case DETOUR_TYPE_CALL: src[0] = 0xE8; break; } *(DWORD*)(src + 1) = (DWORD)(dst - src) - 5; BYTE* Addr = src + 5; BYTE* dstination = src + len; BYTE* pCode = lpMemInfo->lpOriginCode + len; *pCode = 0xE9; *(DWORD*)(pCode + 0x1) = (DWORD)(dstination - pCode) - 5; while (Addr != dstination) { *Addr = 0x90; Addr++; } VirtualProtect(src, len, lpOld, &lpOld); VirtualProtect((LPVOID)lpMemInfo->lpOriginCode, len + 0x5, PAGE_EXECUTE_READWRITE, &lpOld); return (src+len); }

    lpMemInfo是一个结构体,用来存放HOOK的一些信息,它的各属性的含义是
    • dwAddr: HOOK的目标地址
    • len: 覆盖的字节大小
    • lpOriginCode: 一个指向一段空间的指针,这段空间用来存放目标地址处的原代码
    • IsHook: 一个布尔型变量用来存放对HOOK动作的判断

    接下来解释代码
    结构体初始化.png

    方框中的部分分配了一段大小为len+0x5大小的空间,并把原始数据存入

    绘图_刚分配后.png
    置入跳转方式.png

    上面这段代码的意思就是置入跳转方式,把HOOK的地址的第一个字节改为JMP或者CALL,0xE9代表JMP,0xE8代表CALL


    *(DWORD*)(src + 1) = (DWORD)(dst - src) - 5;

    上面这行代码的意思是将接下来的四个字节写入要跳转的地址,因为是指向DWORD的指针,所以是4个字节。所以在CALL之前进行HOOK的话,必须保证HOOK地址与CALL之间的距离大于5个字节


    BYTE* pCode = lpMemInfo->lpOriginCode + len; *pCode = 0xE9;

    修改后.png

    上面代码的作用就是把lpOriginCode指向的空间的后5个字节变成一个跳转到HOOK地址加Len的地方

    汇编片段.png

    在上图中,如果我们的HOOK地址是0x0351C853,那么JMP语句跳转到CALL地址,0x0351C858,len为5


    while (Addr != dstination) { *Addr = 0x90; Addr++; }

    如果len > 5的话,将JMP语句到CALL之间的语句置为空指令nop(代码字节为0x90)
    VirtualProtect函数的作用是改变一段内存区域的访问权限


    最后函数的返回值为CALL的地址


    下面是HOOK函数的使用方法

    我的HOOK函数.png

    _Skin()函数作为HOOK函数的*BYTE dst参数传入,当被HOOK的地址被运行时会跳转到_Skin()函数,pushad用来保护寄存器,之后我们可以调用自己的函数(这里为_Skin_Data())作其它处理


    使用popad、popfd恢复寄存器后,我们需要把上面HOOK过程中被覆盖的代码加上去之后再调用reCall(HOOK函数的返回值)


    HOOK函数中被保存的原始代码和结构体的一些属性这里并没有用到,可以省略
    整个HOOK过程到此结束,作者Q49909509,欢迎交流-_-.

    相关文章

      网友评论

          本文标题:HOOK原理分析

          本文链接:https://www.haomeiwen.com/subject/dlpgrttx.html