Я хочу получить доступ к определенному адресу процесса. Но для этого мне нужно сначала получить базовый адрес процесса. Я использую инструмент, чтобы проверить, действительно ли я делаю это правильно. Инструмент показывает, что мне нужно следующее: "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;
}
}
Как я могу получить базовый адрес процесса, который я открыл?
Если вы хотите получить виртуальный адрес в другом адресном пространстве процесса, вы можете сделать это так:
OpenProcess
- в случае успеха возвращаемое значение является дескриптором процесса, который является просто непрозрачным токеном используемый ядром для идентификации объекта ядра. Его точное целочисленное значение (0x5c в вашем случае) не имеет смысла для программ пользовательского пространства, кроме как отличать его от других дескрипторов и недействительных дескрипторов.GetProcessImageFileName
, чтобы получить имя основного исполняемого модуля процесса.EnumProcessModules
, чтобы перечислить список всех модулей в целевом процессе.GetModuleFileNameEx
, чтобы получить имя файла, и сравните его с исполняемым именем файла.GetModuleInformation
, чтобы получить исходную точку входа исполняемого файла.Это даст вам виртуальный адрес, но с ним вы не сможете многое сделать, поскольку оно не отображается в ваше текущее адресное пространство процесса.
HMODULE
одинаковы, но точка входа модуля (функция запуска CRT, которая вызывает WinMain()
или DllMain()
) отличается от базового адреса.
Я хотел немного рассказать о ответе @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;
}
как для меня лично мне нравится писать две отдельные функции для получения дескриптора и один для получения модуля.
Там мы идем, мы успешно получили базовый адрес иностранного процесса.