18

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?

m0skit0
  • 25,268
  • 11
  • 79
  • 127
Vivendi
  • 20,047
  • 25
  • 121
  • 196
  • 4
    What precisely do you mean by "the base address of a process"? – NPE Jan 22 '13 at 20:17
  • 4
    Perhaps you need to learn about [virtual memory](http://en.wikipedia.org/wiki/Virtual_memory) – Fred Larson Jan 22 '13 at 20:20
  • Are you trying to read the memory of _another_ running process and need to know the base address at which the image was mapped in that process's virtual address space? – Peter Ruderman Jan 22 '13 at 20:24
  • @PeterRuderman That is what i mean – Vivendi Jan 22 '13 at 20:43
  • 1
    You can't just access another process's memory directly. You must use [`ReadProcessMemory()`](http://msdn.microsoft.com/en-us/library/ms680553.aspx) instead. Its `hProcess` parameter can be the `HANDLE` you obtained from `OpenProcess()`. Its `lpBaseAddress` parameter is relative to the process being accessed, so you don't need to calculate it, just hard-code it if you know what it is, eg: `hProcess = OpenProcess(...); ReadProcessMemory(hProcess, (void*)0x011F9B08, ...);`. – Remy Lebeau Jan 22 '13 at 21:54

2 Answers2

20

If you want to get the virtual address within the other process's address space, you can do that like so:

  1. Open the process using OpenProcess -- if successful, the value returned is a handle to the process, which is just an opaque token used by the kernel to identify a kernel object. Its exact integer value (0x5c in your case) has no meaning to userspace programs, other than to distinguish it from other handles and invalid handles.
  2. Call GetProcessImageFileName to get the name of the main executable module of the process.
  3. Use EnumProcessModules to enumerate the list of all modules in the target process.
  4. For each module, call GetModuleFileNameEx to get the filename, and compare it with the executable's filename.
  5. When you've found the executable's module, call GetModuleInformation to get the raw entry point of the executable.

This will give you the virtual address, but there's not a whole lot you can do with it since it's not mapped into your current process's address space.

Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589
  • 4
    Presumably this would be followed up by a call to ReadProcessMemory or some such. Also, I don't believe the call to GetModuleInformation is necessary. The module base address and its HMODULE are one and the same. – Peter Ruderman Jan 22 '13 at 20:37
  • 3
    @Peter: Yes, it is necessary -- the base address and the `HMODULE` are the same, but the module's entry point (the CRT startup function which calls `WinMain()` or `DllMain()`) is different from the base address. – Adam Rosenfield Jan 22 '13 at 22:44
  • 1
    That's true, and it's certainly convenient to call GetModuleInformation() if that's the case (though the OP didn't ask for the entry point). – Peter Ruderman Jan 22 '13 at 22:59
  • But how to find the base address?? – VityaSchel Apr 02 '22 at 12:58
11

I wanted to elaborate a bit on @Adam Rosenfield's answer. I will use League of Legends as an example here.


In order to open the process (Getting a handle) we need it's PID (Process ID). We can do that via a window handle (HWND) because usually the title of the window is known

//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);

Now that we are able to get a handle to the process let's continue

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

The GetModule function

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;
}

as for me personally I like to write 2 separate functions one for getting a handle and one for getting the module.

There we go, we have successfully gotten the base address of a foreign process.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 5
    anyone else copypasting so you don't have to write it for the 100th time, be careful as he for some weird reason closes the handle upon finding it successfully. also for some equally weird reason doesn't close it upon failing – TrisT Nov 28 '20 at 01:23