hook模板x86/x64通用版(3)--CHook.h说明

来源:互联网 发布:c语言vector用法 编辑:程序博客网 时间:2024/05/19 09:11

因为注释比较齐全,所以不多说别的了。

Hook.h:

#pragma once#ifdef _UNICODE#define _T(x)      L ## x#else#define _T(x)      x#endif#ifdef _WIN64#define WriteCall      WriteCall_x64#define WriteJMP       WriteJMP_x64#else#define WriteCall      WriteCall_x86#define WriteJMP       WriteJMP_x86#endif#ifdef _WIN64//普通hook的shellcode大小#define TRANSFER_FUNC_SIZE0xcd//API hook的shellcode大小#define TRANSFER_FUNC_FOR_CALL_SIZE0x193//64位下跳转指令需要的空间大小#define JMP_CODE_LEN0xe//参数结构struct ST_PARAMS {//ST_REGISTER结构中RSP后面的5个寄存器还有0x20的保护空间,一共9个,用不到也别修改 const DWORD64 no_use[9]; //不包含返回地址,返回地址会先pop掉DWORD64 pdwParams[]; //非API头的hook不要使用该结构};//保存hook现场的结构,一般x64的前四个参数是按顺序安排在RCX,RDX,R8,R9struct ST_REGISTER{DWORD64 dw64_R15;DWORD64 dw64_R14;DWORD64 dw64_R13;DWORD64 dw64_R12;DWORD64 dw64_R11;DWORD64 dw64_R10;union{DWORD64 dw64_R9;DWORD64 dw64_Param3;};union{DWORD64 dw64_R8;DWORD64 dw64_Param2;};DWORD64 dw64_Rdi;DWORD64 dw64_Rsi;union{DWORD64 dw64_Rsp;ST_PARAMS* pstMoreParams;};DWORD64 dw64_Rbp;DWORD64 dw64_Rbx;union{DWORD64 dw64_Rdx;DWORD64 dw64_Param1;};union{DWORD64 dw64_Rcx;DWORD64 dw64_Param0;};DWORD64 dw64_Rax;};#else//普通hook的shellcode大小#define TRANSFER_FUNC_SIZE0x49//API hook的shellcode大小#define TRANSFER_FUNC_FOR_CALL_SIZE0x7d//32位下跳转指令需要的空间大小#define JMP_CODE_LEN5//保存hook现场的结构struct ST_REGISTER{DWORD dw_edi;DWORD dw_esi;DWORD dw_ebp;union{DWORD dw_esp;DWORD* pParamsOfCall;//API头的hook使用该结构可以修改参数数值};DWORD dw_ebx;DWORD dw_edx;DWORD dw_ecx;DWORD dw_eax;};#endifclass CHook{public://一个类只hook一个地址,所以在构造函数这里进行hook防止用户多次调用CHook(void* pOriginAdr , void* pNewHook);CHook(void* pOriginAdr , void* pNewHook , void* pHookAfterCall);~CHook(void);//移除hook的函数,未作测试=。=BOOL RemoveHook();//直接移除hook的函数,在本hook的用户函数中调用的话会出大事,所以名字加了unsafe。//在其他地方调用的话要确保没有运行到该hook的代码,所以最好还是调用上面那个函数BOOL RemoveHook_unsafe();//获取hook点现场ST_REGISTER* GetRegOnHookPoint();private://初始化,然而并没有初始化多少东西void Init();//给某地址写跳转指令void WriteJMP_x86(DWORD_PTR dwFrom , DWORD_PTR dwTo);void WriteJMP_x64(DWORD_PTR dwFrom , DWORD_PTR dwTo);//给某地址写一个call指令void WriteCall_x86(DWORD_PTR dwFrom , DWORD_PTR dwTo);void WriteCall_x64(DWORD_PTR dwFrom , DWORD_PTR dwTo);//在地址pOriginAdr设置普通hook,用户定义回调函数pNewHookBOOL SetHook(void* pOriginAdr , void* pNewHook);//在函数头pOriginAdr设置hook,用户定义回调函数pNewHook在函数执行前运行,用于拦截和修改参数;//pHookAfterCall在函数执行后运行,用于拦截和修改函数返回。pNewHook和pHookAfterCall不可同时为空BOOL SetHook(void* pOriginAdr , void* pNewHook , void* pHookAfterCall);//迁移、保存hook点被破坏的代码int TransplantCode( void* pOriginAdr , BYTE* pDestAdr);//保存hook现场的Tls索引DWORD m_dwTlsIndexForRegister;//保存API头hook保存函数返回地址的Tls索引DWORD m_dwTlsIndexForRetAdr;//保存hook点地址void* m_pOrigin_Adr;//保存hook点被破坏的指令长度int m_nOrigin_CodeLen;//hook点被破坏的指令迁移到的地址BYTE* m_pOldCode;//每个CHook类初始化时会申请一块内存,把shellcode复制进去并修正一些偏移,作为中转函数BYTE* m_szMyTransfer;//单纯c3返回的函数,用于API hook时候某个用户定义的函数为空的时候直接调用这个函数//在修正shellcode的时候能简化一点操作static BYTE* m_szRet;//普通hook的shellcode模板static BYTE m_szTransferFunction[TRANSFER_FUNC_SIZE];//API hook的shellcode模板static BYTE m_szTransferFunction_ForCall[TRANSFER_FUNC_FOR_CALL_SIZE];};


0 0
原创粉丝点击