summaryrefslogblamecommitdiffstats
path: root/talks/reverse-engineering/reverse-engineering.html
blob: ade14cc52ae5fb36b4af5cca64c432c88df05d76 (plain) (tree)
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
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483


































































































































































































































































































































































































































































































                                                                                                         
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<title>Reverse-engineering a proprietary game server with Erlang</title>
<!-- metadata -->
<meta charset="utf8" />
<meta name="generator" content="S5" />
<meta name="version" content="S5 1.1" />
<meta name="presdate" content="20120529" />
<meta name="author" content="Loïc Hoguin" />
<meta name="company" content="Nine Nines" />
<!-- configuration parameters -->
<meta name="defaultView" content="slideshow" />
<meta name="controlVis" content="visible" />
<!-- style sheet links -->
<link rel="stylesheet" href="ui/default/slides.css" type="text/css" media="projection" id="slideProj" />
<link rel="stylesheet" href="ui/default/outline.css" type="text/css" media="screen" id="outlineStyle" />
<link rel="stylesheet" href="ui/default/print.css" type="text/css" media="print" id="slidePrint" />
<link rel="stylesheet" href="ui/default/opera.css" type="text/css" media="projection" id="operaFix" />
<!-- S5 JS -->
<script src="ui/default/slides.js" type="text/javascript"></script>
</head>
<body>

<div class="layout">
<div id="controls"><!-- DO NOT EDIT --></div>
<div id="currentSlide"><!-- DO NOT EDIT --></div>
<div id="header">
	<div id="sub_header"></div>
	<div id="logo"><img src="ui/img/logo.svg"/></div>
</div>
<div id="footer">
<div id="footer_shadow"></div>
<h1>EUC 2012</h1>
<h2>Reverse-engineering, Nine Nines</h2>
</div>

</div>


<div class="presentation">

<div class="slide">
<h1>Reverse-engineering a proprietary game server with Erlang</h1>
<h2>Erlang, the fear of game developers...</h2>
<h3>Loïc Hoguin - @lhoguin</h3>
<h4>Erlang Cowboy and Nine Nines Founder</h4>
</div>


<div class="slide">
<h1>Background</h1>
</div>


<div class="slide">
<h1>Why reverse-engineer?</h1>
<ul>
<li>Curiosity</li>
<li>Research the game</li>
<li>Build your own server<ul>
	<li>Because you want a challenge</li>
	<li>Because the official server is discontinued</li>
</ul></li>
</ul>
</div>


<div class="slide">
<h1>Frowned upon</h1>
<ul>
<li>Few game companies understand</li>
<li>Data mining is cheating</li>
<li>Reverse-engineering is cheating</li>
<li>Even if you don't take advantage of your knowledge</li>
</ul>
</div>


<div class="slide">
<h1>Anticheat technology</h1>
<ul>
<li>Online games feature anticheat technology</li>
<li>Often instead of real security</li>
<li>You have to bypass it, undetected</li>
<li>It's OK, anticheat systems are full of flaws</li>
</ul>
</div>


<div class="slide">
<h1>Windows</h1>
<ul>
<li>Online games usually only run on Windows</li>
<li>Wine doesn't work because of anticheat programs</li>
<li>A few steps require a Windows box</li>
<li>If you're doing any gaming you probably have one</li>
</ul>
</div>


<div class="slide">
<h1>Phantasy Star Universe (PSU)</h1>
<ul>
<li>SEGA game released in 2006</li>
<li>US version shutdown in early 2010</li>
<li>JP version still running</li>
<li>Protected by GameGuard (check files, memory, cheat tools...)</li>
<li>TCP for patch server, SSL for login/game servers</li>
<li>My example for this talk</li>
</ul>
</div>


<div class="slide">
<h1>Packet logging</h1>
</div>


<div class="slide">
<h1>Undetected logging</h1>
<ul>
<li>Methods available can vary depending on the game</li>
<li>Common methods:<ul>
	<li>Snooping</li>
	<li>Hooking a function on packet receive/send</li>
	<li>Man in the middle</li>
</ul></li>
</ul>
</div>


<div class="slide">
<h1>Breaking through PSU's SSL</h1>
<ul>
<li>Find the client SSL certificate</li>
<li>Try connecting to the server from Erlang</li>
<li>Use hosts file to redirect the client to localhost</li>
<li>Make the client connect to Erlang and redirect the packets to the server</li>
<li>You just built a proxy for the game</li>
<li>Packets going through the proxy are readable</li>
</ul>
</div>


<div class="slide">
<h1>Tee</h1>
<ul>
<li>A command that redirects input to both standard output and file</li>
<li>Make the proxy save to a file at the same time as redirecting</li>
</ul>
</div>


<div class="slide">
<h1>Proxy hint</h1>
<ul>
<li>You can always send the server whatever you want now</li>
<li>You can read, modify, filter packets</li>
<li>You can send any packet anytime</li>
<li>You get more control than you would through the client</li>
<li>Though you need to know the protocol first</li>
</ul>
</div>


<div class="slide">
<h1>Packet analysis</h1>
</div>


<div class="slide">
<h1>Protocol</h1>
<ul>
<li>First we need to figure out the general framing by hand</li>
<li>Open the log file with a hex editor and find packet boundaries</li>
<li>We got a packet size followed by a command number and the packet</li>
<li>The protocol is 32bit</li>
</ul>
</div>


<div class="slide">
<h1>Spreadsheet help</h1>
<ul>
<li>Parse the file and aggregate the info to CSV files</li>
<li>Figure out the field boundaries</li>
<li>We got 8bit, 16bit, 32bit data, 32bit floats, ASCII and UCS2 strings</li>
<li>Always take notes of what you are doing</li>
</ul>
</div>


<div class="slide">
<h1>Aggregate the field values</h1>
<ul>
<li>Get a clear view of what values a field can take</li>
<li>Sometimes the value never changes</li>
<li>Knowing the values allow you to guess the field purpose</li>
<li>Example: player ID, player level...</li>
<li>It's actually not that hard to figure out most of them</li>
</ul>
</div>


<div class="slide">
<h1>Game mechanics</h1>
<ul>
<li>A few key values hide a lot of secrets</li>
<li>Player ID identifies a player account</li>
<li>Quest, zone, map and entry IDs identify the map you play</li>
<li>Target ID identifies the player object in the zone</li>
<li>Client and file analysis helps figure some of these out</li>
</ul>
</div>


<div class="slide">
<h1>Extracting files</h1>
</div>


<div class="slide">
<h1>What files?</h1>
<ul>
<li>Quest and zone files</li>
<li>Quest files identify the mission played</li>
<li>Zone files define the scripts and objects in a set of area</li>
<li>If we are to write a server, we must understand those</li>
</ul>
</div>


<div class="slide">
<h1>File extraction</h1>
<ul>
<li>The files aren't always named or identified</li>
<li>Extract and tag them as properly as possible</li>
<li>Ignore duplicates</li>
<li>Get a good SSD for this, it can represent GBs of data</li>
</ul>
</div>


<div class="slide">
<h1>Files analysis</h1>
</div>


<div class="slide">
<h1>Client files too</h1>
<ul>
<li>Analyze both client and server files</li>
<li>They share file formats</li>
<li>PSU has an offline mode where more missions can be found</li>
<li>Sometimes file formats can be found on Google, often not</li>
</ul>
</div>


<div class="slide">
<h1>Start with a debugger</h1>
<ul>
<li>First, remove the anticheat technology</li>
<li>Load the game up to the game title</li>
<li>Break at all file loadings (find them with a dissassembler)</li>
<li>Press Enter, loading the login screen</li>
<li>You now have the ASM for loading the file</li>
</ul>
</div>


<div class="slide">
<h1>Step by step</h1>
<ul>
<li>Tediously advance step by step to find the interesting functions</li>
<li>The main archive format was encrypted using a blowfish variant</li>
<li>It was also compressed using a custom LZE algorithm</li>
<li>We got through their "security", let's extract the files</li>
</ul>
</div>


<div class="slide">
<h1>Concurrent extraction</h1>
<ul>
<li>Use Erlang to concurrently extract all the files you have</li>
<li>This can take some time, but less than if you had to do it on 1 core</li>
<li>Chances are your extraction code is wrong and doesn't handle edge cases</li>
</ul>
</div>


<div class="slide">
<h1>Continue with an hex editor</h1>
<ul>
<li>Hex editing allow you to isolate values and group of values</li>
<li>Problem: some files are just structs and arrays with pointers</li>
<li>Pointers get converted to real memory addresses on load</li>
<li>We still need to use a debugger to figure these out</li>
</ul>
</div>


<div class="slide">
<h1>File parser</h1>
<ul>
<li>We now have enough info to write a parser for all files</li>
<li>We should make sure the parser gets values in the right range</li>
<li>Pattern matching allow us to crash on unexpected values</li>
<li>Also crash on values that don't seem to change</li>
</ul>
</div>


<div class="slide">
<h1>Concurrently check our assumptions</h1>
<ul>
<li>Parse all files concurrently with range checking</li>
<li>If all files pass, then all our assumptions are verified</li>
<li>Bonus: convert the files to readable formats</li>
</ul>
</div>


<div class="slide">
<h1>Prototype server</h1>
</div>


<div class="slide">
<h1>Validating protocol assumptions</h1>
<ul>
<li>Using the proxy would be too limited</li>
<li>We need a valid implementation checked against the client</li>
</ul>
</div>


<div class="slide">
<h1>PSU's protocols</h1>
<ul>
<li>Patch, login and game servers</li>
<li>Patch is a very simple TCP protocol</li>
<li>Login and game are the same SSL protocols</li>
<li>Login just redirects to the game server on successful auth</li>
</ul>
</div>


<div class="slide">
<h1>First implementation</h1>
<ul>
<li>Make use of the previously logged packets</li>
<li>Take one log and just send all the packets unmodified</li>
<li>Reach in-game and stop there</li>
<li>Figure out the packet order</li>
<li>Try modifying values and check that nothing went wrong</li>
</ul>
</div>


<div class="slide">
<h1>Trial and error</h1>
<ul>
<li>Figuring out values and testing them is a trial and error process</li>
<li>We're developers, we're used to do this</li>
<li>It gets easier when we properly reach in-game</li>
</ul>
</div>


<div class="slide">
<h1>Trial and error</h1>
</div>


<div class="slide">
<h1>In-game</h1>
<ul>
<li>Open the menus, move the character, enter rooms</li>
<li>In other words: make the client send packets!</li>
<li>Note what packets are sent when you do something</li>
<li>Find in the logs what is replied when it happens</li>
</ul>
</div>


<div class="slide">
<h1>Responses</h1>
<ul>
<li>Same as before, start sending a logged packet</li>
<li>Then figure out the values and test things out</li>
<li>Write a function that does it for you for next times</li>
</ul>
</div>


<div class="slide">
<h1>Shell testing</h1>
<ul>
<li>You don't have to wait for client actions</li>
<li>Use the shell to send packets directly from the server</li>
<li>Make your character warp around!</li>
<li>Test things out thoroughly</li>
</ul>
</div>


<div class="slide">
<h1>Warping is good</h1>
<ul>
<li>Make sure to write a quick command to warp around</li>
<li>Changing areas allow you to unstuck yourself</li>
<li>The client doesn't do everything asynchronously</li>
</ul>
</div>


<div class="slide">
<h1>Feedback loop</h1>
</div>


<div class="slide">
<h1>Lengthy process</h1>
<ul>
<li>We need early feedback</li>
<li>We must not make the client disconnect</li>
<li>Reconnecting makes us lose at least 1 minute!</li>
</ul>
</div>


<div class="slide">
<h1>Reloading</h1>
<ul>
<li>Code reloading allows us to test fixes right away</li>
<li>Data files can be reloaded too</li>
<li>Client can be forced to reload an area through warping</li>
</ul>
</div>


<div class="slide">
<h1>Don't crash in the network layer</h1>
<ul>
<li>We must not kill the socket</li>
<li>When something bad happens, print the error in the console!</li>
<li>If a packet can't be parsed, print its hex representation!</li>
<li>Tips: also print when something is parsed properly</li>
<li>You can always crash after you finished working on the server</li>
</ul>
</div>


<div class="slide">
<h1>Still trial and error</h1>
<ul>
<li>Someone can help by figuring out values in the client</li>
<li>But this is still mostly trial and error</li>
<li>Although it's much better thanks to Erlang</li>
</ul>
</div>


<div class="slide">
<h1>Demo</h1>
</div>


<div class="slide">
<h1>Questions?</h1>
</div>


</div>

</body>
</html>