Mhook_SetHook函数流程

Mhook_SetHook函数流程:
1.EnterCritSec 互斥进入关键Section

2.SkipJumps 查找 被HOOK函数 或者 HOOK函数的真实入口地址,通过判断函数地址前几个字节是为JMP,机器码为E9/FF25/EB
E9+32位偏移 FF25+绝对地址 EB+8位偏移

3.DisassembleAndSkip 函数 在被HOOK函数中查找修改的地址和长度,过滤RET  JMP/JNE...分支,CALL等指令

4.SuspendOtherThreads 函数 挂起该进程所有线程 ----->SuspendOneThread 通过GetThreadContext获取每个线程的上下文,检查线程是否执行着 被HOOK函数中需要被修改地址的指令,如果是则ResumeThread该线程,令该线程执行过那些指令,然后再挂起该线程,而本线程Sleep一下。

5.TrampolineAlloc 查找分配存储inline信息块的进程虚拟空间

6.通过VirtualProtectEx修改被HOOK函数的虚拟地址页属性,也设置存储inline信息块的空间的页属性,令其为可执行的,因为inline信息块中保存了被HOOK函数被修改的指令和再跳转到被HOOK函数的被修改的地址后的指令。

7.设置inline信息块
struct MHOOKS_TRAMPOLINE {
PBYTE pSystemFunction; //被HOOK的函数地址
DWORD cbOverwrittenCode; //需要在被HOOK函数的改写的指令长度
PBYTE pHookFunction; //我们的HOOK函数地址
BYTE codeJumpToHookFunction[MHOOKS_MAX_CODE_BYTES];//跳转到我们的HOOK函数的指令
BYTE codeTrampoline[MHOOKS_MAX_CODE_BYTES]; //跳转到被HOOK函数修改后的指令
BYTE codeUntouched[MHOOKS_MAX_CODE_BYTES]; //被修改的指令
};

7.1 首先把被HOOK函数需要被修改的指令保存在codeUntouched数组中,也保存在codeTrampoline数组中

7.2 然后在codeTrampoline后面加上跳转到原来修改后HOOK函数的指令,通过EmitJump函数完成,从当前 codeTrampoline地址跳到修改后HOOK函数的地址,通过地址比较,如果是小于等于0x7fff0000,则用E9+32位偏移,反之,用FF25 + 绝对地址。

7.3 再设置跳转到我们的HOOK函数的指令保存在codeJumpToHookFunction数组,比较被HOOK函数和HOOK函数的真实入口地址,也是通过EmitJump完成。

7.4 FlushInstructionCache 修改指令

8.更新所谓原来被HOOK函数的地址为codeTrampoline,因为codeTrampoline保存了被修改的指令和跳转到原来 修改后HOOK函数的指令。

9.ResumeOtherThreads重起所有挂起的线程

10.LeaveCritSec 离开关键Section
转载:http://blog.chinaunix.net/uid-150063-id-3145529.html
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页