簡體   English   中英

C++ 內存地址和偏移讀取 - 64 位

[英]C++ memory address and offset reading - 64 Bit

我在嘗試計算帶有偏移量的內存地址時遇到了一些麻煩。

注意:我可以做 32 位,但我需要使用 64 位地址。

我的示例是這個地址:0x000002586F08CE30,偏移量為 0x88。 當我得到這個添加時,它的地址是:0x2586F08CEB8,而它應該是:0x25825C4C880

我試過這個:

void aVoid()
{
    DWORD64* add = (DWORD64*)0x000002586F08CE30;
    cout << add << endl;

    DWORD64* off = (DWORD64*)0x88;
    cout << off << endl;

    DWORD64* BaseTimeAddress = (DWORD64*)((char*)add + (DWORD64)off);
    cout << BaseTimeAddress << endl;    // Gets 000002586F08CEB8
}

使用正確的地址進行偏移 我在哪里得到 0x25825C4C880:( https://i.stack.imgur.com/5K4eP.png

完整代碼

#include <iostream>

#include <windows.h>

#include <string>
#include <vector>
#include <tchar.h>
#include <stdlib.h>
#include <tlhelp32.h>

`
using namespace std;

DWORD GetModuleBaseAddress(TCHAR* lpszModuleName, DWORD pID) {
    DWORD dwModuleBaseAddress = 0;
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pID); // make snapshot of all modules within process
    MODULEENTRY32 ModuleEntry32 = { 0 };
    ModuleEntry32.dwSize = sizeof(MODULEENTRY32);
    
    if (Module32First(hSnapshot, &ModuleEntry32)) //store first Module in ModuleEntry32
    {
        do {
            if (_tcscmp(ModuleEntry32.szModule, lpszModuleName) == 0) // if Found Module matches Module we look for -> done!
            {
                dwModuleBaseAddress = (DWORD_PTR)ModuleEntry32.modBaseAddr;
                break;
            }
        } while (Module32Next(hSnapshot, &ModuleEntry32)); // go through Module entries in Snapshot and store in ModuleEntry32


    }
    CloseHandle(hSnapshot);
    return dwModuleBaseAddress;
}

DWORD GetPointerAddress(HWND hwnd, DWORD gameBaseAddr, DWORD address, vector<DWORD> offsets)
{
    DWORD pID = NULL; // Game process ID
    GetWindowThreadProcessId(hwnd, &pID);
    HANDLE phandle = NULL;
    phandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
    if (phandle == INVALID_HANDLE_VALUE || phandle == NULL);

    DWORD offset_null = NULL;
    ReadProcessMemory(phandle, (LPVOID*)(gameBaseAddr + address), &offset_null, sizeof(offset_null), 0);
    DWORD pointeraddress = offset_null; // the address we need

    for (int i = 0; i < offsets.size() - 1; i++) // we dont want to change the last offset value so we do -1
    {
        ReadProcessMemory(phandle, (LPVOID*)(pointeraddress + offsets.at(i)), &pointeraddress, sizeof(pointeraddress), 0);
        //cout << "ADD: " << &pointeraddress << endl;
    }
    return pointeraddress += offsets.at(offsets.size() - 1); // adding the last offset
}

#include <Psapi.h>

DWORD_PTR GetProcessBaseAddress(DWORD processID)
{
    DWORD_PTR   baseAddress = 0;
    HANDLE      processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
    HMODULE* moduleArray;
    LPBYTE      moduleArrayBytes;
    DWORD       bytesRequired;

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

                if (moduleArrayBytes)
                {
                    unsigned int moduleCount;

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

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

                    LocalFree(moduleArrayBytes);
                }
            }
        }

        CloseHandle(processHandle);
    }

    return baseAddress;
}

int main() {
    //HWND hWnd = FindWindowA(NULL, "Halo Wars: Definitive Edition");
    //char gameModule1[] = "xgameFinal.exe";
    DWORD64 address = 0x00000258722B0AB0;

    float nVal = 2000;

    HWND hWnd = FindWindowA(0, "Halo Wars: Definitive Edition");
    if (hWnd == 0) {
        cerr << "Could not find window." << endl;
    }
    else {
        DWORD PID;
        GetWindowThreadProcessId(hWnd, &PID);
        HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, false, PID);

        if (!hProc) {
            cerr << "Cannot open process." << endl;
        }
        else {



            DWORD64* add = (DWORD64*)0x000002586F08CE30;
            cout << add << endl;

            DWORD64* off = (DWORD64*)0x88;
            cout << off << endl;


            DWORD64* BaseTimeAddress = (DWORD64*)((char*)add + (DWORD64)off);
            cout << BaseTimeAddress << endl;

            DWORD64* com = (DWORD64*)add;
            cout << com << endl;
            //cout << &add << endl;


            DWORD_PTR baseAddr2 = GetProcessBaseAddress(PID);
            cout << "base" << &baseAddr2 << endl;
            cout << "base"<<baseAddr2 << endl;
            cout << "base" <<hex<< baseAddr2 << endl;
            DWORD64 offset_null = NULL;
            DWORD64 add2 = ReadProcessMemory(hWnd, (LPVOID*)(baseAddr2 + 0x014FA250), &offset_null, sizeof(offset_null), 0);
            cout << &add2 << endl;

            cout << &offset_null << endl;

            ReadProcessMemory(hWnd, (LPVOID*)(baseAddr2 + 0x014FA250 + 0x88+0x8+0x110), &offset_null, sizeof(offset_null), 0);
            cout << &offset_null << endl;

            cout << "END";









            char gameModule1[] = "xgameFinal.exe";
            DWORD_PTR baseAddr1 = GetProcessBaseAddress(PID);
            cout << hex << baseAddr1 << endl;
            cout << &baseAddr1 << endl;
            DWORD64 baseAddr = GetModuleBaseAddress(_T(gameModule1), PID);

            /*
            
            char gameModule1[] = "ac_client.exe";

            DWORD baseAddr = GetModuleBaseAddress(_T(gameModule1), procID);
            DWORD pointsAddr = 0x0018AC00;
            vector<DWORD> pointsOffesets = { 0x11C };
            //cout << std::hex << pointsAddr << endl;
            DWORD pointsPtrAddr = GetPointerAddress(hWnd, baseAddr, pointsAddr, pointsOffesets);
            //010FF974
            //cout << pointsPtrAddr << endl << &pointsPtrAddr << endl;
            int val = 1;


            ReadProcessMemory(handle, (LPVOID*)(pointsPtrAddr), &val, sizeof(val), 0);
            cout << "Value: " << val << endl;

            cout << "Pointer Address: " << std::hex << pointsPtrAddr << endl;

            cout << "WORKS";
            //"xgameFinal.exe"+016208B0
            */




          /*  DWORD64* BaseAddress = (DWORD64*)GetModuleHandle(NULL);
            DWORD64* address = (DWORD64*)((char*)BaseAddress + 0x014FA250);
            address = (DWORD64*)((char*)*address + 0x88 + 0x8 + 0x110);
            float currentTime = *(float*)address;

            cout << currentTime;
            cout << "END";
            */







            ReadProcessMemory(hProc, (LPVOID)address, &nVal, (DWORD64)sizeof(nVal), NULL);
            cout << nVal;
            CloseHandle(hProc);

            cin.get();

        }

    }
    return 0;

}
`

DWORD64* BaseTimeAddress = (DWORD64*)((char*)add + (DWORD64)off);

通過執行(char*)add ,您可以讓+運算符在 char 中添加一個偏移量。 字符是 1 個字節。 像這樣,

0x000002586F08CE30 + 0x88 = 0x2586F08CEB8

是正確的。 您指定的其他地址已完全關閉。 你從哪里弄來的?

在您鏈接的圖像中,有一個類型字段。 您可能需要將您的行更改為類型轉換為這種類型:

DWORD64* BaseTimeAddress = (DWORD64*)((float*)add + (DWORD64)off);

這意味着:偏移addoff float的數量。 但是,這種對指針的低級修改很容易導致 C++ 中的未定義行為,除非您非常小心。 您需要了解reinterpret_cast及其局限性。

我想到了。 我確實想感謝@Jeffrey 和@RaymondChen,因為他們的帖子幫助我更好地思考了這個問題。

所以很快我會在下面發布代碼,然后再解釋一下:

void code()
{
    /*1*/ DWORD64* test6 = (DWORD64*)0x2586F08CE30; cout << test6 << endl;
    /*2*/ DWORD64* test7 = (DWORD64*)0x88; cout << test7 << endl;
    /*3*/ DWORD64* test8;
    /*4*/ DWORD64* test9;
    /*5*/ ReadProcessMemory(hProc, (LPVOID*)((DWORD64)test6+ (DWORD64)test7), &test8, sizeof(test8), 0);
    /*6*/ ReadProcessMemory(hProc, (LPVOID*)((DWORD64)test8 + (DWORD64)0x8), &test9, sizeof(test9), 0);
    /*7*/ DWORD64* test2 = (DWORD64*)0x110;
    /*8*/ //cout << test2 << endl;
    /*9*/ DWORD64* test3 = (DWORD64*)((char*)test9 + (DWORD64)test2);
    /*10*/ //cout << test3 << endl;
    /*11*/ float currentTime = 0;
    /*12*/ ReadProcessMemory(hProc, (LPVOID*)test3, &currentTime, sizeof(currentTime), 0);
    /*13*/ //cout << test3 << endl;
    /*14*/ cout << currentTime << endl;
}

這是來自作弊引擎的圖像,其中包含所有數據: https ://i.stack.imgur.com/5K4eP.png

圖片

所以我從現在從作弊引擎獲得的 0x2586F08CE30 開始,但是“xgameFinal.exe”+014FA250 = 0x2586F08CE30

所以接下來我需要獲取該地址並將其與偏移量 0x88 組合,在第 5 行我這樣做了。

接下來是從 test8 中獲取該地址並組合偏移量 0x8。 (@第 6 行)

接下來是最后一個偏移量(0x110),這是@RaymondChen 評論幫助我的地方。

屏幕截圖顯示 [2586F08CE30 + 88] 但你計算了 2586F08CE30 + 88。 – Raymond Chen

所以在第 9 行是我獲得最終地址和值的地方。

暫無
暫無

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

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