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

来源:互联网 发布:sql check约束表达式 编辑:程序博客网 时间:2024/06/04 11:54

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

#include "StdAfx.h"#include "Hook.h"//导入bea反汇编引擎#define BEA_ENGINE_STATIC  #define BEA_USE_STDCALL    #include "../beaEngine/headers/BeaEngine.h"#ifdef _WIN64#pragma comment(lib, "../beaEngine/win64/lib/BeaEngineCheetah64.lib")#pragma comment(linker,"/nodefaultlib:crt64.lib")#else#pragma comment(lib, "../beaEngine/win32/lib/BeaEngineCheetah.lib")#pragma comment(linker,"/nodefaultlib:crt.lib")#endif//BeaEngine end//静态成员初始化BYTE* CHook::m_szRet = 0;//中转函数的shellcode#ifdef _WIN64BYTE CHook::m_szTransferFunction[TRANSFER_FUNC_SIZE] = {0x50 , 0x51 , 0x52 , 0xB9 , 0x00 , 0x00 , 0x00 , 0x00 , 0x48 , 0x89 , 0xE2 , 0x48 , 0x83 , 0xea , 0x68 , 0x48 , 0x83 , 0xec , 0x20 , 0xE8 , 0x00 , 0x00 , 0x00 , 0x00 , 0x83 , 0x04 , 0x24 , 0x12 , 0x68 , 0x00 , 0x00 , 0x00 , 0x00 , 0xC7 , 0x44 , 0x24 , 0x04 , 0x00 , 0x00 , 0x00 , 0x00 , 0xC3 , 0x48 , 0x83 , 0xc4 , 0x20 ,0x53 , 0x55 , 0x54 , 0x56 , 0x57 , 0x41 , 0x50 , 0x41 , 0x51 , 0x41 , 0x52 , 0x41 , 0x53 , 0x41 , 0x54 , 0x41 , 0x55 , 0x41 , 0x56 , 0x41 , 0x57 , 0xE8 , 0x00 , 0x00 , 0x00 , 0x00 , 0x83 , 0x04 , 0x24 , 0x12 , 0x68 , 0x00 , 0x00 , 0x00 , 0x00 , 0xC7 , 0x44 , 0x24 , 0x04 , 0x00 , 0x00 , 0x00 , 0x00 , 0xC3 , 0x41 , 0x5F , 0x41 , 0x5E , 0x41 , 0x5D , 0x41 , 0x5C , 0x41 , 0x5B , 0x41 , 0x5A , 0x41 , 0x59 , 0x41 , 0x58 , 0x5F , 0x5E , 0x5C , 0x5D , 0x5B , 0x5A , 0x59 , 0x58 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x9c , 0x50 , 0x51 , 0x52 , 0x48 , 0x83 , 0xec , 0x20 , 0xB9 , 0x00 , 0x00 , 0x00 , 0x00 , 0x48 , 0x31 , 0xD2 , 0xE8 , 0x00 , 0x00 , 0x00 , 0x00 , 0x83 , 0x04 , 0x24 , 0x12 , 0x68 , 0x00 , 0x00 , 0x00 , 0x00 , 0xC7 , 0x44 , 0x24 , 0x04 , 0x00 , 0x00 , 0x00 , 0x00 , 0xC3 , 0x48 , 0x83 , 0xc4 , 0x20 , 0x5A , 0x59 , 0x58 , 0x9d , 0x68 , 0x00 , 0x00 , 0x00 , 0x00 , 0xC7 , 0x44 , 0x24 , 0x04 , 0x00 , 0x00 , 0x00 , 0x00 , 0xC3};BYTE CHook::m_szTransferFunction_ForCall[TRANSFER_FUNC_FOR_CALL_SIZE] = {0x50 , 0x51 , 0x52 , 0x\B9 , 0x78 , 0x56 , 0x34 , 0x12 , 0x\48 , 0x87 , 0x54 , 0x24 , 0x18 , 0x48 , 0x83 , 0xEC , 0x20 , 0x\E8 , 0x00 , 0x00 , 0x00 , 0x00 , 0x83 , 0x04 , 0x24 , 0x12 , 0x68 , 0x78 , 0x56 , 0x34 , 0x12 , 0xC7 , 0x44 , 0x24 , 0x04 , 0x21 , 0x43 , 0x65 , 0x87 , 0xC3 , 0x\48 , 0x83 , 0xC4 , 0x20 , 0x\B9 , 0x78 , 0x56 , 0x34 , 0x12 , 0x\48 , 0x89 , 0xE2 , 0x48 , 0x83 , 0xEA , 0x68 , 0x48 , 0x83 , 0xEC , 0x20 , 0x\E8 , 0x00 , 0x00 , 0x00 , 0x00 , 0x83 , 0x04 , 0x24 , 0x12 , 0x68 , 0x78 , 0x56 , 0x34 , 0x12 , 0xC7 , 0x44 , 0x24 , 0x04 , 0x21 , 0x43 , 0x65 , 0x87 , 0xC3 , 0x\48 , 0x83 , 0xC4 , 0x20 , 0x53 , 0x55 , 0x54 , 0x56 , 0x57 , 0x41 , 0x50 , 0x41 , 0x51 , 0x41 , 0x52 , 0x41 , 0x53 , 0x41 , 0x54 , 0x41 , 0x55 , 0x41 , 0x56 , 0x41 , 0x57 , 0x\E8 , 0x00 , 0x00 , 0x00 , 0x00 , 0x83 , 0x04 , 0x24 , 0x12 , 0x68 , 0x78 , 0x56 , 0x34 , 0x12 , 0xC7 , 0x44 , 0x24 , 0x04 , 0x21 , 0x43 , 0x65 , 0x87 , 0xC3 , 0x\41 , 0x5F , 0x41 , 0x5E , 0x41 , 0x5D , 0x41 , 0x5C , 0x41 , 0x5B , 0x41 , 0x5A , 0x41 , 0x59 , 0x41 , 0x58 , 0x5F , 0x5E , 0x5C , 0x5D , 0x5B , 0x5A , 0x59 , 0x58 , 0x48 , 0x83 , 0xC4 , 0x08 , 0x\68 , 0x78 , 0x56 , 0x34 , 0x12 , 0xC7 , 0x44 , 0x24 , 0x04 , 0x21 , 0x43 , 0x65 , 0x87 , 0x\90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x\50 , 0x51 , 0x52 , 0x\B9 , 0x78 , 0x56 , 0x34 , 0x12 , 0x\48 , 0x89 , 0xE2 , 0x48 , 0x83 , 0xEA , 0x68 , 0x48 , 0x83 , 0xEC , 0x20 , 0x\E8 , 0x20 , 0x00 , 0x00 , 0x00 , 0x83 , 0x04 , 0x24 , 0x12 , 0x68 , 0x78 , 0x56 , 0x34 , 0x12 , 0xC7 , 0x44 , 0x24 , 0x04 , 0x21 , 0x43 , 0x65 , 0x87 , 0xC3 , 0x\48 , 0x83 , 0xC4 , 0x20 , 0x53 , 0x55 , 0x54 , 0x56 , 0x57 , 0x41 , 0x50 , 0x41 , 0x51 , 0x41 , 0x52 , 0x41 , 0x53 , 0x41 , 0x54 , 0x41 , 0x55 , 0x41 , 0x56 , 0x41 , 0x57 , 0x\E8 , 0x20 , 0x00 , 0x00 , 0x00 , 0x83 , 0x04 , 0x24 , 0x12 , 0x68 , 0x78 , 0x56 , 0x34 , 0x12 , 0xC7 , 0x44 , 0x24 , 0x04 , 0x21 , 0x43 , 0x65 , 0x87 , 0xC3 , 0x\41 , 0x5F , 0x41 , 0x5E , 0x41 , 0x5D , 0x41 , 0x5C , 0x41 , 0x5B , 0x41 , 0x5A , 0x41 , 0x59 , 0x41 , 0x58 , 0x5F , 0x5E , 0x5C , 0x5D , 0x5B , 0x5A , 0x59 , 0x\B9 , 0x78 , 0x56 , 0x34 , 0x12 , 0x\48 , 0x83 , 0xEC , 0x20 , 0x\E8 , 0x20 , 0x00 , 0x00 , 0x00 , 0x83 , 0x04 , 0x24 , 0x12 , 0x68 , 0x78 , 0x56 , 0x34 , 0x12 , 0xC7 , 0x44 , 0x24 , 0x04 , 0x21 , 0x43 , 0x65 , 0x87 , 0xC3 , 0x\48 , 0x83 , 0xC4 , 0x20 , 0x48 , 0x87 , 0x04 , 0x24 , 0x50 , 0x51 , 0x52 , 0x48 , 0x83 , 0xEC , 0x20 , 0x\B9 , 0x78 , 0x56 , 0x34 , 0x12 , 0x\48 , 0x31 , 0xD2 , 0x\E8 , 0x20 , 0x00 , 0x00 , 0x00 , 0x83 , 0x04 , 0x24 , 0x12 , 0x68 , 0x78 , 0x56 , 0x34 , 0x12 , 0xC7 , 0x44 , 0x24 , 0x04 , 0x21 , 0x43 , 0x65 , 0x87 , 0xC3 , 0x\48 , 0x83 , 0xC4 , 0x20 , 0x5A , 0x59 , 0x58 , 0xC3};#elseBYTE CHook::m_szTransferFunction[TRANSFER_FUNC_SIZE] = {0x50 , 0x54 , 0x83 , 0x2C , 0x24 , 0x1C , 0x68 , /*[pos:0x7]*/0x00 , 0x00 , 0x00 , 0x00 , 0xE8 , /*[pos:0xc]*/0x00 , 0x00 , 0x00 , 0x00 , 0x58 , 0x60 , 0xE8 , /*[pos:0x13]*/0x00 , 0x00 , 0x00 , 0x00 , 0x61 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x50 , 0x6A , 0x00 , 0x68 , /*[pos:0x3a]*/0x00 , 0x00 , 0x00 , 0x00 , 0xE8 , /*[pos:0x3f]*/0x00 , 0x00 , 0x00 , 0x00 , 0x58 , 0xE9 , /*[pos:0x45]*/0x00 , 0x00 , 0x00 , 0x00};BYTE CHook::m_szTransferFunction_ForCall[TRANSFER_FUNC_FOR_CALL_SIZE] = {0x87 , 0x04 , 0x24 , 0x50 , 0x68 , /*[pos:0x5]*/0x00 , 0x00 , 0x00 , 0x00 , 0xE8 , /*[pos:0xa]*/0xC9 , 0xFB , 0xD1 , 0x76 , 0x54 , 0x83 , 0x2C , 0x24 , 0x1C , 0x68 , /*[pos:0x14]*/0x00 , 0x00 , 0x00 , 0x00 , 0xE8 , /*[pos:0x19]*/0xBA , 0xFB , 0xD1 , 0x76 , 0x58 , 0x60 , 0xE8 , /*[pos:0x20]*/0x2F , 0xE7 , 0xFF , 0xFF , 0x61 , 0x68 , /*[pos:0x26]*/0x00 , 0x00 , 0x00 , 0x00 , /*[pos:0x2a]*/0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , /*[pos:0x48]*/0x50 , 0x54 , 0x83 , 0x2C , 0x24 , 0x1C , 0x68 , /*[pos:0x4f]*/0x00 , 0x00 , 0x00 , 0x00 , 0xE8 , /*[pos:0x54]*/0x7F , 0xFB , 0xD1 , 0x76 , 0x58 , 0x60 , 0xE8 , /*[pos:0x5b]*/0xF4 , 0xE6 , 0xFF , 0xFF , 0x61 , 0x50 , 0x68 , /*[pos:0x62]*/0x00 , 0x00 , 0x00 , 0x00 , 0xE8 , /*[pos:0x67]*/0xC8 , 0xF8 , 0xD1 , 0x76 , 0x87 , 0x04 , 0x24 , 0x50 , 0x6A , 0x00 , 0x68 , /*[pos:0x72]*/0x00 , 0x00 , 0x00 , 0x00 , 0xE8 , /*[pos:0x77]*/0x5C , 0xFB , 0xD1 , 0x76 , 0x58 , 0xC3};#endif//dllmain中创建线程dwWaitThread,调用MyEntry.cpp的StartHook函数//在暴露给用户的MyEntry.cpp中隐藏起来这些东西。extern void WINAPI StartHook();DWORD WINAPI dwWaitThread( LPVOID lpArgs ){StartHook();return 0;}//写jmp的x86版本函数void CHook::WriteJMP_x86(DWORD_PTR dwFrom , DWORD_PTR dwTo){DWORD_PTR dwAdr = dwFrom;DWORD dwOldP;VirtualProtect((LPVOID)dwAdr , 0x100 , PAGE_EXECUTE_READWRITE , &dwOldP);*(BYTE*)dwAdr = 0xE9;dwAdr+=1;*(DWORD*)dwAdr = dwTo - (dwFrom + 5);}//写call的x86版本函数void CHook::WriteCall_x86(DWORD_PTR dwFrom , DWORD_PTR dwTo){DWORD_PTR dwAdr = dwFrom;DWORD dwOldP;VirtualProtect((LPVOID)dwAdr , 0x100 , PAGE_EXECUTE_READWRITE , &dwOldP);*(BYTE*)dwAdr = 0xE8;dwAdr+=1;*(DWORD*)dwAdr = dwTo - (dwFrom + 5);}//类构造函数CHook::CHook(void* pOriginAdr , void* pNewHook){Init();SetHook(pOriginAdr , pNewHook);}CHook::CHook(void* pOriginAdr , void* pNewHook , void* pHookAfterCall){Init();SetHook(pOriginAdr , pNewHook , pHookAfterCall);}//析构函数CHook::~CHook(void){//等待hook函数走完再析构和释放if (m_szMyTransfer){while (TlsGetValue(m_dwTlsIndexForRegister)){Sleep(500);}RemoveHook();delete[] m_szMyTransfer;}TlsFree(m_dwTlsIndexForRegister);TlsFree(m_dwTlsIndexForRetAdr);}//获取hook点现场ST_REGISTER* CHook::GetRegOnHookPoint(){return (ST_REGISTER*)TlsGetValue(m_dwTlsIndexForRegister);}void CHook::Init(){//初始化两个Tls变量m_dwTlsIndexForRetAdr = TlsAlloc();TlsSetValue(m_dwTlsIndexForRetAdr , 0);m_dwTlsIndexForRegister = TlsAlloc();TlsSetValue(m_dwTlsIndexForRegister , 0);//初始化“直接返回”的函数体,一字节0xc3DWORD dwOld;if (!m_szRet){m_szRet = new BYTE[1];*m_szRet = 0xc3;VirtualProtect(m_szRet , 100 , PAGE_EXECUTE_READWRITE , &dwOld);}}//设置普通hookBOOL CHook::SetHook( void* pOriginAdr , void* pNewHook ){//创建一块内存区域用于存放shellcodeDWORD dwOld;m_szMyTransfer = new BYTE[TRANSFER_FUNC_SIZE];memcpy(m_szMyTransfer , m_szTransferFunction , TRANSFER_FUNC_SIZE);VirtualProtect(m_szMyTransfer , 100 , PAGE_EXECUTE_READWRITE , &dwOld);//shellcode中需要修正的位置保存成数组,方便编译#ifdef _WIN64unsigned int szOffset[] = {0x4 , 0x13 , 0x43 , 0x72 , 0x99 , 0xa0 , 0xbf};#elseunsigned int szOffset[] = {0x7 , 0xc-1 , 0x13-1 , 0x18 , 0x3a , 0x3f-1 , 0x45-1};#endifBOOL bRet = FALSE;HMODULE hMod = GetModuleHandle(_T("Kernel32.dll"));FARPROC pFunc_TlsSetValue = GetProcAddress(hMod , "TlsSetValue");//把hook位置被破坏的指令保存到m_szMyTransfer + szOffset[3]这个地址,中转函数会执行这部分指令int dwCodeLen = TransplantCode(pOriginAdr , m_szMyTransfer + szOffset[3]);//如果允许破坏的空间足够大if (dwCodeLen >= JMP_CODE_LEN){//保存hook地址m_pOrigin_Adr = pOriginAdr;//保存破坏的空间大小m_nOrigin_CodeLen = dwCodeLen;//申请空间,保存被破坏的指令字节m_pOldCode = new BYTE[dwCodeLen];memcpy(m_pOldCode , pOriginAdr , dwCodeLen);//修正shellcode中的各种偏移*(DWORD32*)(m_szMyTransfer + szOffset[0]) = m_dwTlsIndexForRegister;WriteCall((DWORD_PTR)(m_szMyTransfer + szOffset[1]) , (DWORD_PTR)pFunc_TlsSetValue);WriteCall((DWORD_PTR)(m_szMyTransfer + szOffset[2]) , (DWORD_PTR)pNewHook);// memcpy((LPVOID)(m_szMyTransfer + szOffset[3]) , (LPVOID)pOriginAdr , dwCodeLen);*(DWORD32*)(m_szMyTransfer + szOffset[4]) = m_dwTlsIndexForRegister;WriteCall((DWORD_PTR)(m_szMyTransfer + szOffset[5]) , (DWORD_PTR)pFunc_TlsSetValue);WriteJMP((DWORD_PTR)(m_szMyTransfer + szOffset[6]) , (DWORD_PTR)pOriginAdr + dwCodeLen);WriteJMP((DWORD_PTR)pOriginAdr , (DWORD_PTR)m_szMyTransfer);bRet = TRUE;}else{m_szMyTransfer = 0;m_pOrigin_Adr = 0;MessageBox(0 , _T("hook点异常,指令无法识别或含有跳转指令") , _T("hook失败") , MB_OK);}return bRet;}BOOL CHook::SetHook( void* pOriginAdr , void* pNewHook , void* pHookAfterCall ){//创建一块内存区域用于存放shellcodeDWORD dwOld;m_szMyTransfer = new BYTE[TRANSFER_FUNC_FOR_CALL_SIZE];memcpy(m_szMyTransfer , m_szTransferFunction_ForCall , TRANSFER_FUNC_FOR_CALL_SIZE);VirtualProtect(m_szMyTransfer , 100 , PAGE_EXECUTE_READWRITE , &dwOld);//shellcode中需要修正的位置保存成数组,方便编译#ifdef _WIN64unsigned int szOffset[] = {0x4 , 0x11 , 0x2d , 0x3c , 0x6c , 0x9b+4 , 0xc8+4 , 0xa8+4 , 0xcc+4 , 0xdb+4 , 0x10b+4 , 0x13a+4 , 0x142+4 , 0x169+4 , 0x170+4};#elseunsigned int szOffset[] = {0x5 , 0xa-1 , 0x14 , 0x19-1 , 0x20-1 , 0x26 , 0x48 , 0x2a , 0x4f , 0x54-1 , 0x5b-1 , 0x62 , 0x67-1 , 0x72 , 0x77-1};#endifBOOL bRet = FALSE;if (!pNewHook && !pHookAfterCall){return bRet;}HMODULE hMod = GetModuleHandle(_T("Kernel32.dll"));FARPROC pFunc_TlsSetValue = GetProcAddress(hMod , "TlsSetValue");FARPROC pFunc_TlsGetValue = GetProcAddress(hMod , "TlsGetValue");//用户回调函数分为函数执行前和函数执行后,如果某个回调函数设置为null,则替换为m_szRet这个直接c3返回的函数void* pBefore = pNewHook;void* pAfter = pHookAfterCall;if (!pBefore){pBefore = m_szRet;}if (!pAfter){pAfter = m_szRet;}//把hook位置被破坏的指令保存到m_szMyTransfer + szOffset[3]这个地址,中转函数会执行这部分指令int dwCodeLen = TransplantCode(pOriginAdr , m_szMyTransfer + szOffset[7]);//如果允许破坏的空间足够大if (dwCodeLen >= JMP_CODE_LEN){//保存hook地址m_pOrigin_Adr = pOriginAdr;//保存破坏的空间大小m_nOrigin_CodeLen = dwCodeLen;//申请空间,保存被破坏的指令字节m_pOldCode = new BYTE[dwCodeLen];memcpy(m_pOldCode , pOriginAdr , dwCodeLen);//修正shellcode中的各种偏移*(DWORD32*)(m_szMyTransfer + szOffset[0]) = m_dwTlsIndexForRetAdr;WriteCall((DWORD_PTR)(m_szMyTransfer + szOffset[1]) , (DWORD_PTR)pFunc_TlsSetValue);*(DWORD32*)(m_szMyTransfer + szOffset[2]) = m_dwTlsIndexForRegister;WriteCall((DWORD_PTR)(m_szMyTransfer + szOffset[3]) , (DWORD_PTR)pFunc_TlsSetValue);WriteCall((DWORD_PTR)(m_szMyTransfer + szOffset[4]) , (DWORD_PTR)pBefore);#ifdef _WIN64BYTE szTmp = *(m_szMyTransfer + szOffset[7]);WriteJMP((DWORD_PTR)m_szMyTransfer+szOffset[5] , (DWORD_PTR)m_szMyTransfer+szOffset[6]);*(m_szMyTransfer + szOffset[7]) = szTmp;#else *(DWORD32*)(m_szMyTransfer + szOffset[5]) = (DWORD)m_szMyTransfer+szOffset[6];#endif// memcpy((LPVOID)(m_szMyTransfer + szOffset[7]) , (LPVOID)pOriginAdr , dwCodeLen);WriteJMP((DWORD_PTR)m_szMyTransfer+szOffset[7]+dwCodeLen , (DWORD_PTR)(DWORD_PTR)pOriginAdr + dwCodeLen);*(DWORD32*)(m_szMyTransfer + szOffset[8]) = m_dwTlsIndexForRegister;WriteCall((DWORD_PTR)(m_szMyTransfer + szOffset[9]) , (DWORD_PTR)pFunc_TlsSetValue);WriteCall((DWORD_PTR)(m_szMyTransfer + szOffset[10]) , (DWORD_PTR)pAfter);*(DWORD32*)(m_szMyTransfer + szOffset[11]) = m_dwTlsIndexForRetAdr;WriteCall((DWORD_PTR)(m_szMyTransfer + szOffset[12]) , (DWORD_PTR)pFunc_TlsGetValue);*(DWORD32*)(m_szMyTransfer + szOffset[13]) = m_dwTlsIndexForRegister;WriteCall((DWORD_PTR)(m_szMyTransfer + szOffset[14]) , (DWORD_PTR)pFunc_TlsSetValue);WriteJMP((DWORD_PTR)pOriginAdr , (DWORD_PTR)m_szMyTransfer);bRet = TRUE;}else{m_szMyTransfer = 0;m_pOrigin_Adr = 0;MessageBox(0 , _T("hook点异常,指令无法识别或含有跳转指令") , _T("hook失败") , MB_OK);}return bRet;}int CHook::TransplantCode( void* pOriginAdr , BYTE* pDestAdr ){//初始化bea引擎DISASM MyDisasm;memset (&MyDisasm, 0, sizeof(DISASM));#if defined(_WIN64)MyDisasm.Archi = 64;#elseMyDisasm.Archi = 0;#endif//以hook点pOriginAdr开始识别指令MyDisasm.EIP = (UIntPtr)pOriginAdr;DWORD dwCodeLen = 0;while (1){//调用Disasm解析指令int nLen = Disasm(&MyDisasm);//无法识别就滚蛋if (nLen == UNKNOWN_OPCODE) break;//含有跳转也滚蛋if (MyDisasm.Instruction.BranchType == RetType)break;//记录识别的长度dwCodeLen += nLen;//迁移当前指令到中转函数的空间中memcpy(pDestAdr , (void*)MyDisasm.EIP, nLen);//这个判断目前似乎只有x64才会产生作用//用于识别类似于mov [eip+xxx],register这样的指令//即以eip为原点偏移的指令,jmp其实也是,不过跳转指令在上面已经被pass了if (nLen > 4 && MyDisasm.Instruction.AddrValue){//计算指令中的偏移数据DWORD32* pArg = (DWORD32*)(MyDisasm.EIP + nLen - 4);//如果确实是以eip为偏移的指令if (*pArg + nLen + MyDisasm.EIP == MyDisasm.Instruction.AddrValue){//计算迁移后的实际eip为原点的偏移数据DWORD32* pNewArg = (DWORD32*)(pDestAdr + nLen - 4);//修正偏移数据*pNewArg = MyDisasm.Instruction.AddrValue - nLen - (DWORD_PTR)pDestAdr;}}pDestAdr += nLen;MyDisasm.EIP  += nLen;//如果空间已经足够就中断if (dwCodeLen >= JMP_CODE_LEN){break;}};return dwCodeLen;}//写jmp的x64版本函数void CHook::WriteJMP_x64( DWORD_PTR dwFrom , DWORD_PTR dwTo ){DWORD_PTR dwAdr = dwFrom;DWORD dwOldP;VirtualProtect((LPVOID)dwAdr , 0x100 , PAGE_EXECUTE_READWRITE , &dwOldP);*(BYTE*)dwAdr = 0x68;dwAdr+=1;*(DWORD32*)dwAdr = DWORD32(dwTo & 0xffffffff);dwAdr+=4;*(DWORD32*)dwAdr = DWORD32(0x042444c7);dwAdr+=4;*(DWORD32*)dwAdr = DWORD32(dwTo >> 32);dwAdr+=4;*(BYTE*)dwAdr = 0xc3;/*push 地址的低32位mov dword ptr ss:[rsp+4],地址的高32位ret*///14 bytes}//写call的x64版本函数void CHook::WriteCall_x64( DWORD_PTR dwFrom , DWORD_PTR dwTo ){DWORD_PTR dwAdr = dwFrom;DWORD dwOldP;VirtualProtect((LPVOID)dwAdr , 0x100 , PAGE_EXECUTE_READWRITE , &dwOldP);*(BYTE*)dwAdr = 0xE8;dwAdr+=1;*(DWORD*)dwAdr = DWORD32(0);dwAdr+=4;*(DWORD32*)dwAdr = DWORD32(0x12240483);dwAdr+=4;*(BYTE*)dwAdr = 0x68;dwAdr+=1;*(DWORD32*)dwAdr = DWORD32(dwTo & 0xffffffff);dwAdr+=4;*(DWORD32*)dwAdr = DWORD32(0x042444c7);dwAdr+=4;*(DWORD32*)dwAdr = DWORD32(dwTo >> 32);dwAdr+=4;*(BYTE*)dwAdr = 0xc3;/*call @next   //e8 00 00 00 00@next:add dword ptr ss:[rsp],12push 地址的低32位mov dword ptr ss:[rsp+4],地址的高32位ret*///23 bytes}//移除hook的线程//严格来说,也许应该遍历所有线程,保证没有线程运行到hook位置和中转函数//然后冻结线程,再移除hook,这样才正规和安全//然而我不会DWORD WINAPI RemoveHook_Thread(LPVOID lpParam ){CHook *pHook = (CHook*)lpParam;//当GetRegOnHookPoint获取hook现场返回0时候,说明基本执行完毕了while (pHook->GetRegOnHookPoint()){Sleep(500);}//正式移除hookpHook->RemoveHook_unsafe();return 0;}BOOL CHook::RemoveHook(){if (TlsGetValue(m_dwTlsIndexForRegister)){CreateThread(0 , 0 , RemoveHook_Thread , this , 0 , 0);}else{RemoveHook_unsafe();}return TRUE;}BOOL CHook::RemoveHook_unsafe(){//恢复hook点memcpy((LPVOID)m_pOrigin_Adr , (LPVOID)m_pOldCode , m_nOrigin_CodeLen);//释放保存的指令delete[] m_pOldCode;//释放中转函数delete[] m_szMyTransfer;return TRUE;}


0 0
原创粉丝点击