使用ReadProcessMemory获取字符串值的访问违规行为

问题描述 投票:0回答:1

我是一个逆向工程的新手,对C++也很陌生。我想在游戏中收集一个玩家的角色名,用的是 ReadProcessMemory() 但每当我试图读取它时,它就会抛出一个异常。

if (procId != NULL) {
    hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procId);
    ModuleBase = getModuleBaseAddr(procId, "ac_client.exe");
    localPlayerptr = ModuleBase + 0x10f4f4;
    healthaddr = findDMAaddy(hprocess, localPlayerptr, { 0xf8 });
    //load to entitylist Array
    ReadProcessMemory(hprocess, (BYTE*)localPlayerptr, &Entitylist[0], sizeof(Entitylist[0]), 0);
    for (int i = 1; i < 10; ++i) {
        ReadProcessMemory(hprocess, (BYTE*)ModuleBase + 0x10f4f8, &Entitylist[i], sizeof(Entitylist[i]), 0);
        ReadProcessMemory(hprocess,(BYTE*) Entitylist[i]+(i*4), &Entitylist[i], sizeof(Entitylist[i]), 0);
        std::cout << std::hex << Entitylist[i] << std::endl;
        uintptr_t nameaddres;
        std::string name;
        nameaddres = Entitylist[i] + 0x225;
        //ReadProcessMemory(hprocess, (BYTE*)nameaddres, &name, sizeof(name), 0); 
        /*--> ** This is where I have a problem. ***/
        std::cout << name << std::endl;
    }
c++ winapi reverse-engineering
1个回答
0
投票

首先,你需要确定你要读取的字符串是宽字节(wchar)还是多字节(char)版本,然后你可以使用 std::string/char*std::wstring/wchar_t*.

第二,不要使用 sizeof(std::string)你需要确定你要读取的字符串的长度.对于wide-byte:

&(std::string)name 不是一个可写的地址,正如评论所指出的,你可以用wchat_t数组来代替。

wchat_t name[100];
BOOL ret = ReadProcessMemory(hprocess, (BYTE*)nameaddres, name, sizeof(name), 0);

或者你可以使用 &name[0](来自@Remy):

std::wstring name;
name.reserve(100);
BOOL ret = ReadProcessMemory(hprocess, (BYTE*)nameaddres, &name[0], 100*sizeof(wchar_t), 0);
std::wcout << name << std::endl;

那么.., std::cout 不适用 wchar_t*它只打印地址值。它是for循环中的一个局部变量,所以每次进来都会重新分配地址。由于某些规则,系统可能更喜欢选择相同的地址,所以你的地址值是相同的。

使用 std::wcout << name 来输出wchar_t字符串,如果输出总是只有一个字符,那么你可以考虑使用多字节版本来读取内存。

© www.soinside.com 2019 - 2024. All rights reserved.