Windows 进程伪装技术深度解析:从 PEB 结构到实战实现
在 Windows 系统安全领域,进程伪装是一项关键的技术手段。本文将深入探讨如何通过修改进程环境块(PEB)中的路径和命令行信息来实现进程伪装,并提供一个完整的 C++ 实现方案。
1. 进程伪装技术概述
进程伪装是指通过修改进程的某些关键信息,使其在系统监控工具中显示为另一个进程的技术。这种技术在合法用途(如安全测试)和恶意软件中都有应用。
核心原理:Windows 系统中的每个进程都有一个进程环境块(Process Environment Block,PEB),其中包含了进程的镜像路径和命令行参数等信息。通过修改这些信息,可以改变进程在任务管理器等工具中的显示。
1.1 PEB 结构解析
PEB 是 Windows 内核为每个用户模式进程维护的数据结构,包含以下关键字段:
typedef struct _PEB { BYTE Reserved1[2]; BYTE BeingDebugged; BYTE Reserved2[1]; PVOID Reserved3[2]; PPEB_LDR_DATA Ldr; PRTL_USER_PROCESS_PARAMETERS ProcessParameters; PVOID Reserved4[3]; PVOID AtlThunkSListPtr; PVOID Reserved5; ULONG Reserved6; PVOID Reserved7; ULONG Reserved8; ULONG AtlThunkSListPtr32; PVOID Reserved9[45]; BYTE Reserved10[96]; PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine; BYTE Reserved11[128]; PVOID Reserved12[1]; ULONG SessionId; } PEB, *PPEB;其中ProcessParameters指向RTL_USER_PROCESS_PARAMETERS结构,包含了我们需要修改的关键信息:
typedef struct _RTL_USER_PROCESS_PARAMETERS { BYTE Reserved1[16]; PVOID Reserved2[10]; UNICODE_STRING ImagePathName; UNICODE_STRING CommandLine; } RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;2. 技术实现步骤
实现进程伪装需要以下三个关键步骤:
2.1 获取目标进程的 PEB 地址
首先需要通过NtQueryInformationProcess函数获取目标进程的 PEB 地址:
typedef NTSTATUS (NTAPI *typedef_NtQueryInformationProcess)( IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, OUT PVOID ProcessInformation, IN ULONG ProcessInformationLength, OUT PULONG ReturnLength OPTIONAL ); BOOL GetProcessPeb(HANDLE hProcess, PEB* pPeb) { typedef_NtQueryInformationProcess NtQueryInformationProcess = NULL; PROCESS_BASIC_INFORMATION pbi = {0}; NtQueryInformationProcess = (typedef_NtQueryInformationProcess)GetProcAddress( GetModuleHandle("ntdll.dll"), "NtQueryInformationProcess"); NTSTATUS status = NtQueryInformationProcess( hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL); if (!NT_SUCCESS(status)) { return FALSE; } return ReadProcessMemory(hProcess, pbi.PebBaseAddress, pPeb, sizeof(PEB), NULL); }2.2 读取并修改进程参数
获取 PEB 后,我们需要读取并修改ProcessParameters中的ImagePathName和CommandLine:
BOOL ModifyProcessParameters(HANDLE hProcess, PEB* pPeb, const wchar_t* newPath, const wchar_t* newCmd) { RTL_USER_PROCESS_PARAMETERS params = {0}; if (!ReadProcessMemory(hProcess, pPeb->ProcessParameters, ¶ms, sizeof(params), NULL)) { return FALSE; } // 计算新字符串长度(字节数) USHORT pathLen = (wcslen(newPath) + 1) * sizeof(wchar_t); USHORT cmdLen = (wcslen(newCmd) + 1) * sizeof(wchar_t); // 写入新路径 if (!WriteProcessMemory(hProcess, params.ImagePathName.Buffer, newPath, pathLen, NULL)) { return FALSE; } // 更新长度信息 if (!WriteProcessMemory(hProcess, ¶ms.ImagePathName.Length, &pathLen, sizeof(pathLen), NULL)) { return FALSE; } // 写入新命令行 if (!WriteProcessMemory(hProcess, params.CommandLine.Buffer, newCmd, cmdLen, NULL)) { return FALSE; } // 更新长度信息 if (!WriteProcessMemory(hProcess, ¶ms.CommandLine.Length, &cmdLen, sizeof(cmdLen), NULL)) { return FALSE; } return TRUE; }2.3 完整实现代码
以下是完整的进程伪装函数实现:
#include <windows.h> #include <winternl.h> #include <tchar.h> BOOL DisguiseProcess(DWORD pid, const wchar_t* newPath, const wchar_t* newCmd) { // 打开目标进程 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); if (hProcess == NULL) { return FALSE; } // 获取PEB PEB peb = {0}; if (!GetProcessPeb(hProcess, &peb)) { CloseHandle(hProcess); return FALSE; } // 修改进程参数 BOOL result = ModifyProcessParameters(hProcess, &peb, newPath, newCmd); CloseHandle(hProcess); return result; }3. 技术细节与注意事项
3.1 32位与64位兼容性处理
在跨平台环境中,需要注意指针大小的差异:
- 在64位系统中,PEB结构中的指针是8字节
- 在32位系统中,指针是4字节
- 在64位系统上运行32位程序时(WoW64),需要特殊处理
3.2 内存保护属性
修改进程内存时,可能需要先修改内存页的保护属性:
DWORD oldProtect = 0; VirtualProtectEx(hProcess, address, size, PAGE_READWRITE, &oldProtect); // 修改内存 VirtualProtectEx(hProcess, address, size, oldProtect, &oldProtect);3.3 验证与测试
修改完成后,可以使用以下方法验证:
- 使用Process Explorer查看进程属性
- 通过
GetCommandLine()API获取当前进程的命令行 - 检查进程的PEB内容(需要调试器)
4. 防御措施与检测方法
了解攻击技术的同时,也需要知道如何防御:
4.1 检测方法
| 检测技术 | 描述 | 有效性 |
|---|---|---|
| 内存扫描 | 扫描进程内存中的PEB结构 | 高 |
| API Hook | 监控关键API调用(如NtQueryInformationProcess) | 中 |
| 行为分析 | 分析进程行为与声明身份的匹配度 | 高 |
4.2 防御建议
- 使用数字签名验证进程身份
- 实施代码完整性检查
- 采用多层防御策略(如EDR解决方案)
提示:在实际安全产品中,通常会结合多种检测技术来提高检测准确率。
5. 实际应用案例
5.1 合法用途
- 安全测试:红队演练中模拟攻击行为
- 调试工具:隐藏调试器进程
- 隐私保护:保护敏感进程信息
5.2 恶意软件应用
- 木马程序:伪装成系统进程
- 勒索软件:隐藏恶意活动
- APT攻击:长期潜伏不被发现
6. 高级技术与扩展
6.1 傀儡进程技术
通过创建挂起的进程并修改其内存,可以实现更彻底的伪装:
BOOL CreateSuspendedProcess(LPCWSTR path, LPWSTR cmd, LPPROCESS_INFORMATION pi) { STARTUPINFO si = {sizeof(si)}; return CreateProcess(path, cmd, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, pi); }6.2 进程隐藏技术
通过Hook系统API(如ZwQuerySystemInformation)可以完全隐藏进程:
NTSTATUS HookedZwQuerySystemInformation( SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength) { // 调用原始函数 NTSTATUS status = OriginalZwQuerySystemInformation(...); // 过滤掉要隐藏的进程 if (NT_SUCCESS(status) && SystemInformationClass == 5) { FilterProcessList(SystemInformation); } return status; }7. 总结与最佳实践
进程伪装是一项强大的技术,但需要谨慎使用。在合法应用中,应当遵循以下原则:
- 明确授权:只在获得明确授权的环境中使用
- 最小权限:使用最低必要的权限级别
- 可追溯性:保留足够的日志和审计信息
- 防御思维:了解技术的同时也要知道如何防御
对于开发者来说,深入理解Windows内部机制是掌握这类技术的关键。建议从官方文档和逆向分析入手,逐步构建完整的知识体系。