DLL注入游戏后访问内存触发0xc0000005访问违规该如何解决?
崩溃核心原因
- 64位地址截断:目标Unity IL2CPP游戏为64位程序时,模块基地址是8字节长度的64位指针,你使用仅支持32位的
DWORD类型存储lpBaseOfDll,直接截断了地址高位,最终得到的base是无效内存地址,读取时触发访问违规0xc0000005。 - 架构不匹配:如果你的DLL编译为32位版本,注入64位游戏进程时也会出现内存地址解析错误,触发同类崩溃。
修复方案
- 替换地址存储类型:将所有存储内存地址、模块长度的变量类型替换为适配跨架构的
uintptr_t,64位环境下也可直接使用DWORD64。 - 统一编译架构:确认DLL的编译架构和目标游戏完全一致,64位游戏编译x64版本DLL,32位游戏编译x86版本DLL。
- 可选权限校验:读取内存前调用
VirtualQuery校验目标地址的可读权限,避免访问无权限的内存段。
修复后核心代码示例
#include <cstdint> // 引入uintptr_t头文件 class SigScan { public: MODULEINFO GetModuleInfo(const char *szModule) { MODULEINFO modinfo = { 0 }; HMODULE hModule = GetModuleHandleA(szModule); if (hModule == nullptr) return modinfo; GetModuleInformation(GetCurrentProcess(), hModule, &modinfo, sizeof(MODULEINFO)); return modinfo; } uintptr_t FindPattern(const char *module, const char *pattern, const char *mask) { MODULEINFO mInfo = GetModuleInfo(module); // 用uintptr_t存储基地址和大小,避免截断 uintptr_t base = reinterpret_cast<uintptr_t>(mInfo.lpBaseOfDll); size_t size = static_cast<size_t>(mInfo.SizeOfImage); size_t patternLength = strlen(mask); // 测试读取,此时地址有效不会崩溃 char test = *reinterpret_cast<char*>(base); // 后续特征码扫描逻辑可正常实现 // TODO: 实现扫描逻辑 return 0; } };
内容的提问来源于stack exchange,提问作者jjthompson
相关产品推荐
相关产品推荐

