C++ 获取进程基地址
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14467229/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get base address of process
提问by Vivendi
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. I don't think that is right? Atleast, not what i need.
我以为我可以通过 获得进程的基地址OpenProcess()
,但这给了我:0x0000005c
结果。我不认为这是对的?至少,不是我需要的。
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?
如何获取我打开的进程的基地址?
采纳答案by Adam Rosenfield
If you want to get the virtual address within the other process's address space, you can do that like so:
如果你想在另一个进程的地址空间中获取虚拟地址,你可以这样做:
- 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. - Call
GetProcessImageFileName
to get the name of the main executable module of the process. - Use
EnumProcessModules
to enumerate the list of all modules in the target process. - For each module, call
GetModuleFileNameEx
to get the filename, and compare it with the executable's filename. - When you've found the executable's module, call
GetModuleInformation
to get the raw entry point of the executable.
- 打开进程使用
OpenProcess
-- 如果成功,返回的值是进程的句柄,它只是内核用来标识内核对象的不透明标记。它的确切整数值(在您的情况下为 0x5c)对用户空间程序没有意义,只是将其与其他句柄和无效句柄区分开来。 - 调用
GetProcessImageFileName
以获取进程的主要可执行模块的名称。 - 用
EnumProcessModules
枚举目标过程中的所有模块的列表。 - 对于每个模块,调用
GetModuleFileNameEx
以获取文件名,并将其与可执行文件的文件名进行比较。 - 找到可执行文件的模块后,调用
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.
这将为您提供虚拟地址,但您无法使用它做很多事情,因为它没有映射到您当前进程的地址空间。
回答by Adam Rosenfield
I wanted to elaborate a bit on @Adam Rosenfield's answer. I will use League of Legends as an example here.
我想详细说明@Adam Rosenfield 的回答。我将在这里以英雄联盟为例。
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
为了打开进程(获取句柄),我们需要它的 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);
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.
就我个人而言,我喜欢编写 2 个独立的函数,一个用于获取句柄,另一个用于获取模块。
There we go, we have successfully gotten the base address of a foreign process.
好了,我们已经成功获得了一个外部进程的基地址。