创建挂起的进程并在恢复之前重写其内存空间

时间:2018-06-24 17:07:34

标签: c++ windows assembly 64-bit

我正在分析以下代码:

  • 以挂起状态(CREATE_SUSPENDED)创建一个新进程。
  • 使用pZwUnmapViewOfSection()取消映射内存空间。
  • 将新的PE映像(存储在程序中)写入内存空间。
  • 将RAX设置为进程的入口点。
  • 继续创建的过程。

我想知道为什么这种方法有效。

如果代码将PE映像写入新进程的内存空间,那么加载器不会运行以解决导入等问题-还是CREATE_SUSPENDED在加载器执行作业之前?

此外,EAX(或RAX)在启动PE可执行文件时是否始终保留其入口点?

/* Create suspended process for program (using current module) */
memset(&si, 0, sizeof(si));
memset(&pi, 0, sizeof(pi));
si.cb = sizeof(si);
if (CreateProcessA(szFileName, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi) == FALSE) {
    Debug("[Debug] RunPE(): CreateProcessA(): (%lu)\n", GetLastError());
    return FALSE;
}

/* Get thread context (processor-specific register data) */
context.ContextFlags = CONTEXT_FULL;
if (GetThreadContext(pi.hThread, &context) == FALSE) {
    Debug("[Debug] RunPE(): GetThreadContext()");
}

/* Unmap memory space of program */
pZwUnmapViewOfSection = (PZUVOS)GetProcAddress(GetModuleHandleA("ntdll.dll"), "ZwUnmapViewOfSection");
pZwUnmapViewOfSection(pi.hProcess, (PVOID)pinh->OptionalHeader.ImageBase);

/* Allocate virtual memory for program */
lpAddress = VirtualAllocEx(pi.hProcess, (PVOID)pinh->OptionalHeader.ImageBase, pinh->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (lpAddress == NULL) {
    Debug("[Debug] RunPE(): VirtualAllocEx(): (%lu)\n", GetLastError());
    return FALSE;
}

/* Write COFF, optional and section headers into virtual memory */
if (WriteProcessMemory(pi.hProcess, (PVOID)pinh->OptionalHeader.ImageBase, fs->pBuffer, pinh->OptionalHeader.SizeOfHeaders, NULL) == FALSE) {
    Debug("[Debug] RunPE(): WriteProcessMemory(): (%lu)\n", GetLastError());
    return FALSE;
}

/* Write sections into virtual memory */
for (int i = 0; i < pinh->FileHeader.NumberOfSections; i++) {
    /* Compute section header of each section */
    pish = (PIMAGE_SECTION_HEADER)((DWORD)fs->pBuffer + pidh->e_lfanew + sizeof(IMAGE_NT_HEADERS) + sizeof(IMAGE_SECTION_HEADER) * i);
    /* Write section into virtual memory */
    WriteProcessMemory(pi.hProcess, (PVOID)(pinh->OptionalHeader.ImageBase + pish->VirtualAddress), (LPVOID)((DWORD)fs->pBuffer + pish->PointerToRawData), pish->SizeOfRawData, NULL);
}

/* Set entry-point as virtual address: address of entry point */
context.Rax = pinh->OptionalHeader.ImageBase + pinh->OptionalHeader.AddressOfEntryPoint;
if (SetThreadContext(pi.hThread, &context) == FALSE) {
    Debug("[Debug]: RunPE(): SetThreadContext(): (%lu)\n", GetLastError());
    return FALSE;
}

0 个答案:

没有答案