获取进程的基地址

我想访问一个进程的某个地址。 但为此,我需要首先获取进程的基地址。 我正在使用一个工具,看看我是否真的做对了。 该工具显示我需要以下内容: "app.exe"+0x011F9B08 = 0x119F8300

我以为我可以通过OpenProcess()获得进程的基地址,但是这给了我: 0x0000005c作为结果。 我不认为这是对的? 至less,不是我所需要的。

我认为我需要的基地址是: 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; } } 

我怎样才能得到我打开过程的基地址?

如果你想获得另一个进程地址空间内的虚拟地址,你可以这样做:

  1. 使用OpenProcess打开进程 – 如果成功,则返回的值是进程的句柄,它只是内核用来标识内核对象的不透明标记。 它的确切整数值(在你的情况下为0x5c)对用户空间程序没有任何意义,除了区别于其他句柄和无效句柄。
  2. 调用GetProcessImageFileName以获取进程的主要可执行模块的名称。
  3. 使用EnumProcessmodulees枚举目标进程中所有模块的列表。
  4. 对于每个模块,调用GetmoduleeFileNameEx来获取文件名,并将其与可执行文件的文件名进行比较。
  5. 当您找到可执行文件的模块时,调用GetmoduleeInformation来获取可执行文件的原始入口点。

这将为您提供虚拟地址,但是由于它没有映射到当前进程的地址空间,因此您可以使用这个虚拟地址。

我想详细阐述@Adam Rosenfield的回答。 我将在这里以英雄联盟为例。


为了打开进程(获取句柄),我们需要它的PID(进程ID)。 我们可以通过窗口句柄(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 modulee = Getmodulee(); DWORD BaseAddress = (DWORD)modulee; 

Getmodulee函数

 HMODULE Getmodulee() { HMODULE hMods[1024]; HANDLE pHandle = GetHandle(); DWORD cbNeeded; unsigned int i; if (EnumProcessmodulees(pHandle, hMods, sizeof(hMods), &cbNeeded)) { for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) { TCHAR szModName[MAX_PATH]; if (GetmoduleeFileNameEx(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; } 

就我个人而言,我喜欢编写2个独立的函数,一个用于获取句柄,另一个用于获取模块。

我们走了,我们已经成功地获得了一个国外进程的基地址。