aboutsummaryrefslogtreecommitdiffstats
path: root/docs/src/content/tute-highscores.md
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@nullcube.com>2018-02-22 17:21:34 +1300
committerAldo Cortesi <aldo@nullcube.com>2018-02-22 18:07:58 +1300
commit982508d30f887b4fe8b2a855792ae1e33f378222 (patch)
tree9d749a57929a950f0e177a9bf4d6cd7d9a88c16b /docs/src/content/tute-highscores.md
parent1cacefa104626e4e0df5ffb2aa8b0c6f16b615b2 (diff)
downloadmitmproxy-982508d30f887b4fe8b2a855792ae1e33f378222.tar.gz
mitmproxy-982508d30f887b4fe8b2a855792ae1e33f378222.tar.bz2
mitmproxy-982508d30f887b4fe8b2a855792ae1e33f378222.zip
All new documentation
This patch does a lot. - Ditch sphinx in favor of hugo. This gives us complete control of the layout and presentation of our docs. Henceforth, docs will be hosted on our website rather than ReadTheDocs. - Create a simple, clean doc layout and theme. - Remove large parts of the documentaion. I've ditched anything that was a) woefully out of date, b) too detailed, or c) too hard to maintain in the long term. - Huge updates to the docs themselves: completely rewrite addons documentation, add docs for core concepts like commands and options, and revise and tweak a lot of the existing docs. With this patch, we're also changing the way we publish and maintain the docs. From now on, we don't publish docs for every release. Instead, the website will contain ONE set of docs for each major release. The online docs will be updated if needed as minor releases are made. Docs are free to improve during minor releases, but anything that changes behaviour sufficiently to require a doc change warrants a new major release. This also leaves us free to progressively update and improve docs out of step with our release cadence. With this new scheme, I feel CI over the docs is less important. I've removed it for now, but won't object if someone wants to add it back in.
Diffstat (limited to 'docs/src/content/tute-highscores.md')
-rw-r--r--docs/src/content/tute-highscores.md123
1 files changed, 123 insertions, 0 deletions
diff --git a/docs/src/content/tute-highscores.md b/docs/src/content/tute-highscores.md
new file mode 100644
index 00000000..f5cbd7bc
--- /dev/null
+++ b/docs/src/content/tute-highscores.md
@@ -0,0 +1,123 @@
+---
+title: "Setting highscores on Apple GameCenter"
+menu:
+ tutes:
+ weight: 2
+---
+
+# Setting highscores on Apple's GameCenter
+
+## The setup
+
+In this tutorial, I'm going to show you how simple it is to creatively interfere
+with Apple Game Center traffic using mitmproxy. To set things up, [install the
+mitmproxy root certificate]({{< relref concepts-certificates >}}). Then start
+mitmproxy on your desktop, and configure the iPhone to use it as a proxy.
+
+## Taking a look at the Game Center traffic
+
+Lets take a first look at the Game Center traffic. The game I'll use in this
+tutorial is [Super Mega
+Worm](https://itunes.apple.com/us/app/super-mega-worm/id388541990?mt=8) - a
+great little retro-apocalyptic sidescroller for the iPhone:
+
+{{< figure src="/tute-highscores/supermega.png" >}}
+
+After finishing a game (take your time), watch the traffic flowing through
+mitmproxy:
+
+{{< figure src="/tute-highscores/one.png" >}}
+
+We see a bunch of things we might expect - initialisation, the retrieval
+of leaderboards and so forth. Then, right at the end, there's a POST to
+this tantalising
+URL:
+
+{{< highlight none >}}
+https://service.gc.apple.com/WebObjects/GKGameStatsService.woa/wa/submitScore
+{{< / highlight >}}
+
+The contents of the submission are particularly interesting:
+
+{{< highlight xml >}}
+<plist version="1.0">
+ <dict>
+ <key>scores</key>
+ <array>
+ <dict>
+ <key>category</key>
+ <string>SMW_Adv_USA1</string>
+ <key>context</key>
+ <integer>0</integer>
+ <key>score-value</key>
+ <integer>55</integer>
+ <key>timestamp</key>
+ <integer>1363515361321</integer>
+ </dict>
+ </array>
+ </dict>
+</plist>
+{{< / highlight >}}
+
+This is a [property list](https://en.wikipedia.org/wiki/Property_list),
+containing an identifier for the game, a score (55, in this case), and a
+timestamp. Looks pretty simple to mess with.
+
+## Modifying and replaying the score submission
+
+Lets edit the score submission. First, select it in mitmproxy, then
+press <span data-role="kbd">enter</span> to view it. Make sure you're
+viewing the request, not the response -you can use
+<span data-role="kbd">tab</span> to flick between the two. Now press
+<span data-role="kbd">e</span> for edit. You'll be prompted for the part
+of the request you want to change - press <span data-role="kbd">r</span>
+for raw body. Your preferred editor (taken from the EDITOR environment
+variable) will now fire up. Lets bump the score up to something a bit
+more ambitious:
+
+{{< highlight xml >}}
+<plist version="1.0">
+ <dict>
+ <key>scores</key>
+ <array>
+ <dict>
+ <key>category</key>
+ <string>SMW_Adv_USA1</string>
+ <key>context</key>
+ <integer>0</integer>
+ <key>score-value</key>
+ <integer>2200272667</integer>
+ <key>timestamp</key>
+ <integer>1363515361321</integer>
+ </dict>
+ </array>
+ </dict>
+</plist>
+{{< / highlight >}}
+
+Save the file and exit your editor.
+
+The final step is to replay this modified request. Simply press
+<span data-role="kbd">r</span> for replay.
+
+## The glorious result and some intrigue
+
+{{< figure src="/tute-highscores/leaderboard.png" >}}
+
+And that's it - according to the records, I am the greatest Super Mega Worm
+player of all time.
+
+There's a curious addendum to this tale. When I first wrote this tutorial, all
+the top competitors' scores were the same: 2,147,483,647 (this is no longer the
+case, because there are now so many fellow cheaters using this tutorial). If you
+think that number seems familiar, you're right: it's 2^31-1, the maximum value
+you can fit into a signed 32-bit int. Now let me tell you another peculiar thing
+about Super Mega Worm - at the end of every game, it submits your highest
+previous score to the Game Center, not your current score. This means that it
+stores your highscore somewhere, and I'm guessing that it reads that stored
+score back into a signed integer. So, if you **were** to cheat by the relatively
+pedestrian means of modifying the saved score on your jailbroken phone, then
+2^31-1 might well be the maximum score you could get. Then again, if the game
+itself stores its score in a signed 32-bit int, you could get the same score
+through perfect play, effectively beating the game. So, which is it in this
+case? I'll leave that for you to decide.