16

I want to access a certain address of a process. But for that i need to get the base address of the process first. I'm using a tool to see if i'm actually doing it right. The tool shows i need the following: "app.exe"+0x011F9B08 = 0x119F8300

I thought i could obtain the base address of a process through OpenProcess(), but that gives me: 0x0000005c as a result. I don't think that is right? Atleast, not what i need.

I think the base address i need is: 0x119F8300 - 0x011F9B08 = 0x107FE7F8 <-- base?

This is my code:

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

How can i get the base address of the process that i've opened?

4

2 回答 2

17

如果要在其他进程的地址空间中获取虚拟地址,可以这样做:

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

这将为您提供虚拟地址,但您无法使用它做很多事情,因为它没有映射到您当前进程的地址空间。

于 2013-01-22T20:34:10.680 回答
9

我想详细说明@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 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;
}

至于我个人,我喜欢编写 2 个单独的函数,一个用于获取句柄,一个用于获取模块。

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

于 2015-08-08T15:24:47.437 回答