c/c++ как я могу получить базовый адрес запущенного процесса .exe?

Я ищу метод/функцию, которую я могу использовать для получения базового адреса "program.exe"+03262C08 -> B4895A0. Этот адрес взят из Cheat Engine, и базовый адрес был найден с помощью сканера Pointer. В сканере указателя я могу нажать show module list, и есть адрес program.exe, начинающийся с адреса 00400000 program.exe. Сканер указателя был отсканирован для адреса 09c3000 (адрес, который я хочу получить после базового адреса + много смещений [конечный адрес]). Этот адрес является базовым для определенного объекта, но я не могу добраться до адреса. Я могу получить только базовый адрес exe-файла по адресу 00400000. Я пытаюсь добавить смещения от указателя 03262C08 (и других), но я все еще не могу добраться до адреса. Я не могу использовать функцию FindWindow(). Потому что имя программы будет меняться и придерживаться его будет лишним. Я использую OpenProcess(), EnumProcessModulesEx(), GetModuleFileNameEx() функции. Я пробовал и другие, например GetModuleInformation(),..., с тем же результатом. GetModuleHandle() завершился с результатом 0x126 [ERROR_MOD_NOT_FOUND]. Я использую 64-битную ОС и пытаюсь получить базовый адрес другого процесса. Я вижу все процессы на локальной машине и модули процесса "программы".

if (!K32EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) {
    return 1;
}

cProcesses = cbNeeded / sizeof(DWORD);

cout << setw(15) << left << "Process ID" << setw(10) << left << "Modules";
cout << setw(30) << left << "Process Name" << endl;
for (i = 0; i < cProcesses; i++) {
    if (aProcesses[i] != 0) {
        ProcessView::GetProccesses(aProcesses[i], modules, sizeModules, &cModules, &hCurrProcess);
        if (hCurrProcess != NULL) {
            cout << endl << setw(15) << left << aProcesses[i] << setw(10) << left << cModules;
            ProcessView::PrintModuleName(hCurrProcess, modules);
            CloseHandle(hCurrProcess);
        }

    }
}
ProcessView::GetProccesses(cProcesses, modules, sizeModules, &cModules, &hCurrProcess);

system("cls");
ProcessView::PrintModuleNameAll(hCurrProcess, modules, cModules);

Я добавил здесь определение функции в примере из файла ProcessView.h, который я создал.

static void GetProccesses(_In_ DWORD processID, _Inout_ HMODULE ahModules[], _In_ int sizeModules, _Out_ DWORD* cModules, _Out_ HANDLE* hProcess);
static void PrintModuleName(_In_ HANDLE processID, _In_ HMODULE* modules);
static void PrintModuleNameAll(_In_ HANDLE hProcess, _In_ HMODULE * modules, _In_ DWORD cModules);

person Emil Mein    schedule 19.10.2017    source источник
comment
Дубликат? или вам просто нужны запущенные процессы?   -  person Barmak Shemirani    schedule 19.10.2017
comment
Нет. Я пытаюсь прочитать память процесса ReadProcessMemory() с определенного адреса через исполняемый файл, работающий как процесс, а не через функции FindWindow().   -  person Emil Mein    schedule 19.10.2017
comment
Вы уверены, что рассматриваемый адрес принадлежит exe (не dll, не куче и т. д.)?   -  person KonstantinL    schedule 19.10.2017
comment
На самом деле я не уверен в значении я все еще не могу добраться до адреса. Не могли бы вы перефразировать это?   -  person KonstantinL    schedule 19.10.2017
comment
"program.exe"+03262C08 -> B4895A0 в чит-движке (базовый адрес). B4895A0 я хочу получить, но я получаю только базовый адрес исполняемого файла на 0x00400000. Этот 0x00400000 я могу пройти через код и даже могу найти его в CE (полный путь после сканирования указателя: щелкните правой кнопкой мыши адрес -> показать список модулей). Но я не могу связаться с этим B4895A0 с 0x400000 + 0x3262C08 !-> 0xB4895A0.   -  person Emil Mein    schedule 19.10.2017
comment
Цифры выглядят неправильно. Модули всегда выровнены по крайней мере по страницам в памяти, т.е. кратны 0x1000. Вы не можете добавить значение, оканчивающееся на 0xC08, к базовому адресу и получить конечное значение с другими значениями в 3 младших значащих шестнадцатеричных цифрах. Проблема, которую вы описали, не та проблема, которую вы хотите решить.   -  person IInspectable    schedule 19.10.2017
comment
Возможный дубликат Как получить начальный /базовый адрес процесса в C++?   -  person GuidedHacking    schedule 05.02.2018


Ответы (2)


Windows использует рандомизацию адресного пространства уже около десяти лет, но модульная база в EXE-файлах намного старше. Просто игнорируйте это, теперь это бессмысленно.

И не забывайте: у каждого процесса есть свое адресное пространство. Указатель в одном процессе не имеет смысла в другом.

person MSalters    schedule 19.10.2017

Чтобы использовать ReadProcessMemory или WriteProcessMemory по адресу, найденному через цепочку указателей на процесс и динамически получать базовый адрес модуля во время выполнения, вам необходимо выполнить следующие шаги:

  • Найдите процесс с помощью ToolHelp32Snapshot
  • Найдите модуль с помощью ToolHelp32Snapsho
  • Получите дескриптор процесса с правильными разрешениями
  • Пройдите по цепочке указателей, разыменовывая и добавляя смещения
  • Затем вы можете вызвать ReadProcessMemory или WriteProcessMemory.
  • Вы должны запустить от имени администратора

В этом примере я буду использовать простой чит штурмового куба, который я сделал

#include <iostream>
#include <vector>
#include <Windows.h>
#include "proc.h"

int main()
{
    //Get ProcId of the target process
    DWORD procId = GetProcId(L"ac_client.exe");

    //Getmodulebaseaddress
    uintptr_t moduleBase = GetModuleBaseAddress(procId, L"ac_client.exe");

    //Get Handle to Process
    HANDLE hProcess = 0;
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, NULL, procId);

    //Resolve base address of the pointer chain
    uintptr_t dynamicPtrBaseAddr = moduleBase + 0x10f4f4;

    std::cout << "DynamicPtrBaseAddr = " << "0x" << std::hex << dynamicPtrBaseAddr << std::endl;

    //Resolve our ammo pointer chain
    std::vector<unsigned int> ammoOffsets = { 0x374, 0x14, 0x0 };
    uintptr_t ammoAddr = FindDMAAddy(hProcess, dynamicPtrBaseAddr, ammoOffsets);

    std::cout << "ammoAddr = " << "0x" << std::hex << ammoAddr << std::endl;

    //Read Ammo value
    int ammoValue = 0;

    ReadProcessMemory(hProcess, (BYTE*)ammoAddr, &ammoValue, sizeof(ammoValue), nullptr);
    std::cout << "Curent ammo = " << std::dec << ammoValue << std::endl;

    //Write to it
    int newAmmo = 1337;
    WriteProcessMemory(hProcess, (BYTE*)ammoAddr, &newAmmo, sizeof(newAmmo), nullptr);

    //Read out again
    ReadProcessMemory(hProcess, (BYTE*)ammoAddr, &ammoValue, sizeof(ammoValue), nullptr);

    std::cout << "New ammo = " << std::dec << ammoValue << std::endl;

    getchar();
    return 0;
}

Заголовочный файл proc.cpp:

DWORD GetProcId(const wchar_t* procName)
{
    DWORD procId = 0;
    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnap != INVALID_HANDLE_VALUE)
    {
        PROCESSENTRY32 procEntry;
        procEntry.dwSize = sizeof(procEntry);

        if (Process32First(hSnap, &procEntry))
        {
            do
            {
                if (!_wcsicmp(procEntry.szExeFile, procName))
                {
                    procId = procEntry.th32ProcessID;
                    break;
                }
            } while (Process32Next(hSnap, &procEntry));

        }
    }
    CloseHandle(hSnap);
    return procId;
}

uintptr_t GetModuleBaseAddress(DWORD procId, const wchar_t* modName)
{
    uintptr_t modBaseAddr = 0;
    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId);
    if (hSnap != INVALID_HANDLE_VALUE)
    {
        MODULEENTRY32 modEntry;
        modEntry.dwSize = sizeof(modEntry);
        if (Module32First(hSnap, &modEntry))
        {
            do
            {
                if (!_wcsicmp(modEntry.szModule, modName))
                {
                    modBaseAddr = (uintptr_t)modEntry.modBaseAddr;
                    break;
                }
            } while (Module32Next(hSnap, &modEntry));
        }
    }
    CloseHandle(hSnap);
    return modBaseAddr;
}

uintptr_t FindDMAAddy(HANDLE hProc, uintptr_t ptr, std::vector<unsigned int> offsets)
{
    uintptr_t addr = ptr;
    for (unsigned int i = 0; i < offsets.size(); ++i)
    {
        ReadProcessMemory(hProc, (BYTE*)addr, &addr, sizeof(addr), 0);
        addr += offsets[i];
    }
    return addr;
}
person GuidedHacking    schedule 12.11.2019