2017-02-03 7 views
-1

数年前、私はいくつかのメモリの読み物を楽しんだ。標準はその後32ビットでした。ReadProcessMemoryでプロセスからベースアドレスを基準にしたアドレスを読み取る

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

編集 実際の出力にRbMmへ

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

のように使用し、ターゲット・プロセスが64ビットプロセスのですか?アプリケーションを64ビットで構築することを覚えましたか? –

+0

Yesターゲットプロセスが64ビットであり、私も64ビットとして構築しています –

+1

まず、ReadProcessMemory()が成功したかどうかを確認し、失敗した場合はエラーコードを確認します。 –

答えて

0

感謝をデバッグする方法を見つけるのに苦労しています、私が誤っていましたGetProcessBaseAddress内でCloseHandle()を呼び出しました。これを削除しmain()内に配置すると問題が解決しました。

VSの「リリース」モードでもプログラムが正しく実行されているようです。


あなたがEXEの取得のみベースアドレスをしたい場合は、ALLプロセスモジュール列挙を必要としません。 EXEは、常にプロセスの最初のモジュールである - ので、十分なクエリのみ1:

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); 
     } 
関連する問題