簡體   English   中英

使用 ReadProcessMemory 從進程讀取相對於基地址的地址

[英]Reading an address relative to the base address from a process with ReadProcessMemory

幾年前,我做了一些記憶閱讀的東西,主要是為了好玩。 當時的標准是 32 位。

我修改了現有代碼以在 x64 系統上運行,但似乎無法讀取相對於進程基地址的地址。 我的日常工作並不真正涉及低級編程,所以我很生疏。

簡而言之:我想讀取一個相對於進程基地址的內存地址,以便我可以做一些有用的事情。

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

哇-64.exe + 0x173D390

閱讀我的地址沒問題。

在嘗試模擬這一點時,我可以確定(我認為成功)進程基址。 但是,當我嘗試從指針讀取“地址”時,我總是收到 0xCCCCCCCC。 顯然有些不對,但我正在努力尋找如何進一步調試......

#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;
}

編輯控制台的實際輸出

Process base: 7ff7395d0000, Player Base Address: 7ff73ad0d390, Actual address: cccccccccccccccc

感謝 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 );
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM