[C++] Game Hacking (via DLL Injection)

07/25/2011 17:08 cooler7878#1
Hallo liebes Forum ,

Dies ist ein kleines,sehr einfaches Tutorial, wie man den Speicher eines bestimmten Prozesses manipuliert.Ich werde dies über eine Dll Injection machen , da die/eine andere Methode bereits hier erklärt wurde. [Only registered and activated users can see links. Click Here To Register...]

1.Anforderungen/benötigte Software

Bevor wir anfangen benötigen wir folgende Dinge:

-Eine IDE (Entwicklungsumgebung) (ich benutze VC++ 2010)
Download:[Only registered and activated users can see links. Click Here To Register...]

-Cheatengine (oder TSearch oder was auch immer)
Download: [Only registered and activated users can see links. Click Here To Register...]
(Cheat Engine wird nicht für dieses Tutorial benötigt , jedoch ist es wichtig für eure späteren Projekte)

-Winject (zum injizieren der DLL)
Download:[Only registered and activated users can see links. Click Here To Register...]

-Ein Verständniss der Grundlagen von C++ (vorallem über Zeiger)
Zum Auffrischen verstaubter Erkentnisse :[Only registered and activated users can see links. Click Here To Register...]

2.Die Theorie

So dann hätten wir das auch hinter uns.Nun erstmal zur Theorie:
Prinzipiell wollen wir den Speicher eines bestimmten Spieles verändern.
Doch wie bewerkstelligen wir das ?
Man kann dies entweder über das Benutzen verschiedener Windows API Funktionen bewerkstelligen oder über eine Dll Injection.Und da letzteres wesentlich effektiver ist,wird diese Methode in diesem Tutorial behandelt.

2.1 Vorgehensweise

Doch eins nach dem Anderen.Ich werde nun erstmal die grundlegenden Fragen beantworten(falls dich dies langweilt überspring dieses kleine "FAQ"):

F:Was bedeutet den Speicher manipulieren?
A: Dies würde ich gerne am Beispiel eines kleinen Programmes erklären:
Zuerst schreiben wir ein kleines Programm,das den Wert eines normalen Integers ausgibt.
Code:
#include <iostream>

int main(void){

/*Highscore könnte natürlich auch die Menge der Ressourcen oder die Ammo
in einem FPS sein , das ist nur ein Beispiel*/
int highscore=100;

std::cout<<"Der Highscore liegt bei:"<<highscore<<"Punkten";
return 0;
}
So als "Gamehacker" wollen wir natürlich die Variable die den Highscore beinhaltet verändern.Da wir es aber mit einem kompilierten Programm/einer executable zu tuen haben wurde die Variable highscore "aufgelöst" und existiert jetzt nur noch, unter einer bestimmten Adresse,im Speicher.Wenn wir den Wert dieser Adresse (zum Beispiel über Pointer Dereferenzierung) verändern sprich man von Speichermanipulation.

F:Was ist eine DLL ?(Dynamic LinkLibrary)
A:. Dynamic Link Library oder [Only registered and activated users can see links. Click Here To Register...]

F:Prima, aber wie schreibe ich jetzt einen Hack , wie ist die Herangehensweise ?
A:Da eine injizierte DLL den selben Speicherberreich wie das Spiel/der Zielprozess hat müssen wir nur eine DLL schreiben , in der wir Pointer derreferenzieren.Nachdem wir diese injiziert haben sind wir fertig.(dazu logischerweiße später mehr)

F:Was zur Hölle versteht man unter Pointer dereferenzieren ?
A:Unter Pointer dereferenzieren versteht man das:
Code:
#include <iostream>

int main(void){

int x=0;
int *xptr;

//Adresse übergeben
xptr=&x;
//Derefernzieren über den Asteriks(*) Operator
*xptr=3;

//Wow x ist 3 wer hätte das gedacht ;-) 
std::cout<<x;

return 0;
}
Generell meint man mit Derefernzierung das Ansprechen des Inhalts eines Pointers(über den Asteriks * Operator).

Eigentlich bin ich hier fertig, jedoch werden eure Fragen in dieses FAQ mit aufgenommen und beantwortet.

3.Die Praxis

Bevor wir mit dem "Hacken" anfangen schreiben wir uns eine kleine HackMe.
Code:
//HackMe.cpp
#include <iostream>

int main(void){

int Holz=100;


for(;;){

std::cout<<"Sie haben momentan"<<Holz<<"Holz\n";
//Damit wir nicht mühsam suchen müssen
std::cout<<"Die Adresse,die den Betrag an Holz haelt:"<<&Holz<<"\n";

getchar();
}

}
Das ist jetzt vielleicht nicht so fetzig , wie beim Hacken eines normalen Spiel ist aber für unsere Zwecke passend.

OUTPUT:Sie haben momentan 100 Holz
Die Adresse , die den Betrag an Holz haelt:0x28ff24


Nun zum eigentlichen Hack und somit zur DLL:
Code:
//1.
#include <windows.h>
//2.
#define Holz_Adress 0x28ff24
[B]
//3.
void RewriteValues(){

int *HolzPtr;

//Adresse übergeben
HolzPtr=(int *)Holz_Adress;

//Dereferenzieren
*HolzPtr=2000;

}
[/B]
//4.
BOOL WINAPI DllMain(HINSTANCE hinstDll,DWORD Reason,LPVOID Reserved){


	switch(Reason){
         //5.
	case DLL_PROCESS_ATTACH:
		[B]RewriteValues();[/B]
		break;
        //6.
	case DLL_PROCESS_DETACH:
		MessageBox(NULL,"DLL Hack detached","Heyho",0);
		break;

	}


return TRUE;
}
Erklärung:
Wir werden nun den Source Code Schritt für Schritt durchnehmen.
1. Wir inkludieren den Windowsheader (gibt nichts zu erklären)

2. Wir "definen" unsere Adresse als Holz_Adresse somit gilt Holz_Adresse = 0x28ff24 (Holz_Adresse ist einfach nur besser zu benutzen)

3. Diese Funktion ist das Herzstück unseres kleinen Hacks.In dieser Funktion deklarieren wir einen Integer Pointer(HolzPtr*).Diesem Pointer übergeben wir unsere Holz_Adresse , die wir zuvor noch zu einem integer Zeiger casten müssen , da es sonst ,logischerweiße, eine Fehlermeldung vom Compiler geben würde. Der Letzte und Wichtigste Schritt ist die eigentlich Dereferenzierung ->
Code:
*HolzPtr=2000;
Hier weißen wir der Adresse 0x28ff24 aka Holz_Adresse den Wert 2000 zu .

4.Das ist die typische Main Funktion einer jeden DLL(das equivalent zur "regulären" Konsolen Main Funktion)
Code:
int main(int argc, char* argv[])
.Ihr Rückgabewert ist BOOL,ihre Calling Convention ist __stdcall(aka WINAPI) und sie nimmt 3 Paramter.(für Infos zu den Paramtern : [Only registered and activated users can see links. Click Here To Register...])

5.
Innerhalb des Switch Statements behandeln wir Zwei Fälle , die , einfach gesagt, beschreiben was mit der Dll "passiert".

Der erste Fall ist :
Quote:
DLL_PROCESS_ATTACH:
(engl."to attach" etwas anbringen) auf gut Deutsch : Sobald unsere DLL erfolgreich(via Winject) angebracht/injiziert wurde wird dieser Fall(engl."case") angesprungen und unsere Funktion wird aufgerufen.

6.
Der Zweite Fall ist :
Quote:
case DLL_PROCESS_DETACH:
(hm was könnte wohl bedeuten ;-))Sobald unser Zielprozess beendet wird wird unsere DLL auch "abgebracht" und eine MessageBox wird ausgegeben)

4.Kompilieren und Starten des Hacks

Um eine DLL zu Kompilieren müsst ihr unter VC++ ALT+F7 drücken.
und dort bei Projektstandarts unter Konfigurationstyp .dll auswählen.
Danach klickt ihr einfach auf Debuggen (den grünen Pfeil ;-))

Danach startet ihr WinJect und wählt eure DLL aus.
Dann wählt ihr den Zielprozess aus:
Screenshot:
[Only registered and activated users can see links. Click Here To Register...]

Das Ergebnis:
[Only registered and activated users can see links. Click Here To Register...]

Detach:
[Only registered and activated users can see links. Click Here To Register...]

5. Ende

So das wars für heute , falls euch dieses Tutorial geholfen hat würde ich mich über ein Thanks freuen.Des Weiteren freue ich mich über konstruktive Kritik.

Peace Out Cooler7878
07/25/2011 19:10 ScyLoon#2
Sooo...

hübsche Sache das... ich erhol mich jetzt beim abendessen mal von den ganzen fremdwörtern die meinem kopf zum brumen brachten und setze mich danach mal ran, dein tut nach zu scripten :)

lg und thx given!
07/25/2011 19:15 MrSm!th#3
Versteh nicht ganz, was das soll, Pointer Dereferenzierung muss man jemandem, der Sprache kann, nun wirklich nicht erklären und alle anderen sollten es gleich lassen.

@vorposter:

c++ scriptet man nicht!
07/25/2011 19:28 ScyLoon#4
Quote:
Originally Posted by MrSm!th View Post
Versteh nicht ganz, was das soll, Pointer Dereferenzierung muss man jemandem, der Sprache kann, nun wirklich nicht erklären und alle anderen sollten es gleich lassen.

@vorposter:

c++ scriptet man nicht!
dann klär mich auf, schreibt man c++ oder programmiert man c++?! :S
07/25/2011 21:07 cooler7878#5
@Sylocon ich danke dir ^^
@MrSmith es geht hier primär auch nicht um die Dereferenziehung sondern wie man ganz einfach mit injizierten dlls Speicher verändern kann.Ich wollte nur auf die Dereferenzierung eingehen ,da mein Tutorial sonst unvollständig gewesen wäre und andere sicherlich gemeckert hätten das ich ein komplexen Terminus benutze ohne ihn zu erklären
07/25/2011 22:41 MrSm!th#6
Quote:
Originally Posted by cooler7878 View Post
@Sylocon ich danke dir ^^
@MrSmith es geht hier primär auch nicht um die Dereferenziehung sondern wie man ganz einfach mit injizierten dlls Speicher verändern kann.Ich wollte nur auf die Dereferenzierung eingehen ,da mein Tutorial sonst unvollständig gewesen wäre und andere sicherlich gemeckert hätten das ich ein komplexen Terminus benutze ohne ihn zu erklären
Eigentlich nicht.
Im Grunde hättest du nur den Aufbau einer Dll erklären müssen und die Vorgehensweise, wie man den Speicher bearbeiten will.
Dann einfach den Code mit der Dereferenzierung bzw. memcpy/memset hinklatschen und fertig; wer den dann nicht versteht, der sollte es wie gesagt eh gleich lassen.
Quote:
Originally Posted by ScyLoon View Post
dann klär mich auf, schreibt man c++ oder programmiert man c++?! :S
Alles, nur nicht Scripten.
07/25/2011 22:53 cooler7878#7
Ist jetzt auch egal ich hab mir auf jeden Fall viel Mühe gegeben und wenn dort ZU VIEL steht ist das auch kein Weltuntergang
07/26/2011 00:17 Bananenwerfer#8
Mich würde mal interessieren,
warum du immer vor jedes cout das std:: machst,
es ist doch viel leichter gleich im Headbereich using namespace std; zu verwenden ?

Das ist jetzt keine kritik oder sonst was,
nur eine Frage da es mich interessieren würde ;/
07/26/2011 00:19 MrSm!th#9
Quote:
Originally Posted by Bananenwerfer View Post
Mich würde mal interessieren,
warum du immer vor jedes cout das std:: machst,
es ist doch viel leichter gleich im Headbereich using namespace std; zu verwenden ?

Das ist jetzt keine kritik oder sonst was,
nur eine Frage da es mich interessieren würde ;/
Weil using namespace ein schlechter Stil ist.
Man schreibt explizit, welches cout man nutzen möchte.
07/26/2011 11:02 |3lack#10
Aber als totaler Noob würde man nur bahnhof verstehen ;)
07/26/2011 13:15 buFFy!#11
übermäßige verwendung von std:: ist nicht gut.

btw musst du nicht erst nen holzptr erstellen.
das #define ist irgendwie auch fragwürdig.

Code:
DWORD Addresse = 0xAABBCC;
*(DWORD*)Addresse = 1337;
int WertVonAddresse = *(int*)Addresse;
07/26/2011 19:27 cooler7878#12
Darum sollte ein "totaler Noob " auch kein Hack schreiben!
@ ucore das erste was du angesprochen hast ist ausgemachter Unsinn
das Zweite stimmt durchaus jedoch halte ich meine Lösung für anschaulicher
07/26/2011 19:33 Bananenwerfer#13
Quote:
Aber als totaler Noob würde man nur bahnhof verstehen
Ich hab auch gerade erst angefangen C++ zu lernen und ich verstehe fast alles,
nur paar Sachen sind mir unklar.

@Topic Also ich finde dein Tut sehr gelungen,
wenn meine Kentnisse im Bereich C++ mal besser sein sollten,
werde ich auf diesen Thread zurück greifen,
und mich mal an einem Hack probieren ^^
07/26/2011 20:12 shuuky#14
Erstmal super tutorial.
Und an die Meckerheinis..besser machen :)


Kleine Anregung, dass ganze als Videotutorial mit Sprache wäre noch besser.

Und evtl. könnte man ja mal ein read/writeprocess tutorial mit einem besipiel wie minesweeper oder an einem richtigen game zeigen.

In einem tut. von threk hatte er erklärt wie man z.B die offsets findet für den wow radar [Only registered and activated users can see links. Click Here To Register...]

Könnte evtl. jemand der Ahnung davon hat das tut. fortfahren wie man jetzt die offsets in c++ weiterverarbeitet. Ob konsole oder dll. ist ja wurst, nur das man z.B F1 radar an und F2 wieder deaktiviert.

So etwas würde schon sehr helfen, dann versteht man auch wie man offsets weiterverarbeiten kann :)

Mfg
07/27/2011 17:19 black0utCpp#15
Gutes Tutorial ! Sehr hilfreich und ausführlich. Von mir gibts ein Thx !