简体   繁体   English

获取进程的基址

[英]Get base address of process

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 该工具显示我需要以下内容: "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. 我以为我可以通过OpenProcess()获取进程的基地址,但这给了我: 0x0000005c作为结果。 I don't think that is right? 我不认为这是对的吗? Atleast, not what i need. 至少,不是我需要的。

I think the base address i need is: 0x119F8300 - 0x011F9B08 = 0x107FE7F8 <-- base? 我认为我需要的基地址是: 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? 我怎样才能获得我打开过程的基地址?

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. 使用OpenProcess打开进程 - 如果成功,返回的值是进程的句柄,它只是内核用来标识内核对象的不透明标记。 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. 它的确切整数值(在你的情况下是0x5c)对用户空间程序没有意义,除了将它与其他句柄和无效句柄区分开来。
  2. Call GetProcessImageFileName to get the name of the main executable module of the process. 调用GetProcessImageFileName以获取进程的主可执行模块的名称。
  3. Use EnumProcessModules to enumerate the list of all modules in the target process. 使用EnumProcessModules枚举目标进程中所有模块的列表。
  4. For each module, call GetModuleFileNameEx to get the filename, and compare it with the executable's filename. 对于每个模块,调用GetModuleFileNameEx以获取文件名,并将其与可执行文件的文件名进行比较。
  5. When you've found the executable's module, call GetModuleInformation to get the raw entry point of the executable. 找到可执行文件的模块后,调用GetModuleInformation以获取可执行文件的原始入口点。

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. 这将为您提供虚拟地址,但由于它未映射到您当前进程的地址空间,因此您无法使用它。

I wanted to elaborate a bit on @Adam Rosenfield's answer. 我想详细说明一下@Adam Rosenfield的回答。 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). 为了打开过程(获取句柄),我们需要它的PID(进程ID)。 We can do that via a window handle (HWND) because usually the title of the window is known 我们可以通过窗口句柄(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);

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

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. 我们去了,我们已成功获得外国进程的基地址。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM