API HOOK

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;
}
原文地址:https://www.cnblogs.com/Lthis/p/4197207.html