zoukankan      html  css  js  c++  java
  • API HOOK库

    API HOOK库

    API HOOK有两种做法,一种是SetWindowHookEx,简单易用,但如果做其它的HOOK,如HOOK OpenProcess,就需要修改内存地址了,内存地址可以通过WriteProcessMemory来修改,先将调用函数的地址改成自己的(jmp到自己的函数),然后需要时,再改回来。

     View Code

    #pragma once

    #ifdef _M_IX86
    template <typename T>
    class Hooker
    {
    protected:
    static DWORD HookFunction(LPCWSTR lpModule, LPCSTR lpFuncName, PROC lpFunction)
    {
    DWORD dwAddr = (DWORD) GetProcAddress(GetModuleHandle(lpModule), lpFuncName);
    BYTE jmp [] =
    {
    0xe9, //jmp
    0x00, 0x00, 0x00, 0x00, //address
    0xc3 //retn
    };

    ReadProcessMemory(GetCurrentProcess(), (LPVOID) dwAddr, MemoryAddress(), 6, 0);

    DWORD dwCalc = ((DWORD) lpFunction - dwAddr - 5); //((to)-(from)-5)

    memcpy(&jmp[1], &dwCalc, 4); //build the jmp

    WriteProcessMemory(GetCurrentProcess(), (LPVOID) dwAddr, jmp, 6, 0);

    return dwAddr;
    }

    static BOOL UnHookFunction(LPCWSTR lpModule, LPCSTR lpFuncName)
    {
    DWORD dwAddr = (DWORD) GetProcAddress(GetModuleHandle(lpModule), lpFuncName);

    if (WriteProcessMemory(GetCurrentProcess(), (LPVOID) dwAddr, MemoryAddress(), 6, 0))
    return TRUE;

    return FALSE;
    }

    static BYTE* MemoryAddress()
    {
    static BYTE backup[6];
    return backup;
    }
    };
    #elif _M_AMD64
    template <typename T>
    class Hooker
    {
    protected:
    static UINT64 HookFunction(LPCWSTR lpModule, LPCSTR lpFuncName, LPVOID lpFunction)
    {
    UINT64 dwAddr = (UINT64) GetProcAddress(GetModuleHandle(lpModule), lpFuncName);
    BYTE jmp [] =
    {
    0x48, 0xb8, //jmp
    0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, //address
    0x50, 0xc3 //retn
    };

    ReadProcessMemory(GetCurrentProcess(), (LPVOID) dwAddr, MemoryAddress(), 12, 0);

    UINT64 dwCalc = (UINT64) lpFunction;

    memcpy(&jmp[2], &dwCalc, 8); //build the jmp

    WriteProcessMemory(GetCurrentProcess(), (LPVOID) dwAddr, jmp, 12, nullptr);

    return dwAddr;
    }

    static BOOL UnHookFunction(LPCWSTR lpModule, LPCSTR lpFuncName)
    {
    UINT64 dwAddr = (UINT64) GetProcAddress(GetModuleHandle(lpModule), lpFuncName);

    if (WriteProcessMemory(GetCurrentProcess(), (LPVOID) dwAddr, MemoryAddress(), 12, 0))
    return TRUE;

    return FALSE;
    }

    static BYTE* MemoryAddress()
    {
    static BYTE backup[12];
    return backup;
    }
    };
    #endif

    值得注意的是,64位和32位的注入字节有些许不同。

    由于目前Visual Studio 2013 Preview实现的C++类中,还是不允许有非int静态变量,但却允许函数中有静态变量,所以我将目标指针数据备份到静态成员中:

        static BYTE* MemoryAddress()
        {
            static BYTE backup[6];
            return backup;
        }

    然后,在使用时,从Hooker继承一个类即可:

     View Code

    class MessageBoxHooker : Hooker<MessageBoxHooker>
    {
    public:
    static void BeginHook()
    {
    HookFunction(L"user32.dll", "MessageBoxW", (PROC) MyMessageBoxW);
    }
    static void StopHook()
    {
    UnHookFunction(L"user32.dll", "MessageBoxW");
    }
    private:
    static int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType)
    {
    StopHook();
    int x = MessageBox(hWnd, L"hooked", lpCaption, uType);
    BeginHook();
    return x;
    }
    };

    要开启Hook,只需调用:

    MessageBoxHooker::BeginHook();

    这个API HOOK库我使了一个模板,之所以用模板是因为C++函数指针不包含实例的指针。这种使用模板来解决C++指针的缺点的做法很常见,ATL也是这样实现的。

    本文提供的代码可以随意引用,但请充分测试后再部署,出问题本人不承担任何责任,欢迎有任何建议和补充~

     
     
  • 相关阅读:
    WebStorm2019
    微信公众号互阅平台-真实提高阅读量-「作者加鸡腿」
    macos 致命错误: 在类路径或引导类路径中找不到程序包 java.lang
    IDEA2020激活码 / IDEA 2020.1.2激活破解教程
    Linux命令大全
    2019年终总结-2020展望「定版」
    SpringBoot如何切换Redis默认库
    uniapp增加百度统计代码(h5)
    修改MyEclipse/Eclipse左侧文字大小(MacOS/Windows)
    Invalid connection string format, a valid format is: "host:port:sid"
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3306043.html
Copyright © 2011-2022 走看看