You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用ReadProcessMemory读取指针指向整数时程序崩溃问题求助

解决ReadProcessMemory读取外部进程指针值崩溃的问题

问题根源

你直接解引用*intRead导致崩溃的核心原因是进程虚拟地址空间隔离:

  • 每个Windows进程都有独立的虚拟地址空间,你通过ReadProcessMemory读取到的intRead值,是目标进程中的虚拟地址,这个地址在当前进程的地址空间里是无效的(要么未映射,要么属于其他内存区域),直接解引用必然触发内存访问错误,导致程序崩溃。
  • 你的代码错误地把目标进程的地址当成当前进程的指针来使用,这是跨进程内存读取的典型误区。

正确实现思路

跨进程读取指针指向的数值,不能直接解引用,必须通过ReadProcessMemory在目标进程的地址空间中完成读取:

  1. 读取目标进程中指针地址存储的内容(即下一级指针的地址)
  2. 以这个内容为新的地址,再次调用ReadProcessMemory读取最终的整数数值
  3. 如果是多级指针链(比如基址 -> 偏移1 -> 偏移2 -> 目标值),需要依次遍历每一级,重复上述步骤

修正后的代码

DWORD pid;
printf("Enter the process id: ");
scanf("%d", &pid);
printf("\n");

HANDLE hProcess = OpenProcess(PROCESS_VM_READ, FALSE, pid);
if(hProcess == NULL) {
    printf("OpenProcess Failed GetLastError: %d\n", GetLastError());
    getchar();
    return pressToClose(EXIT_FAILURE);
}

uintptr_t currentAddress = 0x00000000;
printf("Enter the pointer address (e.g. 0x590844): ");
scanf("%x", &currentAddress);
printf("\n");

// 第一步:读取指针存储的下一级地址
uintptr_t nextAddress;
BOOL rpmReturn = ReadProcessMemory(hProcess, (LPCVOID)currentAddress, &nextAddress, sizeof(uintptr_t), NULL);
if (rpmReturn == FALSE) {
    printf("ReadProcessMemory failed to get pointer. GetLastError = %d\n", GetLastError());
    CloseHandle(hProcess);
    getchar();
    return pressToClose(EXIT_FAILURE);
}
printf("Read pointer value (next address): 0x%X\n", nextAddress);

// 第二步:读取最终的整数数值(比如弹药数)
int ammoValue;
rpmReturn = ReadProcessMemory(hProcess, (LPCVOID)nextAddress, &ammoValue, sizeof(int), NULL);
if (rpmReturn == FALSE) {
    printf("ReadProcessMemory failed to get ammo. GetLastError = %d\n", GetLastError());
    CloseHandle(hProcess);
    getchar();
    return pressToClose(EXIT_FAILURE);
}

printf("Final ammo value: %d\n", ammoValue);

CloseHandle(hProcess);
getchar();
return pressToClose(EXIT_SUCCESS);

多级指针链的处理方法

如果你的指针链是多级的(比如基址 + 偏移A -> 中间指针 + 偏移B -> 目标值),可以用循环来遍历:

// 示例:指针链为 [基址] -> +0x10 -> +0x20 -> 目标值
uintptr_t baseAddress = 0xXXXXXXX;
uintptr_t offsets[] = {0x10, 0x20};
uintptr_t currentAddr = baseAddress;

// 遍历每一级指针
for (int i = 0; i < sizeof(offsets)/sizeof(offsets[0]); i++) {
    uintptr_t tempAddr;
    if (!ReadProcessMemory(hProcess, (LPCVOID)currentAddr, &tempAddr, sizeof(uintptr_t), NULL)) {
        printf("Failed to read level %d pointer. Error: %d\n", i+1, GetLastError());
        CloseHandle(hProcess);
        return pressToClose(EXIT_FAILURE);
    }
    currentAddr = tempAddr + offsets[i];
}

// 读取最终数值
int targetValue;
if (ReadProcessMemory(hProcess, (LPCVOID)currentAddr, &targetValue, sizeof(int), NULL)) {
    printf("Target value: %d\n", targetValue);
} else {
    printf("Failed to read target value. Error: %d\n", GetLastError());
}

测试验证

当你输入指针地址0x590844时,代码会先读取该地址存储的00710008,然后再读取00710008地址中的整数,就能正确获取弹药数,不会再崩溃。

内容的提问来源于stack exchange,提问作者IDontWantToMakeAnotherAccount

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 22:10:35