Hook 技术通常被称为钩子技术,Hook技术是Windows系统用于替代中断机制的具体实现,钩子的含义就是在程序还没有调用系统函数之前,钩子捕获调用消息并获得控制权,在执行系统调用之前执行自身程序,简单来说就是函数劫持,本笔记将具体介绍应用层Hook的实现机制。

X86 手动完成 HOOK

首先我们来实现一个小功能,这里有一个小程序,当我们点击弹窗时会自动的弹出一个MessageBox提示,我们的目标是通过注入DLL的方式Hook来实现去除这个弹窗,先来看一下Hook的思路:

1.调用 GetModuleHandle 来获取到模块的基址(user32.dll)
2.调用 GetProcAddress 获取到MessageBoxA弹窗的基址
3.调用 VirtualProtect 来修改MsgBox前5个字节内存属性
4.计算 Dest - MsgBox - 5 重定位跳转地址,并Jmp跳转
5.计算 Dest + Offset + 5 = MsgBox +5 跳转回来的位置

1.首先我们载入这个程序,输入MessageBoxA 找到我们需要Hook的地方,如下我们只需要在函数开头写入【jmp xxxx】该指令占用5字节,我们还需要记下被覆盖的这三条指令,在我们自己的中转函数中补齐它否则会导致堆栈不平衡。

我们还需要计算出程序的返回地址,只需要用【772A1f8A - 772A1F70 = 1A】返回地址就是基址加上1A

直接附上代码:

#include <Windows.h>
#include <stdio.h>DWORD jump = 0;__declspec(naked) void Transfer(){__asm{mov edi, edipush ebpmov ebp, espmov ebx, jumpjmp ebx}
}bool APIENTRY DllMain(HANDLE handle, DWORD dword, LPVOID lpvoid)
{HMODULE hwnd = GetModuleHandle(TEXT("user32.dll"));DWORD base = (DWORD)GetProcAddress(hwnd, "MessageBoxA");DWORD oldProtect = 0;if (VirtualProtect((LPVOID)base, 5, PAGE_EXECUTE_READWRITE, &oldProtect)){DWORD value = (DWORD)Transfer - base - 5;jump = base + 0x1a;__asm{mov eax, basemov byte ptr[eax], 0xe9inc eaxmov ebx, valuemov dword ptr[eax], ebx}VirtualProtect((LPVOID)base, 5, oldProtect, &oldProtect);}return true;
}

编译上方代码,然后使用注入工具注入到程序中,当我们点击弹窗时,已经Hook成功。

Hook改标题: 通常情况下,程序设置标题会调用 SetWindowTextA 这个API函数,我们可以拦截这个函数,并传进不同的窗口名称,从而实现修改指定窗口的标题,其实先代码只是在上面代码的基础上稍微改一下就能实现效果。

#include <Windows.h>
#include <stdio.h>DWORD jump = 0;__declspec(naked) bool _stdcall Transfer(HWND hwnd, LPCSTR lpString){__asm{mov edi, edipush ebpmov ebp, espmov ebx, jumpjmp ebx}
}
bool __stdcall MySetWindowTextA(HWND hwnd, LPCSTR lpString){char * lpText = "LyShark 破解版";return Transfer(hwnd, lpText);
}bool APIENTRY DllMain(HANDLE handle, DWORD dword, LPVOID lpvoid)
{HMODULE hwnd = GetModuleHandle(TEXT("user32.dll"));DWORD base = (DWORD)GetProcAddress(hwnd, "SetWindowTextA");DWORD oldProtect = 0;if (VirtualProtect((LPVOID)base, 5, PAGE_EXECUTE_READWRITE, &oldProtect)){DWORD value = (DWORD)MySetWindowTextA - base - 5;jump = base + 5;__asm{mov eax, basemov byte ptr[eax], 0xe9inc eaxmov ebx, valuemov dword ptr[eax], ebx}VirtualProtect((LPVOID)base, 5, oldProtect, &oldProtect);}return true;
}

X64 手动完成 Hook

64位与32位系统之间无论从寻址方式,还是语法规则都与x86架构有着本质的不同,所以上面的使用技巧只适用于32位程序,注入32位进程使用,下面的内容则是64位下手动完成hook挂钩的一些骚操作,由于64位编译器无法直接内嵌汇编代码,导致我们只能调用C库函数来实现Hook的中转。

简单的HookAPI例子:

#include <stdio.h>
#include <Windows.h>#define HOOK_LEN 0xC
void HookMessageBox();
BYTE Ori_Code[HOOK_LEN] = { 0x00 };
BYTE HookCode[HOOK_LEN] = { 0x48, 0xB8, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0xFF, 0xE0 };
/*
MOV RAX, 0x9090909090909090
JMP RAX
*/
static int (WINAPI *OldMessageBoxW)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) = MessageBoxW;
int WINAPI MyMessageBoxW(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
{memcpy(OldMessageBoxW, &Ori_Code, sizeof(HookCode));                       // 恢复hook原始代码int ret = OldMessageBoxW(hWnd, TEXT("hello lyshark"), lpCaption, uType);   // 调用原函数HookMessageBox();                                                          // 继续hookreturn ret;
}
VOID HookMessageBox()
{DWORD OldProtect;if (VirtualProtect(OldMessageBoxW, HOOK_LEN, PAGE_EXECUTE_READWRITE, &OldProtect)){memcpy(Ori_Code, OldMessageBoxW, HOOK_LEN);         // 拷贝原始机器码指令*(PINT64)(HookCode + 2) = (INT64)&MyMessageBoxW;    // 填充90为指定跳转地址}memcpy(OldMessageBoxW, &HookCode, sizeof(HookCode));    // 拷贝Hook机器指令
}
int main()
{HookMessageBox();MessageBoxW(NULL, TEXT("hello"), TEXT("标题"), MB_OK);return 0;
}

应用于DLL注入的Hook

#include <stdio.h>
#include <Windows.h>BYTE OldCode[12] = { 0x00 };
BYTE HookCode[12] = { 0x48, 0xB8, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0xFF, 0xE0 };
DWORD_PTR base;int WINAPI MyMessageBoxW(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
{return 1;
}bool APIENTRY DllMain(HANDLE handle, DWORD dword, LPVOID lpvoid)
{HMODULE hwnd = GetModuleHandle(TEXT("user32.dll"));DWORD_PTR base = (DWORD_PTR)GetProcAddress(hwnd, "MessageBoxW");DWORD OldProtect;if (VirtualProtect((LPVOID)base, 12, PAGE_EXECUTE_READWRITE, &OldProtect)){memcpy(OldCode, (LPVOID)base, 12);                  // 拷贝原始机器码指令*(PINT64)(HookCode + 2) = (INT64)&MyMessageBoxW;    // 填充90为指定跳转地址}memcpy((LPVOID)base, &HookCode, sizeof(HookCode));      // 拷贝Hook机器指令return true;
}

完善这个Hook代码: 经过本人的不断尝试,最终写出了完整的注入代码,不容易啊,苍天鸭!

// By: lyshark
// http://blib.cn
#include <stdio.h>
#include <Windows.h>BYTE OldCode[12] = { 0x00 };
BYTE HookCode[12] = { 0x48, 0xB8, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0xFF, 0xE0 };void HookFunction64(LPCWSTR lpModule, LPCSTR lpFuncName, LPVOID lpFunction)
{DWORD_PTR FuncAddress = (UINT64)GetProcAddress(GetModuleHandle(lpModule), lpFuncName);DWORD OldProtect = 0;if (VirtualProtect((LPVOID)FuncAddress, 12, PAGE_EXECUTE_READWRITE, &OldProtect)){memcpy(OldCode, (LPVOID)FuncAddress, 12);                   // 拷贝原始机器码指令*(PINT64)(HookCode + 2) = (UINT64)lpFunction;               // 填充90为指定跳转地址}memcpy((LPVOID)FuncAddress, &HookCode, sizeof(HookCode));       // 拷贝Hook机器指令VirtualProtect((LPVOID)FuncAddress, 12, OldProtect, &OldProtect);
}
void UnHookFunction64(LPCWSTR lpModule, LPCSTR lpFuncName)
{DWORD OldProtect = 0;UINT64 FuncAddress = (UINT64)GetProcAddress(GetModuleHandle(lpModule), lpFuncName);if (VirtualProtect((LPVOID)FuncAddress, 12, PAGE_EXECUTE_READWRITE, &OldProtect)){memcpy((LPVOID)FuncAddress, OldCode, sizeof(OldCode));}VirtualProtect((LPVOID)FuncAddress, 12, OldProtect, &OldProtect);
}int WINAPI MyMessageBoxW(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
{UnHookFunction64(L"user32.dll", "MessageBoxW");int ret = MessageBoxW(0, L"hello lyshark", lpCaption, uType);HookFunction64(L"user32.dll", "MessageBoxW", (PROC)MyMessageBoxW);return ret;
}
bool APIENTRY DllMain(HANDLE handle, DWORD dword, LPVOID lpvoid)
{switch (dword){case DLL_PROCESS_ATTACH:HookFunction64(L"user32.dll", "MessageBoxW", (PROC)MyMessageBoxW);break;case DLL_PROCESS_DETACH:case DLL_THREAD_DETACH:break;}return true;
}

Detours 库的使用(32位)

前面的内容我们是自己实现的Hook代码,在生产环境中一般都会使用Hook库,常用的Hook库有免费开源的MinHook和商业的Detours Hook 这里我就默认使用Detours来测试32位下的Hook挂钩,Detours的64位是商业版,这里我们只用他的32位。

Detours 库在4.x开始就已经基于MIT许可开源了,GitHub地址: https://github.com/Microsoft/Detours

首先在Git上下载,下载好以后直接解压到指定磁盘,然后使用VS的命令行工具并进入Detours目录,直接数据命令 nmak 等待编译完成,然后配置VS项目,在【调试】->【属性】->【VC目录】将include和lib目录包含到项目中。

修改弹窗: 实现Hook MsgBox弹窗,该库的原理与我们上面手动实现的方式是相同的,不过它这个库更加的健壮。

#include <Windows.h>
#include <detours.h>
#pragma comment(lib,"detours.lib")static int(WINAPI *OldMessageBoxA)(HWND, LPCSTR, LPCSTR, UINT) = MessageBoxA;int WINAPI MyMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{return OldMessageBoxA(hWnd, TEXT("hello lyshark"), lpCaption, uType);
}bool APIENTRY DllMain(HANDLE handle, DWORD dword, LPVOID lpvoid)
{int Error = DetourTransactionBegin();if (Error == NO_ERROR){DetourUpdateThread(GetCurrentThread());                 // 执行线程准备DetourAttach(&(PVOID&)OldMessageBoxA, MyMessageBoxA);   // 挂钩DetourTransactionCommit();}return true;
}

简单实现修改标题: 修改窗体标题,也可以使用这个库,代码非常简洁,如下:

#include <Windows.h>
#include <detours.h>
#include <stdio.h>
#pragma comment(lib,"detours.lib")static BOOL(WINAPI* Old_SetWindowTextA)(HWND hWnd, LPCSTR lpString) = SetWindowTextA;BOOL WINAPI MySetWindowTextA(HWND hWnd, LPCSTR lpString){return Old_SetWindowTextA(hWnd, "已破解");
}bool APIENTRY DllMain(HANDLE handle, DWORD dword, LPVOID lpvoid)
{int Error = DetourTransactionBegin(); if (Error == NO_ERROR){DetourUpdateThread(GetCurrentThread());DetourAttach(&(PVOID&)Old_SetWindowTextA, MySetWindowTextA);DetourTransactionCommit();}return true;
}

实现拦截文件创建: 文件的创建离不开CreateFileA函数,我们可以Hook这个函数,来拦截程序创建文件,此方法可用于对抗恶意代码,一些杀软也会通过Hook的方式监控文件的创建。

#include <Windows.h>
#include <detours.h>
#include <stdio.h>
#pragma comment(lib,"detours.lib")static HANDLE(WINAPI* Old_CreateFileA)(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) = CreateFileA;HANDLE WINAPI MyCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess,DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,HANDLE hTemplateFile)
{char *temp = "c://test.txt";if (strcmp(lpFileName, temp)){MessageBoxA(0, TEXT("拦截到创建文件请求"), 0, 0);lpFileName = "";return Old_CreateFileA(lpFileName, dwDesiredAccess,dwShareMode, lpSecurityAttributes,dwCreationDisposition, dwFlagsAndAttributes,hTemplateFile);}return Old_CreateFileA(lpFileName, dwDesiredAccess,dwShareMode, lpSecurityAttributes,dwCreationDisposition, dwFlagsAndAttributes,hTemplateFile);
}
bool APIENTRY DllMain(HANDLE handle, DWORD dword, LPVOID lpvoid)
{int Error = DetourTransactionBegin();if (Error == NO_ERROR){DetourUpdateThread(GetCurrentThread());DetourAttach(&(PVOID&)Old_CreateFileA, MyCreateFileA);DetourTransactionCommit();}return true;
}

实现Hook多个API:

#include <Windows.h>
#include <detours.h>
#include <stdio.h>
#pragma comment(lib,"detours.lib")static BOOL(WINAPI* Old_SetWindowTextA)(HWND hWnd, LPCSTR lpString) = SetWindowTextA;
static int(WINAPI* Old_MessageBoxA)(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)=MessageBoxA;BOOL WINAPI MySetWindowTextA(HWND hWnd, LPCSTR lpString){return Old_SetWindowTextA(hWnd, "已破解");
}
int WINAPI MyMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{return Old_MessageBoxA(hWnd, TEXT("弹窗已被重定向"), lpCaption, uType);
}
bool APIENTRY DllMain(HANDLE handle, DWORD dword, LPVOID lpvoid)
{int Error = DetourTransactionBegin();if (Error == NO_ERROR){DetourUpdateThread(GetCurrentThread());DetourAttach(&(PVOID&)Old_SetWindowTextA, MySetWindowTextA);DetourAttach(&(PVOID&)Old_MessageBoxA, MyMessageBoxA);DetourTransactionCommit();}return true;
}

获取程序OEP:

#include <Windows.h>
#include <detours.h>
#pragma comment(lib,"detours.lib")bool APIENTRY DllMain(HANDLE handle, DWORD dword, LPVOID lpvoid)
{DWORD ep = (DWORD)DetourGetEntryPoint(GetModuleHandle(0));char str[10];itoa(ep, str, 10);MessageBoxA(0, str, 0, 0);return true;
}

拦截DLL注入: 当本DLL被加载后,我们就无法向程序中注入DLL了,起到了简单保护进程的目的。

#include <Windows.h>
#include <detours.h>
#include <stdio.h>
#pragma comment(lib,"detours.lib")static HMODULE(WINAPI* Old_LoadLibraryA)(LPCSTR lpFileName) = LoadLibraryA;
static FARPROC(WINAPI* Old_GetProcAddress)(HMODULE hModule, LPCSTR lpProcName) = GetProcAddress;HMODULE WINAPI MyLoadLibraryA(LPCSTR lpFileName){return Old_LoadLibraryA("");
}
FARPROC WINAPI MyGetProcAddress(HMODULE hModule, LPCSTR lpProcName){return Old_GetProcAddress(0, "");
}
bool APIENTRY DllMain(HANDLE handle, DWORD dword, LPVOID lpvoid)
{int Error = DetourTransactionBegin();if (Error == NO_ERROR){DetourUpdateThread(GetCurrentThread());DetourAttach(&(PVOID&)Old_LoadLibraryA, MyLoadLibraryA);DetourAttach(&(PVOID&)Old_GetProcAddress, MyGetProcAddress);DetourTransactionCommit();}return true;
}

自定义Hook函数: 有时候我们需要自定义Hook对象,这时候我们就可以使用本方法,直接在最后写上我们需要Hook的地址即可。

#include <Windows.h>
#include <detours.h>
#pragma comment(lib,"detours.lib")static int(WINAPI* Old_MessageBoxA)(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) = (int(WINAPI *)(HWND, LPCSTR, LPCSTR, UINT))0x755A1F70;int WINAPI MyMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{return Old_MessageBoxA(hWnd, lpText, lpCaption, uType);
}bool APIENTRY DllMain(HANDLE handle, DWORD dword, LPVOID lpvoid)
{int Error = DetourTransactionBegin();if (Error == NO_ERROR){DetourUpdateThread(GetCurrentThread());DetourAttach(&(LPVOID&)Old_MessageBoxA, MyMessageBoxA);DetourTransactionCommit();}return true;
}

MinHook 库的使用(64位)

由于Detours hook库的X64版本是商业版无法直接使用,想要X64挂钩这里推荐使用MinHook,该Hook库是完全开源免费的,使用起来也非常的简单。

MinHook的GitHub地址:https://github.com/TsudaKageyu/minhook

首先在Git上下载,下载好以后直接解压到指定磁盘,然后会看到一下目录结构,选择对应的版本,进行编译即可。

编译好后,会生成以下文件,拷贝这两个文件,然后配合头文件使用即可。

MinHook入门: 同样是Hook MessageBox 用库就这么简单,自己写很麻烦!

#include <Windows.h>
#include <MinHook.h>
#pragma comment(lib,"libMinHook.x64.lib")typedef int (WINAPI *MESSAGEBOXW)(HWND, LPCWSTR, LPCWSTR, UINT);
MESSAGEBOXW fpMessageBoxW = NULL;int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType)
{return fpMessageBoxW(hWnd, L"hello lyshark", lpCaption, uType);
}
bool APIENTRY DllMain(HANDLE handle, DWORD dword, LPVOID lpvoid)
{switch (dword){case DLL_PROCESS_ATTACH:MH_Initialize();MH_CreateHook(&MessageBoxW, &MyMessageBoxW, reinterpret_cast<void**>(&fpMessageBoxW));MH_EnableHook(&MessageBoxW);break;case DLL_PROCESS_DETACH:MH_DisableHook(&MessageBoxW);MH_Uninitialize();break;}return true;
}

监控系统进程创建: 将下方DLL注入到explorer.exe进程中,即可监控系统的进程创建,在其中可以做查杀检测等,即可实现简单的主动防御。

#include <Windows.h>
#include <stdio.h>
#include <MinHook.h>
#pragma comment(lib,"libMinHook.x64.lib")typedef int (WINAPI *CREATEPROCESSW)(LPCWSTR, LPWSTR, LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION);
CREATEPROCESSW pfnCreateProcessW = NULL;int WINAPI MyCreateProcessW( LPCWSTR lpApplicationName,LPWSTR lpCommandLine,LPSECURITY_ATTRIBUTES lpProcessAttributes,LPSECURITY_ATTRIBUTES lpThreadAttributes,BOOL bInheritHandles,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCWSTR lpCurrentDirectory,LPSTARTUPINFOW lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation)
{int nRetn = pfnCreateProcessW(lpApplicationName,lpCommandLine,lpProcessAttributes,lpThreadAttributes,bInheritHandles,dwCreationFlags,lpEnvironment,lpCurrentDirectory,lpStartupInfo,lpProcessInformation);MessageBoxW(0, lpApplicationName, 0, 0);return nRetn;
}BOOL APIENTRY DllMain(HMODULE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved)
{if (MH_Initialize() == MH_OK){OutputDebugStringW(L"MH_Initialize success");}if (MH_CreateHook(&CreateProcessW, &MyCreateProcessW, reinterpret_cast<void **>(&pfnCreateProcessW)) == MH_OK){OutputDebugStringW(L"MH_CreateHook success");}if (MH_EnableHook(&CreateProcessW) == MH_OK){OutputDebugStringW(L"MH_Initialize success");}return TRUE;
}

实现禁止结束进程: 通过将DLL注入到系统的任务管理器中,实现禁止QQ进程被强制结束。

#include <Windows.h>
#include <stdio.h>
#include <MinHook.h>
#pragma comment(lib,"libMinHook.x64.lib")typedef HANDLE(WINAPI *OPENPROCESS)(DWORD, BOOL, DWORD);
OPENPROCESS pfnOpenProcess = NULL;HANDLE WINAPI MyOpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
{HWND myhwnd = 0;myhwnd = FindWindowW(L"TXGuiFoundation", L"QQ");if (myhwnd != NULL){HANDLE Retn = pfnOpenProcess(dwDesiredAccess, bInheritHandle, 0);return Retn;}HANDLE Retn = pfnOpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);return Retn;
}
BOOL APIENTRY DllMain(HMODULE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved)
{MH_Initialize();MH_CreateHook(&OpenProcess, &MyOpenProcess, reinterpret_cast<void **>(&pfnOpenProcess));MH_EnableHook(&OpenProcess);return TRUE;
}

上方代码需要注意:任务管理器终止进程其实是调用了TerminateProcess函数来执行强杀进程的,正常情况下应该hook该函数,但此处我们Hook了OpenProcess这个打开进程的API,这是因为在我们结束进程时,系统会先打开进程来获取到进程句柄,然后才会调用TerminateProcess并传递句柄来强制杀掉进程,我们只需要让打开进程失效,此时TerminateProcess函数将得不到正确的句柄,从而无法完成结束进程。

32/64 Min Hook (更多案例)

Hook 实现修改弹窗: 实现Hook MsgBox弹窗,该库的原理与我们上面手动实现的方式是相同的.

#include <Windows.h>
#include <MinHook.h>#pragma comment(lib,"libMinHook.x86.lib")typedef int (WINAPI *OldMessageBox)(HWND, LPCSTR, LPCSTR, UINT);OldMessageBox fpMessageBoxA = NULL;int WINAPI MyMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{int ret = fpMessageBoxA(hWnd, "Hook Inject", lpCaption, uType);return ret;
}void SetHook()
{if (MH_Initialize() == MB_OK){MH_CreateHook(&MessageBoxA, &MyMessageBoxA, reinterpret_cast<void**>(&fpMessageBoxA));MH_EnableHook(&MessageBoxA);}
}void UnHook()
{if (MH_DisableHook(&MessageBoxA) == MB_OK){MH_Uninitialize();}
}BOOL APIENTRY DllMain(HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:SetHook();break;case DLL_PROCESS_DETACH:UnHook();break;}return TRUE;
}

Hook 实现修改标题:

#include <Windows.h>
#include <MinHook.h>
#pragma comment(lib,"libMinHook.x86.lib")typedef BOOL (WINAPI *OldSetWindowTextA)(HWND, LPCSTR);OldSetWindowTextA fpSetWindowTextA = NULL;BOOL WINAPI MySetWindowTextA(HWND hWnd, LPCSTR lpString)
{BOOL ret = fpSetWindowTextA(hWnd, "破解版本");return ret;
}void SetHook()
{if (MH_Initialize() == MB_OK){MH_CreateHook(&SetWindowTextA, &MySetWindowTextA, reinterpret_cast<void**>(&fpSetWindowTextA));MH_EnableHook(&SetWindowTextA);}
}void UnHook()
{if (MH_DisableHook(&SetWindowTextA) == MB_OK){MH_Uninitialize();}
}BOOL APIENTRY DllMain(HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:SetHook();break;case DLL_PROCESS_DETACH:UnHook();break;}return TRUE;
}

Hook 实现拦截文件创建: 文件的创建离不开CreateFileA函数,我们可以Hook这个函数,来拦截程序创建文件,此方法可用于对抗恶意代码,一些杀软也会通过Hook的方式监控文件的创建。

#include <Windows.h>
#include <MinHook.h>
#pragma comment(lib,"libMinHook.x86.lib")typedef HANDLE(WINAPI *OldCreateFileA)(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);OldCreateFileA fpCreateFileA = NULL;// 定义个性化的CreateFileA 并实现过滤功能
HANDLE WINAPI MyCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{char *path = "c://test.txt";if (strcmp(lpFileName, path)){MessageBoxA(NULL, lpFileName, "MsgBox", NULL);MessageBoxA(0, TEXT("拦截到创建文件请求"), 0, 0);lpFileName = "";}return fpCreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
}void SetHook()
{if (MH_Initialize() == MB_OK){// 参数一: 函数名称 参数二: 自定义函数 参数三: 原始函数指针MH_CreateHook(&CreateFileA, &MyCreateFileA, reinterpret_cast<void**>(&fpCreateFileA));MH_EnableHook(&CreateFileA);}
}void UnHook()
{if (MH_DisableHook(&CreateFileA) == MB_OK){MH_Uninitialize();}
}BOOL APIENTRY DllMain(HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:SetHook();break;case DLL_PROCESS_DETACH:UnHook();break;}return TRUE;
}

Hook 实现监控进程创建: 将下方DLL注入到explorer.exe进程中,即可监控系统的进程创建,在其中可以做查杀检测等,即可实现简单的主动防御.

#include <Windows.h>
#include <stdio.h>
#include <MinHook.h>#pragma comment(lib,"libMinHook.x64.lib")typedef int (WINAPI *OldCreateProcessW)(LPCWSTR, LPWSTR, LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION);OldCreateProcessW fpCreateProcessW = NULL;int WINAPI MyCreateProcessW(LPCWSTR lpApplicationName,LPWSTR lpCommandLine,LPSECURITY_ATTRIBUTES lpProcessAttributes,LPSECURITY_ATTRIBUTES lpThreadAttributes,BOOL bInheritHandles,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCWSTR lpCurrentDirectory,LPSTARTUPINFOW lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation)
{MessageBoxW(0, lpApplicationName, 0, 0);int nRetn = fpCreateProcessW(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes,bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation);return nRetn;
}void SetHook()
{if (MH_Initialize() == MB_OK){// 参数一: 函数名称 参数二: 自定义函数 参数三: 原始函数指针MH_CreateHook(&CreateProcessW, &MyCreateProcessW, reinterpret_cast<void**>(&fpCreateProcessW));MH_EnableHook(&CreateProcessW);}
}void UnHook()
{if (MH_DisableHook(&CreateProcessW) == MB_OK){MH_Uninitialize();}
}BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:SetHook();break;case DLL_PROCESS_DETACH:UnHook();break;}return TRUE;
}

Hook 实现禁止结束进程: 通过将DLL注入到系统的任务管理器中,实现禁止结束某个进程,任务管理器通过调用TerminateProcess()函数来执行强杀进程,我们只需要Hook系统中的OpenProcess()打开进程并让其返回假,那么TerminateProcess()拿不到句柄也就无法完成结束进程了.

#include <Windows.h>
#include <stdio.h>
#include <MinHook.h>#pragma comment(lib,"libMinHook.x64.lib")typedef HANDLE(WINAPI *OldOpenProcess)(DWORD, BOOL, DWORD);OldOpenProcess fpOpenProcess = NULL;HANDLE WINAPI MyOpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
{HWND handle = NULL;handle = FindWindow(L"TXGuiFoundation", L"QQ");if (handle != NULL){HANDLE Retn = fpOpenProcess(dwDesiredAccess, bInheritHandle, 0);return Retn;}HANDLE Retn = fpOpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);return Retn;
}void SetHook()
{if (MH_Initialize() == MB_OK){// 参数一: 函数名称 参数二: 自定义函数 参数三: 原始函数指针MH_CreateHook(&OpenProcess, &MyOpenProcess, reinterpret_cast<void**>(&MyOpenProcess));MH_EnableHook(&OpenProcess);}
}void UnHook()
{if (MH_DisableHook(&OpenProcess) == MB_OK){MH_Uninitialize();}
}BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:SetHook();break;case DLL_PROCESS_DETACH:UnHook();break;}return TRUE;
}

Inline Hook 钩子编写技巧相关推荐

  1. C/C++:Windows编程—Inline Hook内联钩子(上)

    前言 先介绍下Windows中的Hook技术.Hook是Windows中提供的一种用以替换DOS下"中断"的系统机制,中文译为"挂钩"或"钩子&quo ...

  2. Inline Hook

    @author: dlive IAT Hook时如果要钩取的API不在IAT中(LoadLibrary后调用),则无法使用该技术.而Inline Hook不存在这个限制. 0x01 Inline Ho ...

  3. Windows内核实验005 Inline Hook

    文章目录 准备工作 寻找Inline Hook的返回地址 编写代码 动态变化的返回地址 JmpTargetAddr Inline Hook基本框架 示例代码 实战HOOK KiTrap01 无需计算偏 ...

  4. Windows驱动开发学习笔记(六)—— Inline HOOK

    Windows驱动开发学习笔记(六)-- Inline HOOK SSDT HOOK Inline Hook 挂钩 执行流程 脱钩 实验一:3环 Inline Hook 实验二:0环 Inline H ...

  5. android hook 实例,代码实例分析android中inline hook

    以下内容通过1.实现目标注入程序,2.实现主程序,3.实现注入函数,4.thumb指令集实现等4个方面详细分析了android中inline hook的用法,以下是全部内容: 最近终于沉下心来对着书把 ...

  6. Windows下x86和x64平台的Inline Hook介绍

    原文链接:https://blog.csdn.net/PeaZomboss/article/details/129095200?spm=1001.2014.3001.5501 前言 我在之前研究文明6 ...

  7. IAT hook与inline hook的区别

    IAT hook 导入表hook原理:修改导入表中某函数的地址到自己的补丁函数.IATHook 通过GetProcAddress获取目标函数地址 在程序内存中找到所在dll的导入表 查找目标函数地址保 ...

  8. wince中的hook(钩子)用法

    wince中的hook(钩子)用法 Hook(钩子)是一种在消息到达目标窗口前进行截获的技术.使用钩子主要使用以下三个函数SetWindowsHookEx:创建钩子 CallNextHookEx:将消 ...

  9. C语言playsoundw函数,使用inline hook实现修改PC微信通知铃声-哥哥微信来了

    本帖最后由 bester 于 2020-2-15 01:20 编辑 原贴:https://www.52pojie.cn/thread-1103441-1-1.html 最近频繁刷某音刷到哥哥微信来了的 ...

最新文章

  1. C# WinForm 在窗口菜单上显示已打开窗体的标题及其窗体的排列
  2. python学习费用-python学习,是看免费视频自学,还是报个收费班学习好?
  3. 02 - Unit06:弹出对话框
  4. java文本区显示在右边_怎么让文本区从右边开始显示文本
  5. 如何用Java代码在SAP Marketing Cloud里创建contact数据
  6. 【Android 修炼手册】Gradle 篇 -- Gradle 源码分析
  7. 快手2021年营收810亿元 经调整净亏损188亿元
  8. Docker这么香,为啥还要K8S?
  9. iOS 无证书真机调试
  10. ActiveMQ消息队列
  11. Linux运维04:vmstat命令详解
  12. BAT机器学习面试1000题系列
  13. 中级程序员还应该如何提高自己
  14. Q1营收7740万元亏损大幅收窄,转型自救的途牛能否追赶携程艺龙?
  15. 测牛学堂:2023软件测试入门学习指南之测试方法完结总结
  16. 初一学生上计算机教学内容,初一计算机教学工作计划.docx
  17. HCL实验-使用ACL进行SSH服务器的登录源限制的简单实验(NAT+SSH+ACL)
  18. 一文概览神经网络优化算法
  19. 区块链+大数据:万物互联时代的“CP组合”
  20. win10环境下AndroidStudio输入法光标不跟随解决办法

热门文章

  1. 数据传输 -- 字符串报文
  2. 互联网创新创业大赛优秀范例_第五十九期创业沙龙——“互联网+”大学生创新创业大赛实践案例...
  3. 中兴推“小兴看看”,诠释智能家电的真谛
  4. 域名是干啥用的?企业自己都记不住的域名还能发挥作用吗?
  5. Filezilla 连接不上 Error: Connection timed out after 20 seconds of inactivity
  6. 【报错】安装scrapy时Could not build wheels for cryptography which use PEP 517 and cannot be installed direc
  7. vue使用报错记录(cli4):[vue/valid-v-for] Custom elements in iteration require ‘v-bind:key‘ direc
  8. 系统上公有云安全需要考虑什么?
  9. 美国短信怎么发?美国短信如何计费?
  10. 那些年用过的时间衰减函数