Нахождение базового адреса после создания приостановленного процесса

Я пытаюсь узнать, как сделать процесс выдавливания / замены (ради обучения). Я создал 32-битный процесс в подвешенном состоянии, после чего мне нужен базовый адрес этого процесса, чтобы впоследствии отобразить его из памяти и заменить другим.

Из моего исследования я могу получить его от PEB процесса, который включает этот адрес. также из того, что я понял, PEB всегда находится в регистре ebx, а точка входа находится в регистре eax.

ОДНАКО, когда я получаю контекст для основного потока (который содержит содержимое регистров), все становится равным нулю, что не имеет смысла для меня, но это не дает сбоя.

ВТОРАЯ ПРОБЛЕМА. когда я читаю память процесса, я получаю ошибку 299 (12B), которая, как я понимаю, возникает при попытке прочитать память 64-битной памяти из 32-битной (но помните, что я запускаю 32-битный процесс).

#include <Windows.h>
#include <tchar.h>
#include <stdio.h>

void end_program(LPPROCESS_INFORMATION pinfo, LPSTARTUPINFO stinfo)
{
    TerminateProcess(pinfo->hProcess, 1);
    CloseHandle(pinfo->hProcess);
    CloseHandle(pinfo->hThread);
    CloseHandle(stinfo->hStdError);
    CloseHandle(stinfo->hStdInput);
    CloseHandle(stinfo->hStdOutput);
    system("pause");
}

void main()
{
    // Create process suspended
    PROCESS_INFORMATION process_info;
    STARTUPINFO start_info;
    ZeroMemory(&process_info, sizeof(process_info));
    ZeroMemory(&start_info, sizeof(start_info));
    TCHAR path[100] = TEXT("C:\\Windows\\SysWOW64\\svchost.exe");
    if (!CreateProcess(NULL, path, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &start_info, &process_info))
    {
        printf("Failed creating process: error 0x%p", GetLastError());
        return;
    }
    printf("PID: %i Handle: 0x%p\r\n", process_info.dwProcessId, process_info.hProcess);

    // Get context of thread
    CONTEXT context;
    ZeroMemory(&context, sizeof(context));
    if (!GetThreadContext(process_info.hThread, &context))
    {
        printf("Failed getting context: error 0x%p\r\n", GetLastError());
        end_program(&process_info, &start_info);
        return;
    }
    printf("Context recieved!\r\n");

    // Get base address
    PVOID base_address;
    ZeroMemory(&base_address, sizeof(base_address));
    if (!ReadProcessMemory(process_info.hProcess, (BYTE)(context.Ebx + 8), &base_address, sizeof(PVOID), NULL))
    {
        printf("Error reading file: error 0x%p\r\n", GetLastError());
        end_program(&process_info, &start_info);
        return;
    }

    // Bugs that haven't been uncovered yet goes here




    // End of program
    end_program(&process_info, &start_info);
}

Примечание 1: исследования показали, что PEB со смещением в 8 байтов является базовым адресом.

примечание 2: попытался сделать снимок всего процесса, но та же ошибка, также попробовал enumprocessmodules, такая же ошибка происходит.

примечание 3: все, что я нашел в сети, предназначено для нахождения базового адреса работающего процесса, который я попробовал и успешно выполнил, но, поскольку ни один модуль не загружен в приостановленном состоянии (как это видно в диспетчере задач, так как нет имени для процесса, может быть неправильно) хотя), это не работает для меня.

примечание 4: я также новичок в кодировании на C, так что извините, если что-то выглядит странно.

любая помощь будет с удовольствием оценена. если у вас есть другие способы получить базовый адрес, я хотел бы услышать. извините, если код немного грязный, или если я не был понятен. Я сделаю все возможное, чтобы объяснить...

забыл добавить: моя система Windows 10 64bit

Редактировать: Исправлена ​​проблема. необходимо сделать context.ContextFlags=CONTEXT_INTEGER. это позволило мне читать. также не удалось прочитать память readprocess, потому что я дал неверный адрес для чтения (в основном 0+8=8), который, как я полагаю, был для 64-битного процесса

0 ответов

Вы никогда не устанавливаете context.ContextFlags, вы должны установить его в CONTEXT_INTEGER перед вызовом GetThreadContext().

Вот пример кода:

#if defined(_WIN64)
    WOW64_CONTEXT context;
    memset(&context, 0, sizeof(WOW64_CONTEXT));
    context.ContextFlags = CONTEXT_INTEGER;
    Wow64GetThreadContext(pi.hThread, &context);
#else   
    CONTEXT context;
    memset(&context, 0, sizeof(CONTEXT));
    context.ContextFlags = CONTEXT_INTEGER;
    GetThreadContext(pi.hThread, &context);
#endif

Взято из отличной реализации runpe от hasherezade

Другие вопросы по тегам