RunPE неисправность памяти - PullRequest
0 голосов
/ 10 марта 2020

Каждый раз, когда выполняется мой исполняемый файл, он работает 80% времени. Остальные 20% времени я получаю ошибку 0xc00000005 от Windows. Я считаю, что это может быть проблема с памятью, но я не уверен, как ее исправить. Я потратил слишком много времени, пытаясь понять, как я могу это исправить, поэтому я сейчас приеду сюда. Я использую Visual Studio.

Я отладил программу, и она перестала работать прямо здесь, в сценарии отладки с именем «Запись процесса памяти, шаг 1: сбой».

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;
}

Предупреждающие сообщения:

Код серьезности Описание Состояние подавления строки файла проекта
Предупреждение C6011 Разыменование нулевого указателя 'CTX'.
Строка 39

Код серьезности Описание Состояние подавления строки файла проекта
Предупреждение C6387 «CTX» может быть «0»: это не соответствует спецификации для функции «GetThreadContext». См. Строку 39 для более раннего местоположения, где это может произойти
Строка 41

Код серьезности Описание Состояние подавления строки файла проекта
Предупреждение C6387 «pImageBase» может иметь значение «0»: это не соответствует спецификация для функции 'WriteProcessMemory'.
Строка 48

Код серьезности Описание Состояние подавления строки файла проекта
Предупреждение C6387 'CTX' может быть '0': это не соответствует спецификации для функция 'SetThreadContext'. Смотрите строку 39 для более раннего местоположения, где это может произойти
Строка 62

Ответы [ 2 ]

0 голосов
/ 15 марта 2020

Я решил проблему, установив «Рандомизированный базовый адрес» на «Нет» на вкладке «Линкер / Дополнительные параметры».

Затем я добавил NtUnmapViewofSection в свой код

*(DWORD_PTR*)&pNtUnmapViewOfSection = (DWORD_PTR)GetProcAddress(GetModuleHandleW(L"NTDLL.dll"), "NtUnmapViewOfSection");
0 голосов
/ 10 марта 2020

У вас ошибка при вычислении указателя NtHeader, и это вызывает denied access при попытке доступа к NtHeader->Signature. Ваш указатель должен быть рассчитан так:

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