2013-07-31 12 views
5

Używam WinAPI ReadProcessMemory() do odczytywania "ukrytych" informacji z gry.Czytanie pamięci z ".exe" + offset?

Użyłem Cheat Engine, aby znaleźć statyczne wskaźniki, ale nie wiem, jak je odczytać. Cheat Engine daje mi wskaźnik do mniej więcej tak: "mygame.exe"+1C50

jestem bardzo nowy w WinAPI, w jaki sposób mogę przekonwertować "mygame.exe"+1C50 do adresu, który można odczytać z ReadProcessMemory()?

EDYCJA: Próbowałem uprościć problem, ale domyślam się, że powinienem podać pełny kod. Pracuję tutaj z adresami statycznymi i wskaźnikami wielopoziomowymi, ale nadal mam problem z uzyskaniem adresu bazowego lub w/e.

Oto pełny kod i a picture of my cheat engine address:

#include <iostream> 
#include <windows.h> 
#include <tlhelp32.h> 

using namespace std; 

HANDLE GetProcessHandle(const char *procName); 

int main() 
{ 
    const char *procName = "prism3d.exe"; 
    HANDLE hProc = GetProcessHandle(procName); 
    if (hProc) { 

    /* This works if I use the dynamic address (f.e. 0x02C2C4DC), 
     but it changes every time I restart the game. 
     I need to use the static address (prism3d.exe+A1C) to get 
     the dynamic address for my "nuke". 
     */ 
     float nuke; 
     ReadProcessMemory(hProc, (void*)0x02C2C4DC, &nuke, 4, 0); 
     cout << nuke; 

    } 
    CloseHandle(hProc); 
    return 0; 
} 

HANDLE GetProcessHandle(const char *procName) 
{ 
    HANDLE hProc = NULL; 
    PROCESSENTRY32 pe32; 
    pe32.dwSize = sizeof(PROCESSENTRY32); 
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
    if (Process32First(hSnapshot, &pe32)) { 
     do { 
      if (!strcmp(pe32.szExeFile, procName)) { 
       hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID); 
       break; 
      } 
     } while (Process32Next(hSnapshot, &pe32)); 
    } 
    CloseHandle(hSnapshot); 
    return hProc; 
} 

Edit 2: Oto jak próbowałem czytać wartość mojego nuke, ale daje mi liczb losowych, inny za każdym razem ponownie uruchomić grę (czasami jest to 0, czasami 324324324, itp ...):

if (hProc) [ 

    DWORD baseAddr = (DWORD)GetModuleHandle(procName) + 0xA1C50; // also tried this with GetModuleHandle(NULL) 
    DWORD mainAddr; 
    ReadProcessMemory(hProc, (void*)(baseAddr + 0x111C), &mainAddr, 4, 0); 

    // Nuke 
    float nuke; 
    DWORD nukeAddr; 
    ReadProcessMemory(hProc, (void*)(mainAddr + 0x48), &nukeAddr, 4, 0); 
    ReadProcessMemory(hProc, (void*)nukeAddr, &nuke, 4, 0); 
    cout << nuke; 
} 
+0

Musisz zlokalizować adres bazowy "game.dll", a następnie dodać 1C50. –

Odpowiedz

6

podstawa przesunięcie jest zwykle początkiem modułu pamięci, można uzyskać to z GetModuleHandle (zwracany adres jest początkiem PE w pamięci). Mówię ogólnie, ponieważ niektóre konwencje definiują podstawę w stosunku do początku sekcji kodu, którą należy następnie odczytać z PE.

można zrobić coś takiego jak:

UINT_PTR addr = (UINT_PTR)GetModuleHandle("game.dll") + 0x1C50; 
ReadProcessMemory(hProc,(void*)addr,pBuffer,nSize,&BytesRead); 

Powyższy działa tylko jeśli używasz w przestrzeni adresowej procesu są kierowane (przez wstrzyknięcie DLL), aby to zrobić za pomocą pilota proces (jak pokazuje twój przykład) musisz wyliczyć, aby przetworzyć moduły, aby uzyskać prawidłowy uchwyt do modułu, który cię interesuje.

MSDN ma przykład tego here, trochę go refaktoryzując, możesz utworzyć funkcję, która sprawdza nazwę i zwraca HMODULE jeśli pasuje, odlewanie to da ci adres bazowy modułu.

+0

Nie działa, to tylko daje mi jakieś dziwne numery tyłek, a nie prawidłowe adresy:/Edytowałem pytanie, mam już wskaźnik statyczny '.exe' –

+0

@SkamahOne czy sprawdziłeś, czy raporty CE o adresach są względne lub czy sekcja kodu krewny? i czym dokładnie są te "dziwne" liczby? – Necrolis

+0

Nie, jak mogę to sprawdzić ...? Mam wskaźnik o wartości '" mygame.exe "+ 1C50', który wskazuje na inny adres, próbuję uzyskać" inny adres ". I tylko kilka wielkich liczb całkowitych, '17512325403' itd. –