首页 > 解决方案 > 创建挂起的进程并在恢复前重写其内存空间

问题描述

我正在分析代码(见下文):

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

如果代码将 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;
}

标签: c++windowsassembly64-bit

解决方案


推荐阅读