使用ReadProcessMemory读取指针指向整数时程序崩溃问题求助
解决ReadProcessMemory读取外部进程指针值崩溃的问题
问题根源
你直接解引用*intRead导致崩溃的核心原因是进程虚拟地址空间隔离:
- 每个Windows进程都有独立的虚拟地址空间,你通过
ReadProcessMemory读取到的intRead值,是目标进程中的虚拟地址,这个地址在当前进程的地址空间里是无效的(要么未映射,要么属于其他内存区域),直接解引用必然触发内存访问错误,导致程序崩溃。 - 你的代码错误地把目标进程的地址当成当前进程的指针来使用,这是跨进程内存读取的典型误区。
正确实现思路
跨进程读取指针指向的数值,不能直接解引用,必须通过ReadProcessMemory在目标进程的地址空间中完成读取:
- 读取目标进程中指针地址存储的内容(即下一级指针的地址)
- 以这个内容为新的地址,再次调用
ReadProcessMemory读取最终的整数数值 - 如果是多级指针链(比如基址 -> 偏移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", ¤tAddress); 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
相关产品推荐
相关产品推荐

