Получить базовый адрес процесса

8

Я хочу получить доступ к определенному адресу процесса. Но для этого мне нужно сначала получить базовый адрес процесса. Я использую инструмент, чтобы проверить, действительно ли я делаю это правильно. Инструмент показывает, что мне нужно следующее: "app.exe"+0x011F9B08 = 0x119F8300

Я думал, что могу получить базовый адрес процесса через OpenProcess(), но это дает мне: 0x0000005c в результате. Я не думаю, что это правильно? По крайней мере, не то, что мне нужно.

Я думаю, что мне нужен базовый адрес: 0x119F8300 - 0x011F9B08 = 0x107FE7F8 <-- base?

Это мой код:

hWindow = FindWindow(NULL, lpWindowName);
if(hWindow)
{
    GetWindowThreadProcessId(hWindow, &dwProcId);
    if(dwProcId != 0)
    {
            // hProcHandle -> 0x0000005c
            hProcHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcId);
    }
    else
    {
        return 0;
    }
}

Как я могу получить базовый адрес процесса, который я открыл?

  • 3
    Что именно вы подразумеваете под «базовым адресом процесса»?
  • 3
    Возможно, вам нужно узнать о виртуальной памяти
Показать ещё 3 комментария
Теги:
pointers

2 ответа

5
Лучший ответ

Если вы хотите получить виртуальный адрес в другом адресном пространстве процесса, вы можете сделать это так:

  • Откройте процесс, используя OpenProcess - в случае успеха возвращаемое значение является дескриптором процесса, который является просто непрозрачным токеном используемый ядром для идентификации объекта ядра. Его точное целочисленное значение (0x5c в вашем случае) не имеет смысла для программ пользовательского пространства, кроме как отличать его от других дескрипторов и недействительных дескрипторов.
  • Вызовите GetProcessImageFileName, чтобы получить имя основного исполняемого модуля процесса.
  • Используйте EnumProcessModules, чтобы перечислить список всех модулей в целевом процессе.
  • Для каждого модуля вызовите GetModuleFileNameEx, чтобы получить имя файла, и сравните его с исполняемым именем файла.
  • Когда вы нашли исполняемый модуль, вызовите GetModuleInformation, чтобы получить исходную точку входа исполняемого файла.

Это даст вам виртуальный адрес, но с ним вы не сможете многое сделать, поскольку оно не отображается в ваше текущее адресное пространство процесса.

  • 1
    Предположительно, за этим последует вызов ReadProcessMemory или чего-то подобного. Кроме того, я не считаю, что вызов GetModuleInformation необходим. Базовый адрес модуля и его HMODULE - это одно и то же.
  • 1
    @Peter: Да, это необходимо - базовый адрес и HMODULE одинаковы, но точка входа модуля (функция запуска CRT, которая вызывает WinMain() или DllMain() ) отличается от базового адреса.
Показать ещё 1 комментарий
2

Я хотел немного рассказать о ответе @Adam Rosenfield. Я буду использовать Лигу Легенд в качестве примера здесь.


Чтобы открыть процесс (получение дескриптора), нам понадобится PID (идентификатор процесса). Мы можем сделать это с помощью дескриптора окна (HWND), потому что обычно известно название окна

//You will need to change this the name of the window of the foreign process
HWND WindowHandle = FindWindow(nullptr, L"League of Legends (TM) Client");
DWORD PID;
GetWindowThreadProcessId(WindowHandle, &PID);
PVOID hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, 0, PID);

Теперь, когда мы можем получить дескриптор процесса, продолжаем

HMODULE Module = GetModule();
DWORD BaseAddress = (DWORD)Module;

Функция GetModule

HMODULE GetModule()
{
    HMODULE hMods[1024];
    HANDLE pHandle = GetHandle();
    DWORD cbNeeded;
    unsigned int i;

    if (EnumProcessModules(pHandle, hMods, sizeof(hMods), &cbNeeded))
        {
        for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++)
        {
            TCHAR szModName[MAX_PATH];
            if (GetModuleFileNameEx(pHandle, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR)))
            {
                wstring wstrModName = szModName;
                //you will need to change this to the name of the exe of the foreign process
                wstring wstrModContain = L"League of Legends.exe"; 
                if (wstrModName.find(wstrModContain) != string::npos)
                {
                    CloseHandle(pHandle);
                    return hMods[i];
                }
            }
        }
    }
    return nullptr;
}

как для меня лично мне нравится писать две отдельные функции для получения дескриптора и один для получения модуля.

Там мы идем, мы успешно получили базовый адрес иностранного процесса.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню