RunPE内存故障

RunPE memory malfunction

每当执行我的可执行文件时,80% 的时间它都能正常工作。另外 20% 的时间,我从 Windows 收到 0xc00000005 错误。我相信这可能是内存问题,但我不确定如何解决。我花了太多时间试图弄清楚如何解决这个问题,所以我现在来到这里。我正在使用 Visual Studio.

我调试了程序,但它在名为 "Write process memory step 1: Failed."

的调试脚本处失败了
if (WriteProcessMemory(PI.hProcess, pImageBase, Image, NtHeader->OptionalHeader.SizeOfHeaders, NULL))
{
    for (count = 0; count < NtHeader->FileHeader.NumberOfSections; count++)
    {
        SectionHeader = PIMAGE_SECTION_HEADER(DWORD(Image) + DOSHeader->e_lfanew + 248 + (count * 40));

        WriteProcessMemory(PI.hProcess, LPVOID(DWORD(pImageBase) + SectionHeader->VirtualAddress),
            LPVOID(DWORD(Image) + SectionHeader->PointerToRawData), SectionHeader->SizeOfRawData, 0);
    }

RunPE 函数:

     /*             PE Execution Function               */
int RunPortableExecutable(void* Image)
{
    IMAGE_DOS_HEADER* DOSHeader;
    IMAGE_NT_HEADERS* NtHeader;
    IMAGE_SECTION_HEADER* SectionHeader;

    PROCESS_INFORMATION PI;
    STARTUPINFOA SI;

    DWORD* ImageBase;
    void* pImageBase;

    int count;
    char CurrentFilePath[1024];

    DOSHeader = PIMAGE_DOS_HEADER(Image);
    NtHeader = PIMAGE_NT_HEADERS(DWORD(Image) + DOSHeader->e_lfanew);

    GetModuleFileNameA(0, CurrentFilePath, 1024);
    if (NtHeader->Signature == IMAGE_NT_SIGNATURE)
    {
        ZeroMemory(&PI, sizeof(PI));
        ZeroMemory(&SI, sizeof(SI));

        if (CreateProcessA(CurrentFilePath, NULL, NULL, NULL, FALSE,
            CREATE_SUSPENDED, NULL, NULL, &SI, &PI))
        {
            LPCONTEXT CTX = LPCONTEXT(VirtualAlloc(NULL, sizeof(CTX), MEM_COMMIT, PAGE_READWRITE));
            CTX->ContextFlags = CONTEXT_FULL;

            if (GetThreadContext(PI.hThread, LPCONTEXT(CTX)))
            {
                if (ReadProcessMemory(PI.hProcess, LPCVOID(CTX->Ebx + 8), LPVOID(&ImageBase), 4, 0))
                {
                    pImageBase = VirtualAllocEx(PI.hProcess, LPVOID(NtHeader->OptionalHeader.ImageBase),
                    NtHeader->OptionalHeader.SizeOfImage, 0x3000, PAGE_EXECUTE_READWRITE);

                    if (WriteProcessMemory(PI.hProcess, pImageBase, Image, NtHeader->OptionalHeader.SizeOfHeaders, NULL))
                    {
                        for (count = 0; count < NtHeader->FileHeader.NumberOfSections; count++)
                        {
                            SectionHeader = PIMAGE_SECTION_HEADER(DWORD(Image) + DOSHeader->e_lfanew + 248 + (count * 40));

                            if (WriteProcessMemory(PI.hProcess, LPVOID(DWORD(pImageBase) + SectionHeader->VirtualAddress),
                                LPVOID(DWORD(Image) + SectionHeader->PointerToRawData), SectionHeader->SizeOfRawData, 0))
                            {
                                cout << "Write process memory in FOR statement. Success";
                            }
                            else cout << "Write process memory in FOR statement. Failed";
                        }

                        if (WriteProcessMemory(PI.hProcess, LPVOID(CTX->Ebx + 8),
                            LPVOID(&NtHeader->OptionalHeader.ImageBase), 4, 0))
                        {

                            CTX->Eax = DWORD(pImageBase) + NtHeader->OptionalHeader.AddressOfEntryPoint;
                            if (SetThreadContext(PI.hThread, LPCONTEXT(CTX)))
                            {
                                if (ResumeThread(PI.hThread))
                                {
                                cout << "Resume thread: Success";
                                }
                                else cout << "Resume thread: Failed";
                            }
                            else cout << "Set thread context: Failed";

                        }
                        else cout << "Write process memory step 2: Failed";
                    }
                    else cout << "Write process memory step 1: Failed";
                }
                else cout << "Read process memory: Failed";
            }
            else cout << "Get thread context: Failed";
        }
        else cout << "Create process: Failed";
    }
    else cout << "Get module file name: Failed";
    return 0;
}

警告消息:

Severity Code Description Project File Line Suppression State
Warning C6011 Dereferencing NULL pointer 'CTX'.
Line 39

Severity Code Description Project File Line Suppression State
Warning C6387 'CTX' could be '0': this does not adhere to the specification for the function 'GetThreadContext'. See line 39 for an earlier location where this can occur
Line 41

Severity Code Description Project File Line Suppression State
Warning C6387 'pImageBase' could be '0': this does not adhere to the specification for the function 'WriteProcessMemory'.
Line 48

Severity Code Description Project File Line Suppression State
Warning C6387 'CTX' could be '0': this does not adhere to the specification for the function 'SetThreadContext'. See line 39 for an earlier location where this can occur
Line 62

您在计算 NtHeader 指针时出错,这会导致在您尝试访问 NtHeader->Signature 时出现 denied access。你的指针应该这样计算:

NtHeader = (PIMAGE_NT_HEADERS) ((u_char*)DOSHeader + DOSHeader->e_lfanew);

我通过在 Linker/Advanced 选项选项卡中将随机基地址设置为否解决了这个问题。

然后我将 NtUnmapViewofSection 添加到我的代码中

*(DWORD_PTR*)&pNtUnmapViewOfSection = (DWORD_PTR)GetProcAddress(GetModuleHandleW(L"NTDLL.dll"), "NtUnmapViewOfSection");