扫描内存(C++)

Scan memory (C++)

本文关键字:C++ 内存 扫描      更新时间:2023-10-16

我得到了一个函数,它扫描内存中的字节数组(XX?XX XX XX等)。

我的代码适用于windows 7,但最终在windows 10上得到了ACCESS_VIOLATION,因为内存的工作方式似乎与windows 7不同。

我的问题是,在加载游戏(64位)时,我需要在GetModuleHandle(0)作为我正在搜索的字节数组返回的地址加载到内存之前开始扫描。

如何获取游戏内存的起始位置,或者验证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;
}   

Process不按顺序加载其资产,在操作系统认为合适的地方加载不同的dll和堆,地址空间是碎片化的。您不应该使用任何确切的地址,因为它可以在不同的运行中更改。

请改用VirtualQueryEx。我现在没有合适的代码,但您可以在这里找到用法示例。

我发布了一个答案,因为我似乎无法编辑我的帖子(我键入的每个字符都会回滚)。我还忘了提到我正在内部运行此代码(从注入的dll)

我尝试了以下功能(按照light_keeer的建议使用VirtualQuery)。

它确实有效,但我扫描的地址并不总是在我的代码检测到的第一个"内存区域"中,我似乎不知道如何获得其他地址,我尝试的所有东西要么在我读取时返回内存中的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: %pn", (DWORD64)mBI.BaseAddress + mBI.RegionSize);
                Pattern::ScanC(addr, memoryRegionEnd, "XX XX XX ? XX");//ends up crashing while reading memory
                break;
            }
        }
    }
return 0;

}