-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.html
369 lines (354 loc) · 19.3 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Game Reverse Engineering 101</title>
<link rel="stylesheet" href="css/reveal.css">
<link rel="stylesheet" href="css/theme/blood.css">
<link rel="stylesheet" href="css/style.css">
<!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="lib/css/zenburn.css">
<script src="plugin/highlight/highlight.js"></script>
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? 'css/print/pdf.css' : 'css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
</head>
<body>
<div class="reveal">
<div class="slides">
<section>
<div>Game Reverse Engineering 101</div>
<div class="small">oder: Wie modifiziere ich ein Spiel?</div>
<aside class="notes">
Hallo und herzlich Willkommen.
Ich moechte euch heute erklaeren was reverse engineering ueberhaupt ist, was ich die letzten Wochen gelernt habe und was man so alles damit anstellen kann.
Reverse engineering betreiben hauptsaechlich Maleware Analysten, da ich mich aber mit Spielen ganz gut auskenne und selber welche entwickle hab ich mir den Gaming Bereich zum lernen ausgesucht.
Ich hab wie gesagt selber erst vor einigen Wochen damit angefangen und mir Silver als Ziel ausgesucht weil ich das Spiel noch von frueher kenne und es ziemlich simpel ist.
Drum haben auch alle Bilder und Beispiele etwas mit Silver zu tun.
</aside>
</section>
<section>
<section>
<div>Was ist Reverse Engineering?</div>
<aside class="notes">
Fangen wir an:
Reverse engineering bedeutet 'umgekeht entwickeln'. Man versucht also herauszufinden wie ein Spiel gebaut wurde um es dann entweder zu veraendern, erweitern oder auch nachzubauen.
</aside>
</section>
<section>
<pre><code class="c++">int main() {
Game myGame;
myGame.init();
while(myGame.running) {
myGame.handleInput();
myGame.updateLogic();
myGame.render();
}
return 0;
}</code></pre>
<aside class="notes">
Hier sieht man ein super simples Spiel, schoen lesbar in C++.
Es wird der Gameloop gestartet und in jeder Frame wird der Input des Spielers abgefragt, die Logik des Spiels aktualisiert und dann alles auf den Bildschirm gezeichnet.
</aside>
</section>
<section>
<pre><code class="asm">mov ds:dword_55606C, ecx
add edx, [eax+0Ch]
add ebx, [eax+10h]
add edx, ds:dword_5D1BD0[ebx*4]
add edx, ds:dword_5913C8
mov esi, eax
mov edi, edx
mov eax, [esi+4]
mov ebx, [esi+8]
mov ecx, [esi]
...</code></pre>
<aside class="notes">
Was ihr hier seht koennte jetzt ein Teil des Spiels sein. Nicht mehr so einfach zu lesen.
Der Computer versteht naemlich keine Hochsprache und braucht was einfacheres.
Also wird der lesbare Code in die Maschinensprache uebersetzt bzw compiliert.
</aside>
</section>
<section>
... super für einen 🖥️ und schlecht für 🤷🏻♂️
</section>
</section>
<section>
<ul>
<li>Binärcode mit einem Disassambler in Maschinensprache übsersetzen</li>
<li>Maschinensprache nun mit einem Decompiler in eine Hochsprache übersetzen</li>
<li>Neuer Code != Original Code</li>
</ul>
<aside class="notes">
Wir gehen jetzt den umgekehrten Weg.
Aus dem Binärcode wird Maschinensprache und daraus lesbarer Code.
Aber Achtung: Der neue Code ist aufkeinenfall der selbe wie der Urspruengliche.
Der Compiler optimiert naemlich beim Übersetzen den Code und dadurch gehen sehr viele Informationen des Original Codes verloren.
Zum Beispiel gibt es keine Variablennamen mehr, Schleifen werden aufgeloest und Kommentare entfernt.
</aside>
</section>
<section>
<img src="images/snowman_silver.png">
<aside class="notes">
Hier sieht man jetzt so einen decompilierten Code. Sieht ganz schoen uebel aus oder?
Garnicht mehr so simpel wie in dem Beispiel vorhin.
Was macht man jetzt beim Reverse Engineering?
Man liest den Maschinencode und versucht das Spiel zu verstehen. Der decompilierte Code hilft hier auch weiter weil man leichter sehen kann wie die Funktionen aufgebaut sind.
Man versucht das Spiel zu debuggen oder veraendert den Speicher waherend des Spielens.
Mit den ganzen Informationen kann man jetzt das Spiel veraendern oder andere Dinge anstellen die ich euch gleich noch erklaeren moechte.
</aside>
</section>
<section>
<img src="images/but-why.jpg">
<aside class="notes">
Ihr fragt euch sicherlich jetzt warum man sich die Muehe macht.
</aside>
</section>
<section> <!-- Warum RE? -->
<p class="fragment">Neugier</p>
<p class="fragment"><img src="images/silver_memory_dump.jpg"></p>
<p class="fragment">Spaß</p>
<p class="fragment">Profit</p>
<p class="fragment">Anerkennung</p>
<aside class="notes">
<ul>
<li>Neugier: Ich moechte wissen wie der Entwickler die Funktion XY implementiert hat. Oder ob er sich einen Spaß gemacht hat und irgendetwas im Spiel versteckt hat.</li>
<li>Spaß: Es ist lustig sich einfach mal die tausendfache Stärke zu geben und unbesigbar durchs Spiel rennen zu können.</li>
<li>Profit: Natürlich gibt es auch Menschen die Ihre Hacks verkaufen keine Frage.</li>
<li>Anerkennung: Es ist schön Lob von anderen zu bekommen wenn man etwas geschafft hat was nicht so vorgesehen war.</li>
</ul>
</aside>
</section>
<section>
<ul>
<li class="fragment">Remakes / Open Source Engines <span class="small">(OpenRA, OpenAge, freeablo)</span></li>
<li class="fragment">Patches <span class="small">(Bugfixes)</span></li>
<li class="fragment">Mods <span class="small">(TurboHUD, GTA Multiplayer)</span></li>
<li class="fragment">Private Server <span class="small">(WoW)</span></li>
<li class="fragment">Cheats <span class="small">(Trainer, Wallhacks, Aimbot)</span></li>
</ul>
<aside class="notes">
<ul>
<li>Also was kann man nun alles damit anstellen?</li>
<li>Remakes: Man kann alten Spielen ein neues Leben geben. Einige Spiele laufen nicht auf neuen System oder sind nur fuer eine Platform vorgesehen. Man koennte also ein Remake des Spiels bauen welches auf aktuellen Systemen laueft.</li>
<li>Patches: Der Entwickler hat einen Fehler gemacht und das Spiel stuerzt unter Windows 10 ab? Kein Problem wir koennen versuchen ihn zu fixen.</li>
<li>Mods: In Diablo 3 zum Beispiel fehlt eine Anzeige wie viel Schaden man jetzt gerade macht, also wurde TurbuHUD entwickelt. Ein Overlay was alle moeglichen Informationen ueber Spiel legt.</li>
<li>GTA San Andreas ist ein reines Single Player Abenteuer. Drum haben sich ein paar schlaue Leute hingesetzt und einen Multiplayer Modus entwickelt.</li>
<li>Private Server: Bekanntlich kosten viele MMORPGs jeden Monat Geld. Es gibt fuer einige dieser MMOs inoffizielle Server. Die konnten nur entwickelt werden weil man voher mit reverse engineering das Netzwerk Protokol studiert und nachgebaut hat.</li>
<li>Cheats: Man kann unsterblich sein oder alle Gegenstaende freischalten. Ich wuerde sagen Cheats sind die einfachste Disziplin beim reverse engineering und man kommt recht schnell zu einem Ergebnis.</li>
</ul>
</aside>
</section>
<section>
<section>
<aside class="notes">
Wie faengt man an?
</aside>
</section>
<section>
<div>Disassembler (IDA)</div>
<img src="images/ida_silver.png">
<aside class="notes">
Ganz wichtig. Man braucht einen Disassambler. Man oeffnet damit das Spiel und sieht den compilierten Code als Maschinensprache. Oder auch hier als Graphen.
Das Program welches ihr hier seht nennt sich IDA. Die Pro Version davon kostet etwa 3000 Dollar. Wie man bei dem Preis schon vermuten kann ist das Tool auch sozusagen das NonPlusUltra in dem Bereich.
Es gibt noch Alternativen, die sind aber lange noch nicht so weit.
</aside>
</section>
<section>
<div>Memory Scanner (Cheat Engine)</div>
<img src="images/ce_silver.png">
<aside class="notes">
Auch sehr wichtig ist der Memory Scanner. Damit kann man schnell Werte suchen, berarbeiten und sogar das Spiel im laufenden Betrieb patchen.
Cheat Engine wird eigentlich immer als erstes hergenommen wenn man mit dem reversen startet. Damit findet man schnell wichtige Stellen im Speicher und kann sich von hier aus durch den Code arbeiten.
</aside>
</section>
<section>
<div>Debugger (x64dbg)</div>
<img src="images/x64dbg_silver.png">
<aside class="notes">
Mit dem Debugger kann man jetzt ganz langsam durch den Code gehen und sieht Live was passiert.
</aside>
</section>
<section>
<div>Decompiler (Snowman)</div>
<img src="images/snowman_silver.png">
<aside class="notes">
Das Bild haben wir eben schon gesehen. Das ist der Decompiler. Damit versucht man den bereits compilierten Code in etwas lesbares zu uebersetzen.
</aside>
</section>
<section>
<div>Memory Dissector (ReClassEx)</div>
<img src="images/reclass_silver.png">
<aside class="notes">
Eines meiner Lieblingstools. Hat ein bisschen was von Cheat Engine. Man kann sich damit einen Bereich im Speicher anschauen und Strukturen zusammenbauen, Variablennamen und Datentypen vergeben.
Man baut also waehren das Spiel laeuft Strukturen zusammen und bekommt Informationen darueber wie das Spiel Daten im Speicher ablegt.
</aside>
</section>
<section>
<div>Binary Parser (Kaitai Struct)</div>
<img src="images/kaitai.jpg">
<aside class="notes">
Auch ein ziemlich cooles Tool. Kaitai ist ein compiler fuer Binaerformate. Man kann sich damit eine Beschreibung einer Binaerdatei zusammenbauen und dann daraus code generieren lassen.
Mit dem Code kann man dann diese Bianerdateien lesen und schreiben.
</aside>
</section>
</section>
<section>
<div>Demo</div>
<aside class="notes">
Ich moechte euch jetzt mal MEINE ersten Schritte zeigen. Weil mein aktueller Rechner nicht der schnellste ist und hab ich ein paar Screenshots vorbereitet. Wer will kann mich aber gerne nachher ansprechen dann koennen wir das ganze mal am Rechner ausprobieren.
</aside>
</section>
<section>
<section>
<img src="images/open_cheat_engine.png">
<aside class="notes">
Wir oeffnen also Cheat Engine und haengen uns ans Spiel um den Speicher auszulesen.
</aside>
</section>
<section>
<img src="images/silver_health_highlighted.png">
<aside class="notes">
Nun suchen wir uns einen einfach zu beeinflussenden Wert aus. Ich hab mich hier in diesem Fall fuer das aktuelle Leben entschieden.
</aside>
</section>
<section>
<img src="images/cheat_engine_search_health.png">
<aside class="notes">
Jetzt muss man ein wenig rumprobieren. Lebenspunkte sind normalerweise als Integer abgespeichert, daher stet der Value Type auf 4 Bytes und nicht auf Float oder String. Als Wert gebe ich 132 ein und druecke New Scan.
Wir haben jetzt 100 moegliche Stellen im Speicher gefunden in denen aktuell 132 steht.
</aside>
</section>
<section>
<img src="images/change_value_in_game.png">
<aside class="notes">
Zurueck im Spiel muessen wir den Wert irgendwie veraendern. Dazu lass mich einfach von einem Gegner treffen und reduziere die Lebenspunkte. Genauso haette ich auch einen Trank trinken koennen.
</aside>
</section>
<section>
<img src="images/search_changed_value.png">
<aside class="notes">
Wieder in Cheat Engine gebe ich den neuen Wert ein und druecke auf Next Scan. Damit werden nur die bereits gefunden 100 Stellen erneut ueberprueft. Alle anderen werden verworfen.
Wir haben jetzt Glueck und finden sofort nur noch eine einzige Stelle.
Normalerweise muss man das ganze jetzt einige Male wiederholen bis man sich sicher ist das man den richtigen Wert gefunden zu haben.
</aside>
</section>
<section>
<img src="images/change_value_in_cheat_engine.png">
<aside class="notes">
Ich aendere den Wert jetzt im Speicher und ueberpruefe ob wir die richtige Variable gefunden haben.
</aside>
</section>
<section>
<div>🎉🎉🎉</div>
<img src="images/silver_changed_value.png">
<aside class="notes">
Und siehe da wir sind praktisch unbesiegbar.
</aside>
</section>
<section>
<img src="images/save_cheat_table.png">
<aside class="notes">
Die sog. Cheat Table hier unten koennte jetzt noch angepasst und erweitert werden.
Wenn man sich ein bisschen mit dem Entwickeln von Spielen auskennt weiß man dass die Mana des Spielers in der Naehe des Lebens sein muss.
Normalerweise haengt alles was irgendwie miteinander zutun hat zusammen im Speicher.
Wir koennen unseren Fortschritt auch speichern und spaeter hier wieder weiter machen.
</aside>
</section>
<section>
<div>🤔</div>
<aside class="notes">
Ihr fragt euch sicherlich: Das ist ja nur eine kleiner Memory Hack. Wir wollen doch Spiele modifizieren.
Ja das stimmt, aber das ist ein kleiner Schritt auf einer ganz langen Reise.
Beim Reverse Engineering ist es wichtig viele Informationen zu sammeln und damit man es spaeter leichter hat.
Wir wissen jetzt wo im Speicher der Spieler steht, von hier aus koennen wir uns durch den Code hangeln.
Ich hab zum Beispiel rausgefunden wo die Liste aller Gegner ist weil nicht weiter vom Leben des Spielers auch der aktuell makierte Gegner stand.
Das ist einfach nur ein Zeiger der auf ein Element in einer Liste gezeigt hat.
Was ich mit der Information anstelle weiß ich noch nicht :)
</aside>
</section>
</section>
<section>
<section>
<img src="images/fullCheat.png">
<aside class="notes">
Jetzt will ich euch kurz meinen Weg auf der langen Reise zeigen.
Zu aller erst hab ich natuerlich mit Cheat Engine im Speicher herumgesucht und mit den Werten gespielt.
</aside>
</section>
<section>
<img src="images/memoryWrite.png">
<aside class="notes">
Weil ich jetzt weiß wo der Spieler im Speicher steht kann ich mir eigenes Program schreiben welches alle Werte auf einen maximal Wert setzt.
</aside>
</section>
<section>
<img src="images/imgui_overlay.png">
<aside class="notes">
Noch cooler als die Werte von außen zu bearbeiten ist es wenn man die Werte waehren dem Spielens bearbeiten kann.
Ich hab also gelernt wie sogenannten Proxy DLLs funktionieren und nutze die Zeichenfunktionen des Spiels um eigene Grafiken auf dem Bildschirm zu zeichnen.
Windows ist recht einfach gestrickt was DLls betrifft. Ein Program versucht immer zuerst die DLLs aus dem eigenen Verzeichnis zu laden.
Man schreibt also eine DLL die alle Funktionen der originalen enthaelt und packt seinen eigenen Code oben drauf.
Das Spiel laed diese dann und fuehrt den zusaetzlichen Code aus.
Ich bin jetzt also im Spiel drin und kann alles machen was ich moechte.
</aside>
</section>
<section>
<img src="images/silver_window_mode.png">
<aside class="notes">
Silver laesst sich leider nur im Vollbild spielen und zum Debuggen und Coden ist das nicht so geil. Drum hab ich angefangen einen Patch fuer zu schreiben um das Spiel im Fenster Modus starten zu koennen.
</aside>
</section>
<section>
<img src="images/kaitai.jpg">
<aside class="notes">
Aktuell versuche ich die Bilder, Levels, Sounds usw aus dem Spiel zu extrahieren. Dafuer nutze ich wieder Kaitai um zu verstehen wie die Binaerdateien aufgebaut sind.
Man kann auch an die Stellen im Code gehen in der die Dateien geladen werden und versuchen die Funktionen nachzubauen.
</aside>
</section>
<section>
<p>Und danach?</p>
<aside class="notes">
Also ich wuerde gerne eine Open Source Variante des Spiels entwickeln. Das hat eigentlich keinen besonderen Grund. Ich hab mir Silver ausgesucht weil es recht alt und ziemlich einfach aufgebaut ist.
Als Einstiegsprojekt also eine gute Wahl. Mal schauen was daraus wird :)
</aside>
</section>
</section>
<section>
<div>🎉 Dankeschön ❤️</div>
👏🏻👏🏻👏🏻👏🏻👏🏻
</section>
<section>
<ul>
<li>Mail: [email protected]</li>
<li>Twitter: @devnetik</li>
</ul>
<aside class="notes">
Und weil das Thema so umfangreich ist könnt ihr mich gerne jederzeit Fragen. Entweder ueber Twitter oder per Mail. Oder ihr sprecht mich einfach persoenlich an. Danke.
</aside>
</section>
</div>
</div>
<script src="lib/js/head.min.js"></script>
<script src="js/reveal.js"></script>
<script>
// More info about config & dependencies:
// - https://github.com/hakimel/reveal.js#configuration
// - https://github.com/hakimel/reveal.js#dependencies
Reveal.initialize({
dependencies: [
{ src: 'plugin/markdown/marked.js' },
{ src: 'plugin/markdown/markdown.js' },
{ src: 'plugin/notes/notes.js', async: true },
{ src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }
]
});
</script>
</body>
</html>