C++中十六进制地址相加后读取内存值的问题求助
解决十六进制地址相加异常的问题
嘿,刚接触C++就碰内存读写的问题很正常,我来帮你捋捋~
首先看你代码里的核心问题:直接把两个十六进制常量相加后强转成void*,这里大概率是整数类型的符号问题或者编译架构不匹配导致的异常,咱们一步步来解决:
可能的原因
- 有符号整数溢出风险:默认情况下,十六进制常量在MSVC里会被当作有符号
int处理。虽然你当前的两个值相加(0x37c90000 + 0xE29FE8 = 0x38AB9FE8)没超过32位有符号int的最大值,但如果后续偏移更大,就会触发溢出的未定义行为,直接导致地址计算错误。 - 编译架构不匹配:如果目标进程是64位,但你的程序编译成了32位,指针长度(32位vs64位)不匹配,地址计算肯定会出错。
修复方案
1. 使用指针专用的整数类型计算地址
用uintptr_t(定义在<cstdint>头文件中)来存储基地址和偏移,它是专门为指针设计的无符号整数类型,能适配32/64位平台,完全避免符号和溢出问题:
#include <cstdint> #include <iostream> #include <windows.h> // 确保包含Windows API头文件 // ... 你的其他代码,比如获取pHandle的部分 ... int number; uintptr_t base_addr = 0x37c90000; uintptr_t offset = 0xE29FE8; uintptr_t target_addr = base_addr + offset; // 用reinterpret_cast做指针转换,比C风格转换更安全 if (!ReadProcessMemory(pHandle, reinterpret_cast<void*>(target_addr), &number, sizeof(number), nullptr)) { // 检查读写失败的原因,方便调试 std::cerr << "内存读取失败!错误码:" << GetLastError() << std::endl; } else { std::cout << "读取到的值:" << number << ",目标地址:0x" << std::hex << target_addr << std::endl; }
2. 匹配编译架构
打开MSVC的项目属性:
- 进入「配置属性」→「常规」
- 把「平台工具集」改成和目标进程一致的架构(x86对应32位进程,x64对应64位进程)
3. 动态获取基地址(可选但推荐)
如果目标进程重启后基地址会变化(大部分程序都是这样),不要硬编码0x37c90000,可以用EnumProcessModules或GetModuleHandleEx来动态获取目标模块的基地址,避免地址失效。
额外提示
一定要检查ReadProcessMemory的返回值!很多时候不是地址计算错了,而是进程权限不够、地址无效或者目标进程已经退出,通过GetLastError()能快速定位问题。
内容的提问来源于stack exchange,提问作者Lmfaoown
相关产品推荐
相关产品推荐

