Base Adresse/Base Pointer in C++ nutzen?

09/27/2015 16:30 Pytroxis#1
Guten Tag,
ich habe folgendes Problem:
Ich habe via Cheat Engine(Automatisches Scannen) die Base Adresse/Base Pointer von der Schrotflinte in Bioshock herausgefunden, doch nun weis ich nicht wie ich die Adresse in C++ einfügen und nutzen soll da es ja nicht nur ein HEX Code ist(siehe Spoiler und Anhang)

Danke schon einmal für eure Hilfe.
MfG :D
09/27/2015 16:59 warfley#2
Ich verrate dir ein Geheimnis: Ein "HEX Code" ist einfach nur eine zahl im Hexadecimal system
Code:
"bioshock.exe"+00001C6C
bedeutet einfach: die Adresse des Prozesses bioshock.exe + 7276
09/27/2015 18:02 Daifoku#3
Ich denke nicht, dass es ihm um die Zahl geht ;)

"bioshock.exe" ist die Basisadresse von dem Spiel, der Einstiegspunkt.
Es gibt drei Wege die du einschlagen kannst.

Nummer 1: Hardcoden : überlicherweise 0x400000 .. zumindest unter 32bit. Kannst du dir aber auch in Cheatengine anzeigen lassen.
Nummer2 : CreateToolhelp32Snapshot
Nummer3: Über alle Module iterieren

für Ansatz Nummer 2 wird überlicherweise diese Funktion verwendet :

Code:
DWORD_PTR dwGetModuleBaseAddress(DWORD dwProcessIdentifier, TCHAR *szModuleName) 
{ 
   DWORD_PTR dwModuleBaseAddress = 0; 
   HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, dwProcessIdentifier); 
   if (hSnapshot != INVALID_HANDLE_VALUE) 
   { 
      MODULEENTRY32 ModuleEntry32; 
      ModuleEntry32.dwSize = sizeof(MODULEENTRY32); 
      if (Module32First(hSnapshot, &ModuleEntry32)) 
      { 
         do 
         { 
            if (_tcscmp(ModuleEntry32.szModule, szModuleName) == 0) 
            { 
               dwModuleBaseAddress = (DWORD_PTR)ModuleEntry32.modBaseAddr; 
               break; 
            } 
         } 
         while (Module32Next(hSnapshot, &ModuleEntry32)); 
      } 
      CloseHandle(hSnapshot); 
   } 
   return dwModuleBaseAddress; 
}
09/28/2015 13:35 Lazeboy#4
Quote:
Originally Posted by Daifoku View Post
Ich denke nicht, dass es ihm um die Zahl geht ;)

"bioshock.exe" ist die Basisadresse von dem Spiel, der Einstiegspunkt.
Es gibt drei Wege die du einschlagen kannst.

Nummer 1: Hardcoden : überlicherweise 0x400000 .. zumindest unter 32bit. Kannst du dir aber auch in Cheatengine anzeigen lassen.
Nummer2 : CreateToolhelp32Snapshot
Nummer3: Über alle Module iterieren

für Ansatz Nummer 2 wird überlicherweise diese Funktion verwendet :

Code:
DWORD_PTR dwGetModuleBaseAddress(DWORD dwProcessIdentifier, TCHAR *szModuleName) 
{ 
   DWORD_PTR dwModuleBaseAddress = 0; 
   HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, dwProcessIdentifier); 
   if (hSnapshot != INVALID_HANDLE_VALUE) 
   { 
      MODULEENTRY32 ModuleEntry32; 
      ModuleEntry32.dwSize = sizeof(MODULEENTRY32); 
      if (Module32First(hSnapshot, &ModuleEntry32)) 
      { 
         do 
         { 
            if (_tcscmp(ModuleEntry32.szModule, szModuleName) == 0) 
            { 
               dwModuleBaseAddress = (DWORD_PTR)ModuleEntry32.modBaseAddr; 
               break; 
            } 
         } 
         while (Module32Next(hSnapshot, &ModuleEntry32)); 
      } 
      CloseHandle(hSnapshot); 
   } 
   return dwModuleBaseAddress; 
}
Darf ich mal fragen wo du den Unterschied zwischen Nummer 2 und 3 siehst?

Ich denke mal du meinst das so:

Nr 2: CreateToolhelp32Snapshot
Nr 3: EnumProcessModules

Wobei ja beide über alle Module iterieren.
09/28/2015 17:39 Cyrex'#5
internal:
Code:
(DWORD)GetModuleHandle("bioshock.exe") + 0x00001C6C
external: siehe @Daifoku

wenn du jetzt mit schrotflinten pointer, die munition meinst:
Code:
*(DWORD*)((DWORD)GetModuleHandle("bioshock.exe") + 0x00001C6C) = 9999; // example
falls es die class von der waffe ist, reverse sie mit reclass oder ce dissect data structure und dereferenzier die offsets von der baseclass aus und änder values wie du willst.
10/03/2015 10:29 Pytroxis#6
@Cyrex': Danke erstmal :handsdown: Ja du hattest recht ich wollte die Munition verändern.

Ich hab nun noch eine Frage ich hatte mir ein Video angeguckt und da war die rede von Level Pointern.(Es war ein Tut für Assault Cube da hat er dann gesagt für Pistole(o.ä. weis jetzt nicht mehr) ist der Level Pointer 3) und dann hat er im Code eine 3 eingetragen) wie finde ich jetzt aber das raus?

10/03/2015 11:12 Slade100#7
Quote:
Originally Posted by Pytroxis View Post
@Cyrex': Danke erstmal :handsdown: Ja du hattest recht ich wollte die Munition verändern.

Ich hab nun noch eine Frage ich hatte mir ein Video angeguckt und da war die rede von Level Pointern.(Es war ein Tut für Assault Cube da hat er dann gesagt für Pistole(o.ä. weis jetzt nicht mehr) ist der Level Pointer 3) und dann hat er im Code eine 3 eingetragen) wie finde ich jetzt aber das raus?

das zeigt nur wie viele offsets du hast, also sagen wir du hast 3 offsets, dann ist dein pointer lvl 3.
10/22/2015 19:20 Cyrex'#8
Quote:
Originally Posted by Pytroxis View Post
@Cyrex': Danke erstmal :handsdown: Ja du hattest recht ich wollte die Munition verändern.

Ich hab nun noch eine Frage ich hatte mir ein Video angeguckt und da war die rede von Level Pointern.(Es war ein Tut für Assault Cube da hat er dann gesagt für Pistole(o.ä. weis jetzt nicht mehr) ist der Level Pointer 3) und dann hat er im Code eine 3 eingetragen) wie finde ich jetzt aber das raus?

ja, fleeps methoden sind aber scheiße.
intern kannst du das viel besser und vorallem einfacher machen:
PHP Code:
*(DWORD*)(((DWORD)GetModuleHandleA("bioshock.exe") + 1C6C) + 0x610) + 4B8 
nach deinem CE screen sollte das so funktionieren..
10/22/2015 19:25 qqdev#9
Seine Methode ist aber besser. Wenn du die Offsets änderst, musst du bei der Methode, die Pytroxis gepostet hat, nur "Offsets" anpassen.
10/22/2015 20:18 Cyrex'#10
Quote:
Originally Posted by qqdev View Post
Seine Methode ist aber besser. Wenn du die Offsets änderst, musst du bei der Methode, die Pytroxis gepostet hat, nur "Offsets" anpassen.
ist sie nicht... wenn du überhaupt eine ahnung von computern hättest;

- perfomance-technisch - meins besser, du musst nicht hundert mal die api readprocmem aufrufen.
- weniger code.
- kannst dir auch ne func machen, die noch viel kürzer wäre.

musst nur mal ein bisschen nachdenken ;)
10/23/2015 17:13 MrSm!th#11
Quote:
Originally Posted by Pytroxis View Post
@Cyrex': Danke erstmal :handsdown: Ja du hattest recht ich wollte die Munition verändern.

Ich hab nun noch eine Frage ich hatte mir ein Video angeguckt und da war die rede von Level Pointern.(Es war ein Tut für Assault Cube da hat er dann gesagt für Pistole(o.ä. weis jetzt nicht mehr) ist der Level Pointer 3) und dann hat er im Code eine 3 eingetragen) wie finde ich jetzt aber das raus?
Wenn man von einem Level X Pointer spricht, meint man in der Regel, dass man X-mal dereferenzieren, also eine Adresse auslesen muss (abgesehen von der Berechnung der Adresse des Base Pointers innerhalb des Moduls), um an die gewünschte Stelle zu kommen. Bei einem Level 3 Pointer hat man also einen (Base) Pointer auf einen Pointer auf einen Pointer.

Mal zwei Beispiele für Level 3 Pointer:
Code:
//in Pseudo C:

int value = 5;
int *ptr1 = &value; //erstes level
int **ptr2 = &ptr1; //zweites level
int ***ptr3 = &ptr2; //drittes level

***ptr3 = 42; //3 dereferenzierungen, um den wert zu ändern, abgesehen vom zugriff auf ptr3 selbst

//in cheat engine syntax (eckige klammern dereferenzieren den pointer):

//zugriff auf ptr3 (base pointer)
adresse von ptr3:  ModulBase + OffsetVonPtr3ImModul
wert von ptr3:     [ModulBase + OffsetVonPtr3ImModul]
//von nun an 3 dereferenzierungen, um an den wert zu kommen
adresse von ptr2 = wert von ptr3 + 0
adresse von ptr1:  [wert von ptr3 + 0] + 0//inhalt von ptr2 auslesen und 0 addieren
adresse von value: [[wert von ptr3 + 0] + 0] + 0 //inhalt von ptr1 auslesen und 0 addieren
zugriff auf value: [[[wert von ptr3 + 0] + 0] + 0] //value auslesen

//das ganze nun mit offsets in Pseudo C:

struct Struct1
{
	int someOtherValue;  //offset 0
	int yetAnotherValue; //offset 0x4
	int *ptr1;           //offset 0x8
}

struct Struct2
{
	int someOtherValue; //offset 0
	Struct1 *ptr2;      //offset 0x4
}

Struct1 s1, Struct2 s2;
int value = 5;
s1.ptr1 = &value;
s2.ptr2 = &s1;
Struct2 *ptr3 = &s2;

int addrOfS2 = (int)ptr3;
int addrOfPtr2 = addrOfS2 + 0x4; //ptr2 befindet sich innerhalb von s2 an offset 0x4
int addrOfS1 = *(int*)addrOfPtr2; //inhalt von ptr2 auslesen
int addrOfPtr1 = addrOfS1 + 0x8; //ptr1 befindet sich innerhalb von s1 an offset 0x8
int addrOfValue = *(int*)addrOfPtr1; //inhalt von ptr1 auslesen
*(int*)addrOfValue = 42; //inhalt von value modifizieren

//oder direkt in einer zeile:

*(int*)(*(int*)(*(int*)((int)ptr3 + 0x4) + 0x8) + 0) = 42;

//und in cheat engine syntax:

//zugriff auf ptr3 (base pointer)
adresse von ptr3:  ModulBase + OffsetVonPtr3ImModul
wert von ptr3:     [ModulBase + OffsetVonPtr3ImModul]
//von nun an 3 dereferenzierungen, um an den wert zu kommen
adresse von ptr2:  wert von ptr3 + 0x4
adresse von ptr1:  [wert von ptr3 + 0x4] + 0x8 //inhalt von ptr2 auslesen und 0x8 addieren
adresse von value: [[wert von ptr3 + 0x4] + 0x8] + 0 //inhalt von ptr1 auslesen und 0 addieren
zugriff auf value: [[[wert von ptr3 + 0x4] + 0x8] + 0] //inhalt von value auslesen
(Ich hoffe, das Beispiel macht nicht mehr kaputt als dass es hilft, lol)

Auf dem Screenshot im ersten Post steht in dieser Schreibweise:
Code:
adresse des base pointers: BioshockModuleBase + 0x1C6C
base pointer wert: [BioshockModuleBase + 0x1C6C]
adresse von value: [BasePtrWert + 0x610] + 0x4B8
zugriff auf value: [[BasePtrWert + 0x610] + 0x4B8]
Dort finden zwei Dereferenzierungen statt, weshalb es ein Level 2 Pointer ist. Simpel ausgedrückt hast du genau so viele Level wie CheatEngine dir Eingabefelder für Offsets bietet. ;)

Quote:
Originally Posted by Cyrex' View Post
ja, fleeps methoden sind aber scheiße.
intern kannst du das viel besser und vorallem einfacher machen:
PHP Code:
*(DWORD*)(((DWORD)GetModuleHandleA("bioshock.exe") + 1C6C) + 0x610) + 4B8 
nach deinem CE screen sollte das so funktionieren..
Wenn man klugscheißt, dann bitte richtig. Du dereferenzierst einmal zu wenig.

So wäre es korrekt:

Code:
int moduleBase = (int) GetModuleHandleA("bioshock.exe");
//insgesamt 3 dereferenzierungen; eine für den base pointer
int basePtr = *(int*)(moduleBase + 0x1C6C);
//und zwei, um von dort zum eigentlichen wert zu kommen
int valueAddr = *(int*)(basePtr + 0x610) + 0x4B8;
*(int*)valueAddr = 42;

//oder zusammengefasst, wie bei dir:
int valueAddr = *(int*)(*(int*)(moduleBase + 0x1C6C) + 0x610) + 0x4B8;
Übrigens macht es die obige Funktion, die mit ReadProcessMemory arbeitet, richtig. Du hast aber Recht damit, dass recht ineffizient arbeitet (sie liest übrigens auch einmal zu viel aus; beim letzten Durchgang steht in pTemp bereits der Wert, also die 49 vom Screenshot).
10/23/2015 20:10 qqdev#12
Quote:
Originally Posted by Cyrex' View Post
ist sie nicht... wenn du überhaupt eine ahnung von computern hättest;

- perfomance-technisch - meins besser, du musst nicht hundert mal die api readprocmem aufrufen. Stimmt
- weniger code. Stimmt
- kannst dir auch ne func machen, die noch viel kürzer wäre. Darum geht es nicht?

musst nur mal ein bisschen nachdenken ;)
Downsides:
- Nicht flexibel
- Schlechter lesbar
- Schlechter wartbar

Sein Ansatz ist besser, aber durch deine Implementierung kann man sie noch weiter verbessern. Nachgedacht habe ich.