Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用ReadProcessMemory从进程中读取相对于基址的地址_C++_Winapi - Fatal编程技术网

C++ 使用ReadProcessMemory从进程中读取相对于基址的地址

C++ 使用ReadProcessMemory从进程中读取相对于基址的地址,c++,winapi,C++,Winapi,几年前,我做了一些记忆读物,主要是为了好玩。当时的标准是32位 我已经修改了现有代码以在x64系统上运行,但似乎无法读取相对于进程基址的地址。我的日常工作并不涉及低级编程,所以我很生疏 简而言之:我想读取一个内存地址,相对于进程的基址,这样我就可以做一些有用的事情 在作弊引擎中,我可以使用: Wow-64.exe+0x173D390 读我的地址没问题 在尝试模拟此过程时,我可以确定(我认为是成功的)进程基址。然而,当我试图从指针读取“地址”时,我总是收到0xCCCC。显然有些地方不对劲,但我正在

几年前,我做了一些记忆读物,主要是为了好玩。当时的标准是32位

我已经修改了现有代码以在x64系统上运行,但似乎无法读取相对于进程基址的地址。我的日常工作并不涉及低级编程,所以我很生疏

简而言之:我想读取一个内存地址,相对于进程的基址,这样我就可以做一些有用的事情

在作弊引擎中,我可以使用:

Wow-64.exe+0x173D390

读我的地址没问题

在尝试模拟此过程时,我可以确定(我认为是成功的)进程基址。然而,当我试图从指针读取“地址”时,我总是收到0xCCCC。显然有些地方不对劲,但我正在努力寻找如何进一步调试这个

#include "stdafx.h"
#include <iostream>
#include <string>
#include <windows.h>
#include <psapi.h>

using namespace std;

UINT_PTR GetProcessBaseAddress(DWORD processID, HANDLE *processHandle);

int main()
{
    HWND WindowHandle = FindWindow(nullptr, L"World of Warcraft");
    DWORD PID;
    GetWindowThreadProcessId(WindowHandle, &PID);
    HANDLE      processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
    if (processHandle == 0) {
        cout << "Could not open process";
        return 1;
    }

    UINT_PTR BaseAddress = GetProcessBaseAddress(PID, &processHandle);
    UINT_PTR PlayerBaseAddress = (BaseAddress + 0x173D390);

    UINT_PTR PlayerBase;

    ReadProcessMemory(processHandle, (void *)PlayerBaseAddress, &PlayerBase, sizeof(PlayerBase, 0));


    cout << "Process base: " << hex << BaseAddress << ", Player Base Address: " << hex << PlayerBaseAddress << ", Actual address: " << hex << PlayerBase << "\n";

    system("PAUSE");
    return 0;
}


UINT_PTR GetProcessBaseAddress(DWORD processID, HANDLE *processHandle)
{
    DWORD_PTR   baseAddress = 0;

    HMODULE     *moduleArray;
    LPBYTE      moduleArrayBytes;
    DWORD       bytesRequired;

    if (*processHandle)
    {
        if (EnumProcessModulesEx(*processHandle, NULL, 0, &bytesRequired, 0x02))
        {
            if (bytesRequired)
            {
                moduleArrayBytes = (LPBYTE)LocalAlloc(LPTR, bytesRequired);

                if (moduleArrayBytes)
                {
                    unsigned int moduleCount;

                    moduleCount = bytesRequired / sizeof(HMODULE);
                    moduleArray = (HMODULE *)moduleArrayBytes;

                    if (EnumProcessModulesEx(*processHandle, moduleArray, bytesRequired, &bytesRequired, 0x02))
                    {
                        baseAddress = (DWORD_PTR)moduleArray[0];
                    }

                    LocalFree(moduleArrayBytes);
                }
            }
        }

        CloseHandle(*processHandle);
    }

    return baseAddress;
}

多亏了RbMm,我意外地在GetProcessBaseAddress中留下了对CloseHandle()的调用。将其移除并放置在main()中解决了该问题

程序似乎只有在VS中处于“释放”模式时才能正确执行


如果只想获取
EXE
的基址,则不需要枚举所有进程模块<代码>EXE始终是处理过程中的第一个模块-因此只需查询一个即可:

ULONG GetProcessBaseAddress(HANDLE hProcess, HMODULE* phmod)
{
    ULONG cb;
    return EnumProcessModulesEx(hProcess, phmod, sizeof(HMODULE), &cb, LIST_MODULES_DEFAULT) ? 0 : GetLastError();
}
像这样使用

        union {
            HMODULE hmod;
            ULONG_PTR BaseAddress;
        };
        ULONG err = GetProcessBaseAddress(h, &hmod);
        if (!err)
        {
            DbgPrint("%p\n", BaseAddress + 0x173D390 );
        }

那么,目标进程是64位进程?您还记得将应用程序构建为64位吗?应该已经提到,是的,目标进程是64位的,我将构建为64位的。首先要做的是检查ReadProcessMemory()是否成功,如果没有成功,错误代码是什么。您的括号放错了位置
sizeof(PlayerBase,0)
。您可以调用
CloseHandle(*processHandle)
位于
GetProcessBaseAddress
中,因此您可以使用已关闭的句柄调用
ReadProcessMemory()
        union {
            HMODULE hmod;
            ULONG_PTR BaseAddress;
        };
        ULONG err = GetProcessBaseAddress(h, &hmod);
        if (!err)
        {
            DbgPrint("%p\n", BaseAddress + 0x173D390 );
        }