我有一个扫描内存的字节数组(XX?XX XX XX等)。
我的代码适用于Windows 7,但最终在Windows 10上获得ACCESS_VIOLATION,因为内存似乎与在Windows 7上的工作方式不同。
我的问题是我需要在GetModuleHandle(0)返回的地址之前开始扫描,因为我正在搜索的字节数组在游戏( 64位)加载时被加载到内存中
如何在游戏中启动内存或验证lpCurrentByte是否在内存中?
static DWORD64 ScanC(DWORD64 dwLength, std::string s) {
std::vector<PatternByte> p;
std::istringstream iss(s);
std::string w;
while (iss >> w) {
if (w.data()[0] == '?') { // Wildcard
p.push_back(PatternByte());
}
else if (w.length() == 2 && isxdigit(w.data()[0]) && isxdigit(w.data()[1])) { // Hex
p.push_back(PatternByte(w));
}
else {
return NULL;
}
}
for (DWORD64 i = 0; i < dwLength; i++) {
UINT8* lpCurrentByte = (UINT8*)(0x10000000 + i);
bool found = true;
for (size_t ps = 0; ps < p.size(); ps++) {//Sa plante la
if (p[ps].ignore == false && lpCurrentByte[ps] != p[ps].data) {
found = false;
break;
}
}
if (found) {
return (DWORD64)lpCurrentByte;
}
}
return NULL;
}
答案 0 :(得分:1)
进程不会按顺序加载其资源,在OS找到合适的地方加载不同的dll和堆,地址空间被分段。您不应该使用任何确切的地址,因为它可以在不同的运行中更改。
请改用VirtualQueryEx。我现在没有相应的代码,但您可以找到用法示例here。
答案 1 :(得分:0)
我发布了一个答案,因为我似乎无法编辑我的帖子(我输入的每个字符都会被回滚)。我也忘了提到我在内部运行此代码(来自注入的dll)
我尝试了以下功能(使用VirtualQuery作为light_keeer建议)。
它确实有效,但我扫描的地址并不总是在第一个&#34;内存区域&#34;我的代码检测到并且我似乎无法弄清楚如何获取其他代码,我尝试的所有内容都会在内存中返回我,在我读取它时返回ACCESS_VIOLATION或者在我可以读取的内存区域中间返回(不是在开始)。
DWORD WINAPI GetFirstAddressInMemory(LPVOID lpParam){
DWORD64 memoryRegionStart = 0x0000010000000000;
DWORD64 memoryRegionEnd = 0x7fffffffffffffff;
MEMORY_BASIC_INFORMATION mBI;
for (DWORD64 addr = memoryRegionStart; addr < memoryRegionEnd; addr += 0x200000){//Big increment otherwise it takes ages to load
if (VirtualQuery((void*)addr, &mBI, sizeof(MEMORY_BASIC_INFORMATION))){
if (mBI.State == MEM_COMMIT) {
printf("Address at %p (%p)\n", addr, mBI.BaseAddress);
printf("Next region: %p\n", (DWORD64)mBI.BaseAddress + mBI.RegionSize);
Pattern::ScanC(addr, memoryRegionEnd, "XX XX XX ? XX");//ends up crashing while reading memory
break;
}
}
}
return 0;
}