一些奇奇怪怪的隐藏闲谈
字数 1860 2025-08-06 23:10:24

Windows系统隐藏技术详解

0x00 前言

本文详细讲解Windows系统中各种隐藏技术,包括DLL模块隐藏、API调用隐藏、进程隐藏和驱动隐藏等技术原理与实现方法。这些技术可用于安全研究、反病毒检测等场景。

0x01 隐藏DLL模块

1.1 断链技术

原理
Windows进程加载的DLL模块信息保存在PEB(Process Environment Block)结构的_PEB_LDR_DATA中,包含三个链表:

  • InLoadOrderModuleList
  • InMemoryOrderModuleList
  • InInitializationOrderModuleList

这些链表指向LDR_DATA_TABLE_ENTRY结构,包含模块详细信息。

实现步骤

  1. 获取PEB地址:__readgsqword(0x60)
  2. 遍历模块链表找到目标DLL
  3. 修改链表指针实现断链:
    • 修复前后节点的Flink和Blink指针
    • 清除模块特征

关键代码

// 断链操作
pNext->InLoadOrderLinks.Flink->Blink = pNext->InLoadOrderLinks.Blink;
pNext->InLoadOrderLinks.Blink->Flink = pNext->InLoadOrderLinks.Flink;
pNext->InLoadOrderLinks.Blink = pNext->InLoadOrderLinks.Flink = (PLIST_ENTRY)pNext;

// 清除特征
VirtualProtect(pNext->DllBase, 0x1000, PAGE_READWRITE, &dwOleProct);
memset(pNext->DllBase, 0, 0x1000);

1.2 内存加载DLL

原理
实现本地PE装载器,直接在内存中加载DLL而不通过系统加载器:

  1. 复制PE头部
  2. 复制节区数据
  3. 修复重定位
  4. 修复导入表
  5. 跳转到入口点执行

关键函数

VOID CopyPEHeader(PUCHAR buffer, PUCHAR IamgeBase);  // 复制PE头
VOID CopySection(PUCHAR buffer, PUCHAR ImageBase);   // 复制节区
VOID FixReloaction(PUCHAR pImageBase);              // 修复重定位
VOID FixIAT(PUCHAR pImageBase);                     // 修复导入表

实现要点

  • 使用VirtualAlloc分配内存
  • 处理不同节的对齐方式
  • 修复地址相关的重定位项
  • 动态解析API地址

0x02 隐藏API调用

2.1 系统调用技术

原理
绕过常规API调用路径,直接通过系统调用进入内核:

  1. 用户层API最终调用Nt*系列函数
  2. Nt*函数通过KiFastSystemCall进入内核
  3. 直接复制系统调用代码到自定义内存执行

实现方法

  1. 直接调用Nt*系列函数替代Win32 API
  2. 复制系统调用代码到新内存执行

示例代码

// 直接调用NtCreateFile替代CreateFile
NTSTATUS NtCreateFileFunc(...)
{
    auto pfnCall = (PFN_NtCreateFile)VirtualAlloc(0, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy_s(pfnCall, 0x1000, pCall, 0x1000);
    return pfnCall(...);
}

注意事项

  • 需要处理参数转换
  • 建议重载ntdll.dll获取干净函数
  • 避免挂钩检测

0x03 隐藏进程

3.1 进程伪装

修改进程信息使其看起来像合法进程:

  • 修改进程名
  • 修改PEB中的路径信息
  • 伪装成系统进程

3.2 傀儡进程技术

3.2.1 内存加载进程

原理
类似DLL内存加载,直接在内存中加载整个PE文件执行

实现步骤

  1. 读取PE文件到内存
  2. 分配内存空间
  3. 复制PE头和节区
  4. 修复重定位和导入表
  5. 跳转到入口点执行

特点

  • 进程列表中不可见
  • 无磁盘文件痕迹

3.2.2 进程替换

原理
挂起目标进程后替换其内存内容

实现步骤

  1. 创建挂起状态的进程
  2. 获取线程上下文
  3. 分配内存并写入PE数据
  4. 修复重定位和导入表
  5. 设置新入口点
  6. 恢复线程执行

关键代码

// 创建挂起进程
CreateProcessA(path, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);

// 获取和修改线程上下文
GetThreadContext(pi.hThread, &context);
context.Rip = ULONG64(pImageBase) + pNtHeader->OptionalHeader.AddressOfEntryPoint;
SetThreadContext(pi.hThread, &context);

3.3 Hook NtQuerySystemInformation

原理
拦截进程枚举API调用,过滤特定进程信息

实现方法

  1. Hook NtQuerySystemInformation函数
  2. 检查SystemProcessInformation调用
  3. 从进程链表中移除目标进程

关键代码

NTSTATUS NtQuerySystemInformationHooked(...)
{
    // 调用原始函数
    Result = pfnNtQuerySystemInformation(...);
    
    // 过滤进程信息
    while (pNextSystemProcess->NextEntryOffset != 0)
    {
        if (lstrcmpW(pNextSystemProcess->ImageName.Buffer, HIDE_PROCESS_NAME) == 0) {
            pSystemProcess->NextEntryOffset += pNextSystemProcess->NextEntryOffset;
        }
    }
}

3.4 断链隐藏进程(驱动层)

原理
修改内核EPROCESS结构的ActiveProcessLinks链表

实现步骤

  1. 遍历进程链表找到目标EPROCESS
  2. 修改前后进程的链表指针
  3. 移除目标进程项

关键代码

// 断链操作
global::s_pListEntry = (PLIST_ENTRY)((ULONG64)pEprocess + Eprocess_ActiveProcessLinks_Offset);
RemoveEntryList(global::s_pListEntry);

注意事项

  • 需要驱动权限
  • 可能触发PatchGuard导致蓝屏
  • 需处理Wow64进程

0x04 隐藏驱动

4.1 断链隐藏驱动

原理
修改驱动对象的DriverSection指向的LDR_DATA_TABLE_ENTRY结构

实现方法

// 断链操作
PKLDR_DATA_TABLE_ENTRY pHead = ((PKLDR_DATA_TABLE_ENTRY)(pObj->DriverSection));
RemoveEntryList((PLIST_ENTRY)pHead);

// 清除特征
pObj->Size = 0;
pObj->Type = 0;
pObj->DeviceObject = 0;
pObj->DriverSection = 0;

4.2 使用MiProcessLoaderEntry

原理
调用未公开的MiProcessLoaderEntry函数安全移除驱动信息

实现步骤

  1. 通过特征码定位函数地址
  2. 调用函数移除驱动信息
  3. 清理驱动对象特征

关键代码

// 特征码定位
UCHAR ucMiProcessLoaderEntrySignCode[] = { 
    0x48, 0x8B, 0xC4, 0x48, 0x89, 0x58, 0x08, ... };

// 调用函数移除
((void (*_fastcall)(PVOID, ULONG))pfnMiProcessLoaderEntry)(DriverObject->DriverSection, 0);

4.3 内存加载驱动

原理
在内存中直接加载驱动执行

实现步骤

  1. 读取驱动文件到内存
  2. 分配内核内存
  3. 复制PE头和节区
  4. 修复重定位和导入表
  5. 调用驱动入口

关键函数

ULONG64 LoadDriver(PUCHAR buffer, PULONG64 pEntry)
{
    // 分配内存
    image = MmAllocateContiguousMemorySpecifyCache(...);
    
    // 复制PE结构
    CopyIamgeHeader(buffer, image);
    CopyIamgeSection(buffer, image);
    
    // 修复
    FixReloc(image);
    FixImport(image);
    
    // 获取入口点
    *pEntry = pNt->OptionalHeader.AddressOfEntryPoint + image;
}

0x05 注意事项

  1. 现代系统安全机制(PatchGuard, DSE等)可能拦截这些技术
  2. 部分技术可能导致系统不稳定
  3. 实际应用中需要组合多种技术
  4. 建议在合法授权范围内使用这些技术

0x06 参考资源

  1. Windows Internals书籍
  2. MSDN文档
  3. 相关技术博客和论文
  4. 开源项目如Mimikatz、Process Hacker等实现
Windows系统隐藏技术详解 0x00 前言 本文详细讲解Windows系统中各种隐藏技术,包括DLL模块隐藏、API调用隐藏、进程隐藏和驱动隐藏等技术原理与实现方法。这些技术可用于安全研究、反病毒检测等场景。 0x01 隐藏DLL模块 1.1 断链技术 原理 : Windows进程加载的DLL模块信息保存在PEB(Process Environment Block)结构的 _PEB_LDR_DATA 中,包含三个链表: InLoadOrderModuleList InMemoryOrderModuleList InInitializationOrderModuleList 这些链表指向 LDR_DATA_TABLE_ENTRY 结构,包含模块详细信息。 实现步骤 : 获取PEB地址: __readgsqword(0x60) 遍历模块链表找到目标DLL 修改链表指针实现断链: 修复前后节点的Flink和Blink指针 清除模块特征 关键代码 : 1.2 内存加载DLL 原理 : 实现本地PE装载器,直接在内存中加载DLL而不通过系统加载器: 复制PE头部 复制节区数据 修复重定位 修复导入表 跳转到入口点执行 关键函数 : 实现要点 : 使用 VirtualAlloc 分配内存 处理不同节的对齐方式 修复地址相关的重定位项 动态解析API地址 0x02 隐藏API调用 2.1 系统调用技术 原理 : 绕过常规API调用路径,直接通过系统调用进入内核: 用户层API最终调用Nt* 系列函数 Nt* 函数通过 KiFastSystemCall 进入内核 直接复制系统调用代码到自定义内存执行 实现方法 : 直接调用Nt* 系列函数替代Win32 API 复制系统调用代码到新内存执行 示例代码 : 注意事项 : 需要处理参数转换 建议重载ntdll.dll获取干净函数 避免挂钩检测 0x03 隐藏进程 3.1 进程伪装 修改进程信息使其看起来像合法进程: 修改进程名 修改PEB中的路径信息 伪装成系统进程 3.2 傀儡进程技术 3.2.1 内存加载进程 原理 : 类似DLL内存加载,直接在内存中加载整个PE文件执行 实现步骤 : 读取PE文件到内存 分配内存空间 复制PE头和节区 修复重定位和导入表 跳转到入口点执行 特点 : 进程列表中不可见 无磁盘文件痕迹 3.2.2 进程替换 原理 : 挂起目标进程后替换其内存内容 实现步骤 : 创建挂起状态的进程 获取线程上下文 分配内存并写入PE数据 修复重定位和导入表 设置新入口点 恢复线程执行 关键代码 : 3.3 Hook NtQuerySystemInformation 原理 : 拦截进程枚举API调用,过滤特定进程信息 实现方法 : Hook NtQuerySystemInformation 函数 检查 SystemProcessInformation 调用 从进程链表中移除目标进程 关键代码 : 3.4 断链隐藏进程(驱动层) 原理 : 修改内核 EPROCESS 结构的 ActiveProcessLinks 链表 实现步骤 : 遍历进程链表找到目标 EPROCESS 修改前后进程的链表指针 移除目标进程项 关键代码 : 注意事项 : 需要驱动权限 可能触发PatchGuard导致蓝屏 需处理Wow64进程 0x04 隐藏驱动 4.1 断链隐藏驱动 原理 : 修改驱动对象的 DriverSection 指向的 LDR_DATA_TABLE_ENTRY 结构 实现方法 : 4.2 使用MiProcessLoaderEntry 原理 : 调用未公开的 MiProcessLoaderEntry 函数安全移除驱动信息 实现步骤 : 通过特征码定位函数地址 调用函数移除驱动信息 清理驱动对象特征 关键代码 : 4.3 内存加载驱动 原理 : 在内存中直接加载驱动执行 实现步骤 : 读取驱动文件到内存 分配内核内存 复制PE头和节区 修复重定位和导入表 调用驱动入口 关键函数 : 0x05 注意事项 现代系统安全机制(PatchGuard, DSE等)可能拦截这些技术 部分技术可能导致系统不稳定 实际应用中需要组合多种技术 建议在合法授权范围内使用这些技术 0x06 参考资源 Windows Internals书籍 MSDN文档 相关技术博客和论文 开源项目如Mimikatz、Process Hacker等实现