InlineHook.h
#pragma once class CInlineHook { public: CInlineHook() {}; ~CInlineHook() {}; public: static BOOL hookUnhookWindowsHookEx(); static BOOL unhookUnhookWindowsHookEx(); static BOOL hookSetTimer(); static BOOL unhookSetTimer(); }; typedef BOOL(WINAPI *UNHOOKWINDOWSHOOKEX)(HHOOK); typedef HRESULT (WINAPI *SETTIMER)(QWORD,PVOID,DWORD*);
InlineHook.cpp
#include "stdafx.h" #include "InlineHook.h" #include "MyDll.h" #include <strsafe.h> BYTE bytOldCode1[5] = { 0 }; // 用于保存hook前原始code; BOOL bIsHook1 = FALSE; // 标识当前是否被HOOK; BOOL WINAPI newUnhookWindowsHookEx( _In_ HHOOK hhk ) { BOOL bRet = FALSE; if (hhk != g_MsgHook || hhk != g_KeybdHook || hhk != g_DbgHook) { return bRet; } OutputDebugString(L"newuUnhookWindowsHookEx invoked!"); CInlineHook::unhookUnhookWindowsHookEx(); // UNHOOK bRet = UnhookWindowsHookEx(hhk); CInlineHook::hookUnhookWindowsHookEx(); return bRet; } BYTE bytOldCode2[5] = { 0 }; // 用于保存hook前原始code; BOOL bIsHook2 = FALSE; // 标识当前是否被HOOK; UINT_PTR WINAPI newSetTimer( __in_opt HWND hWnd, __in UINT_PTR nIDEvent, __in UINT uElapse, __in_opt TIMERPROC lpTimerFunc ) { CString strDebug(_T("nIDEvent is ")); strDebug.AppendFormat(_T("%d"), nIDEvent); OutputDebugString(strDebug); BOOL bRet = FALSE; if (nIDEvent == 513 || nIDEvent == 514 || nIDEvent == 516 || nIDEvent == 3) return FALSE; TCHAR szWndText[MAXBYTE] = { 0 }; ::GetWindowText(hWnd, szWndText, MAXBYTE); if (_tcscmp(szWndText,_T("QQEdit")) == 0) { return FALSE; } OutputDebugString(_T("恢复 SetTimer")); CInlineHook::unhookSetTimer(); bRet = SetTimer(hWnd, nIDEvent, uElapse, lpTimerFunc); CInlineHook::hookSetTimer(); OutputDebugString(_T("Hook SetTimer")); return bRet; } BOOL CInlineHook::hookUnhookWindowsHookEx() { DWORD dwOffset = (DWORD)newUnhookWindowsHookEx - 5 - (DWORD)UnhookWindowsHookEx; DWORD dwOldProtect; _asm { LEA EDI, bytOldCode1; // 0xB8 0x70 0x10 00 00 MOV ESI, UnhookWindowsHookEx; CLD; MOVSB; MOVSD; } if (!bIsHook1) { VirtualProtect((LPVOID)UnhookWindowsHookEx, 0x100, PAGE_EXECUTE_READWRITE, &dwOldProtect); _asm{ PUSH EAX; PUSH EBX; MOV EAX, UnhookWindowsHookEx; MOV BYTE PTR[EAX], 0xE9; INC EAX; MOV EBX, dwOffset; MOV DWORD PTR[EAX], EBX; POP EBX; POP EAX; } bIsHook1 = TRUE; VirtualProtect((LPVOID)UnhookWindowsHookEx, 0x100, dwOldProtect, &dwOldProtect); } return TRUE; } BOOL CInlineHook::unhookUnhookWindowsHookEx() { DWORD dwOldProtect; if (bIsHook1) { VirtualProtect((LPVOID)UnhookWindowsHookEx, 0x100, PAGE_EXECUTE_READWRITE, &dwOldProtect); _asm { MOV EDI, UnhookWindowsHookEx; LEA ESI, bytOldCode1; CLD; MOVSB; MOVSD; } bIsHook1 = FALSE; VirtualProtect((LPVOID)UnhookWindowsHookEx, 0x100, dwOldProtect, &dwOldProtect); } return TRUE; } BOOL CInlineHook::hookSetTimer() { DWORD dwOffset = (DWORD)newSetTimer - 5 - (DWORD)SetTimer; DWORD dwOldProtect; __asm{ LEA EDI, bytOldCode2; MOV ESI, SetTimer; CLD; MOVSB; MOVSD; } //////////////////////////////////////////////////////////////////// ///////////////////////调试语句///////////////////////////////////// //////////////////////////////////////////////////////////////////// CString str(_T("bytOldCode2:")); str.AppendFormat(_T("0x%X,0x%X,0x%X,0x%X,0x%X"), bytOldCode2[0], bytOldCode2[1], bytOldCode2[2], bytOldCode2[3], bytOldCode2[4] ); OutputDebugString(str); if (!bIsHook2) { VirtualProtect((LPVOID)SetTimer, 0x100, PAGE_EXECUTE_READWRITE, &dwOldProtect); __asm{ MOV EAX, SetTimer; MOV BYTE PTR[EAX], 0xE9; INC EAX; MOV EBX, dwOffset; MOV[EAX], EBX; } bIsHook2 = TRUE; VirtualProtect((LPVOID)SetTimer, 0x100, dwOldProtect, &dwOldProtect); } return TRUE; } BOOL CInlineHook::unhookSetTimer() { DWORD dwOldProtect; if (bIsHook2) { VirtualProtect(SetTimer, 0x100, PAGE_EXECUTE_READWRITE, &dwOldProtect); __asm{ LEA ESI, bytOldCode2; MOV EDI, SetTimer; CLD; MOVSB; MOVSD; } bIsHook2 = FALSE; VirtualProtect(SetTimer, 0x100, dwOldProtect, &dwOldProtect); } return TRUE; }