我目前正在尝试使用 C 实现某种进程挖空 (RunPE) 技术。 到目前为止我所做的基本上就是找到 PEB 并获取进程的(在挂起模式下)图像基地址。 现在,我明白我必须使用函数
NtUnmapViewOfSection
来“擦除”进程的虚拟内存并用我的替换它。
但是,每当我尝试使用
NtUnmapViewOfSection
时,它都显示为白色,并且不允许我编译...
我包含了 <winternl.h>
并且在 Visual Studio 2019 的链接器选项中,我添加了 ntdll.lib
依赖项。但它仍然不让我使用它,即使它让我使用 Native API 的其他函数,例如 NtQueryInformationProcess(查找 PEB 的地址)。
如果相关的话,这是我到目前为止的代码:
#include <windows.h>
#include <stdio.h>
#include <winternl.h>
int main(int argc, char* argv[])
{
printf("Creating process\r\n");
LPSTARTUPINFOA si = (LPSTARTUPINFOA)calloc(1, sizeof(STARTUPINFOA));
LPPROCESS_INFORMATION pi = (LPPROCESS_INFORMATION)calloc(1, sizeof(PROCESS_INFORMATION));
if (!CreateProcessA
(
"C:\\Windows\\sysWOW64\\calc.exe", // Process uses LoadLibraryA and GetProcAddress. TODO: shellcode with LDR.
NULL,
NULL,
NULL,
NULL,
CREATE_SUSPENDED,
NULL,
NULL,
si,
pi
))
{
printf("Error with CreateProcessA - %d", GetLastError());
return 1;
}
if (!pi->hProcess)
{
printf("Error creating process - %d", GetLastError());
return 1;
}
HANDLE hDestProcess = pi->hProcess;
PROCESS_BASIC_INFORMATION* pbi = (PROCESS_BASIC_INFORMATION*)calloc(1, sizeof(PROCESS_BASIC_INFORMATION));
DWORD retLen = 0;
if (NtQueryInformationProcess(hDestProcess, ProcessBasicInformation, pbi, sizeof(PROCESS_BASIC_INFORMATION), &retLen))
{
printf("Error finding peb - %d", GetLastError());
return 1;
}
DWORD pebImageBaseOffset = (DWORD)pbi->PebBaseAddress + 0x8;
printf("Peb offset: %p\n", pebImageBaseOffset);
LPVOID destImageBase = 0;
SIZE_T bytesRead;
if (!ReadProcessMemory(hDestProcess, (LPCVOID)pebImageBaseOffset, &destImageBase, 0x4, &bytesRead))
{
printf("Error getting process's image base - %d", GetLastError());
return 1;
}
printf("Process image base: %p\n", destImageBase);
if (NtUnmapViewOfSection(pi->hProcess, destImageBase))
{
printf("Process view unmapping failed");
}
// Read other executable file
HANDLE sourceFile =
CreateFileA("C:\\Windows\\sysWOW64\\cmd.exe", GENERIC_READ, NULL, NULL, OPEN_EXISTING, NULL, NULL);
DWORD sourceFileSize = GetFileSize(sourceFile, NULL);
DWORD fileBytesRead = 0;
LPVOID sourceFileBytes = (LPVOID)malloc(sourceFileSize);
ReadFile(sourceFile, sourceFileBytes, sourceFileSize, &fileBytesRead, NULL);
/*DWORD bytesWritten = 0;
BOOL writeSuccess = WriteProcessMemory(hDestProcess, entryPointAddr, sourceFileBytes, fileBytesRead, &bytesWritten);
if (!writeSuccess)
{
printf("Problem writing to memory - %d", GetLastError());
return 1;
}*/
// Resume the main thread
ResumeThread(pi->hThread);
printf("Process main thread resumed");
// Close handles
CloseHandle(pi->hProcess);
CloseHandle(pi->hThread);
return 0;
}
错误信息: 当我试图包含 wdm.h 或其他人时:
Severity Code Description Project File Line Suppression State
Error C1083 Cannot open include file: 'wdm.h': No such file or directory process_hollowing_other_exe D:\other_projects\process_hollowing\process_hollowing_other_exe\process_hollowing_other_exe\main.c 4
当我尝试使用没有标题的功能时:
Error LNK2019 unresolved external symbol _NtUnmapViewOfSection referenced in function _main process_hollowing_other_exe D:\other_projects\process_hollowing\process_hollowing_other_exe\process_hollowing_other_exe\main.obj 1
根据文档:ZwUnmapViewOfSection 函数 (wdm.h)
如果这个函数的调用发生在用户态,你应该使用 将“ZwUnmapViewOfSection”命名为“NtUnmapViewOfSection”。
你应该包括
wdm.h
。项目应该在 WDK 的构建环境中构建。您需要构建一个真正的驱动程序才能使用 NtUnmapViewOfSection。