C++ Hook注入DLL 完整例子

Posted dounine

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ Hook注入DLL 完整例子相关的知识,希望对你有一定的参考价值。

包含要注入的Demo与dll,与注入的程序。

要注入的Demo.exe程序代码

#include <iostream>
#include <Windows.h>
using namespace std;
int showAge(int age) 
    int a = 0;
    cout << a << age << endl;
    return age;


int main() 
    SetConsoleTitle("Demo");
    cout << "Hello, World!" << endl;
    showAge(18);
    cin.get();
    return 0;

注入程序的Dll

#include <Windows.h>
#include <iostream>
#include "tchar.h"
#include "tlhelp32.h"

BOOL getProcessAddr(DWORD dwPID, DWORD &baseAddr);

DWORD retAddr;
char oldCode[5] = 0;
DWORD hookAddr;

/**
 * hook的一个exe中的方法
 * void showAge(int age)
 *   std::cout << age << endl;
 * 
 */
void hookPrint(int age)
    std::cout << "hook age is : " << (int)age << std::endl;


void _declspec(naked) print() 
    __asm 
        push ebp
        mov ebp,esp

        mov eax,dword ptr ss:[ebp+8]
        push eax
        call hookPrint
        add esp,0x4

        mov esp,ebp
        pop ebp
        jmp retAddr
    


void hook(DWORD offset) 
    DWORD baseAddr;
    DWORD pid = GetCurrentProcessId();
    getProcessAddr(pid, baseAddr);
    hookAddr = baseAddr + offset;
    /**
     * 不需要权限
     */
    memcpy((LPVOID) oldCode, (LPVOID) hookAddr, 5);
    retAddr = hookAddr + 5;
    char jmpCode[5] = 0;
    jmpCode[0] = 0xE9;//或者0xE8
    *(DWORD *) &jmpCode[1] = (DWORD) print - hookAddr - 5;
    /**
     * 不能替换成memcpy使用
     */
    if (WriteProcessMemory(GetCurrentProcess(), (LPVOID) hookAddr, (LPVOID) jmpCode, 5, nullptr) == 0) 
        std::cout << "hook fail" << std::endl;
     else 
        std::cout << "hook success" << std::endl;
    


void unhook() 
    std::cout << "unhook" << std::endl;
    if (WriteProcessMemory(GetCurrentProcess(), (LPVOID) hookAddr, (LPVOID) oldCode, 5, nullptr) == 0) 
        std::cout << "unhook fail" << std::endl;
     else 
        std::cout << "unhook success" << std::endl;
    


BOOL getProcessAddr(DWORD dwPID, DWORD &baseAddr) 
    HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
    MODULEENTRY32 me32;
    hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
    me32.dwSize = sizeof(MODULEENTRY32);
    if (!Module32First(hModuleSnap, &me32)) 
        CloseHandle(hModuleSnap);
        return FALSE;
    
    baseAddr = (DWORD) me32.modBaseAddr;
    CloseHandle(hModuleSnap);
    return TRUE;


BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) 
    switch (ul_reason_for_call) 
        case DLL_PROCESS_ATTACH:
            hook(0x1717);//0x1717是使用x32dbg查到call的位置偏移
            break;
        case DLL_PROCESS_DETACH:
            unhook();
            break;
        case DLL_THREAD_ATTACH:
            break;
        case DLL_THREAD_DETACH:
            break;
    
    return TRUE;


注入Dll的程序

#include <iostream>
#include <Windows.h>
#include "tchar.h"
#include "WindowUtil.h"

DWORD findProcessPid(LPCTSTR name) 
    HANDLE hProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (!hProcess) 
        return FALSE;
    
    PROCESSENTRY32 info;
    info.dwSize = sizeof(info);
    if (!Process32First(hProcess, &info)) 
        return FALSE;
    
    while (true) 
        const LPTSTR fName = info.szExeFile;
        if (_tcscmp(fName, name) == 0) 
            CloseHandle(hProcess);
            return info.th32ProcessID;
        
        if (!Process32Next(hProcess, &info)) 
            CloseHandle(hProcess);
            return FALSE;
        
    


BOOL getProcessAddr(DWORD pid, LPCTSTR moduleName, DWORD &baseAddr) 
    HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
    MODULEENTRY32 me32;
    hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
    me32.dwSize = sizeof(MODULEENTRY32);
    if (!Module32First(hModuleSnap, &me32)) 
        CloseHandle(hModuleSnap);
        return FALSE;
    
    do 
        if (_tcscmp(me32.szModule, moduleName) == 0 || _tcscmp(me32.szExePath, moduleName) == 0) 
            break;
        
     while (Module32Next(hModuleSnap, &me32));
    baseAddr = (DWORD) me32.modBaseAddr;
    CloseHandle(hModuleSnap);
    return TRUE;


void inject(LPCTSTR name, LPCTSTR dllPath) 
    DWORD pid = findProcessPid(name);
    HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    unsigned int size = strlen(dllPath);
    LPVOID dllPathAddr = VirtualAllocEx(handle, nullptr, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    WriteProcessMemory(handle, dllPathAddr, dllPath, size, nullptr);
    HANDLE remoteHandle = CreateRemoteThread(handle, nullptr, NULL, (PTHREAD_START_ROUTINE) LoadLibraryA, dllPathAddr,
                                             NULL, nullptr);
    WaitForSingleObject(remoteHandle, INFINITE);
    VirtualFreeEx(handle, dllPathAddr, size, MEM_DECOMMIT);
    CloseHandle(remoteHandle);
    CloseHandle(handle);


void unject(LPCTSTR name, LPCTSTR dllPath) 
    DWORD pid = findProcessPid(name);
    DWORD dllPathAddr;
    getProcessAddr(pid, dllPath, dllPathAddr);
    std::cout << std::hex << dllPathAddr << std::endl;
    HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    HANDLE remoteHandle = CreateRemoteThread(handle, nullptr, NULL, (PTHREAD_START_ROUTINE) FreeLibrary,
                                             (LPVOID) dllPathAddr,
                                             NULL, nullptr);
    WaitForSingleObject(remoteHandle, INFINITE);
    CloseHandle(remoteHandle);
    CloseHandle(handle);


int main() 
    LPCTSTR name = _T("Demo.exe");
    LPCTSTR dllPath = _T("C:\\\\Users\\\\Administrator\\\\CLionProjects\\\\Dll2\\\\cmake-build-release\\\\Dll2.dll");
    inject(name, dllPath);
    std::cin.get();//输入任意字符回车即可卸载Dll
    unject(name, dllPath);
    return 0;

以上是关于C++ Hook注入DLL 完整例子的主要内容,如果未能解决你的问题,请参考以下文章

C++ Hook注入DLL 完整例子

VC注入dll后,如何用代码实现inline hook?

C++ hook 问题

Windows Dll InjectionProcess InjectionAPI Hook

DLL注入之SetWindowsHook

防止来自Dll C ++的Dll注入