如何在C++程序中可靠读取Chrome进程内存中的坐标值?
自动定位Chrome内存中固定结尾的动态坐标地址方案
核心问题拆解
你观察到的地址结尾固定(如80209B74)、前缀动态变化的现象,本质是目标地址 = 动态基址 + 固定偏移。这里的动态基址并非Chrome主进程的模块基址,而是游戏所在的Chrome渲染进程中某块动态分配内存区域的起始地址。之前获取的主进程基址7FF72ACB0000和目标地址不在同一进程地址空间,所以完全无关。
具体解决步骤
1. 定位正确的Chrome进程
Chrome采用多进程架构,游戏运行在渲染进程(而非主进程)中。你需要:
- 打开任务管理器,找到对应游戏网页的Chrome渲染进程(通常命令行包含
--type=renderer且带有游戏URL); - 在C++代码中,可通过枚举进程窗口标题、解析进程命令行参数来自动识别目标渲染进程。
2. 用Cheat Engine获取多级指针
要自动计算动态基址,需找到基于模块基址的多级指针链:
- 附加Cheat Engine到目标渲染进程,找到当前X坐标的内存地址;
- 右键该地址,选择「找出是什么访问了这个地址」,操作游戏让X坐标变化,记录访问指令(如
mov eax,[rax+0x80209B74]); - 对指令中的寄存器(如
rax)对应的地址,重复「找出是什么访问了它」,直到找到一个基于chrome.dll模块基址的指针(如chrome.dll+0x123456); - 最终得到的指针链结构类似:
chrome.dll基址 + 偏移1 → 一级指针 + 偏移2 → 二级指针 + 固定偏移(0x80209B74)= 目标地址。
3. 绕过Chrome沙箱限制
Chrome默认开启沙箱,阻止外部进程读取渲染进程内存,需二选一处理:
- 临时关闭沙箱:启动Chrome时添加参数
--no-sandbox(注意会降低安全性,仅用于测试); - 申请调试权限:在C++代码中调用
AdjustTokenPrivileges开启SE_DEBUG_NAME权限,获得读取目标进程内存的权限。
4. C++代码实现自动定位
基于获取的指针链,编写代码自动计算目标地址:
#include <windows.h> #include <tlhelp32.h> #include <stdio.h> // 辅助函数:根据进程ID获取chrome.dll模块基址 DWORD64 GetChromeModuleBase(DWORD dwProcessId) { HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, dwProcessId); if (hSnapshot == INVALID_HANDLE_VALUE) return 0; MODULEENTRY32 me32; me32.dwSize = sizeof(MODULEENTRY32); if (!Module32First(hSnapshot, &me32)) { CloseHandle(hSnapshot); return 0; } DWORD64 baseAddr = 0; do { if (_wcsicmp(me32.szModule, L"chrome.dll") == 0) { baseAddr = (DWORD64)me32.modBaseAddr; break; } } while (Module32Next(hSnapshot, &me32)); CloseHandle(hSnapshot); return baseAddr; } int main() { // 替换为目标渲染进程ID,或通过代码自动枚举获取 DWORD dwProcessId = 12345; HANDLE hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, dwProcessId); if (!hProcess) return 1; // 获取chrome.dll的基址 DWORD64 chromeBase = GetChromeModuleBase(dwProcessId); if (!chromeBase) { CloseHandle(hProcess); return 1; } // 示例多级指针链:需替换为你实际找到的偏移值 DWORD64 ptr1; ReadProcessMemory(hProcess, (LPCVOID)(chromeBase + 0xABCDEF), &ptr1, sizeof(ptr1), NULL); DWORD64 ptr2; ReadProcessMemory(hProcess, (LPCVOID)(ptr1 + 0x1234), &ptr2, sizeof(ptr2), NULL); DWORD64 targetAddr = ptr2 + 0x80209B74; // 读取X坐标值 int xCoord; ReadProcessMemory(hProcess, (LPCVOID)targetAddr, &xCoord, sizeof(xCoord), NULL); printf("X坐标:%d\n", xCoord); CloseHandle(hProcess); return 0; }
对已尝试方法的补充说明
- 枚举地址:之前枚举的是主进程模块,需改为枚举渲染进程的
chrome.dll模块; - 禁用ASLR:无需禁用,多级指针基于模块基址+偏移,即使ASLR开启,模块基址变化后仍能通过偏移计算正确地址;
- Cheat Engine找指针:需找到基于模块基址的多级指针链,而非直接的静态地址,这样才能适配每次启动的动态基址变化。
内容的提问来源于stack exchange,提问作者fragment_me
相关产品推荐
相关产品推荐

