I'm trying to figure out what data the iPhone application sends. It uses the GKTurnBasedMatch framework.
I grabbed some of my packages and I found a promising XML message with this line as the value for the game-state key:
=
Base64, of course! So I decoded it and got:
{"GameGuid":"bd120afb-3c64-4e76-937a-fe1628e1db57","GameData":"AgEUwqlp8iLRvVwQfW+WtOHinFWjUaxt51yl3MLCN2w+Lgd9iSOxbRFvvw6g2uSr2RgXTcyqc9YXufdVFe1guS4B10ev\/4BEpO4fPPqeGDZt98ZLJto7IvPBAPTg26htfdLLPvrmn3J4osEZk\/YdysXx0g2kL5GUekX\/TKn+aDUNZIo980fKNDpVu4k+9p7O8DwETBQO+9VatHOIHux0EGGTiKpTdRKKDYAdow5nkggaNjL+aU8CQnurHj6\/3WK6Oo3oUZQGz8UNtDPvC1obotM3gDpct3ZgntX6eZLpx5osuiRsx8SVqaiGoaM89TO1xo8etWoHWAqfaMwxnfnRvLZkU5qFFgLicKE9uFCeH9P+4p9W0QPz89MyshaytWCtRq8FGbH5swIyo9RfvCV4WWZLOBX1u9eYMvFTqd1+f0\/vnUIRQPZt6SFczGixOXkFijOysO0KGOav3bV+QxQq3HoyIL+V5AA22Fa1Z0t28noax0MoQAvOfZz6VJ\/cGr4SgyfPx+DvuUAOe8Rrp3k+v1e9a\/xVN7XgJDmo74ARL\/\/yNa0lu1ljEsv6ukUB\/6QvBgdglHmm8hPkEKO2t3CoypG3AAhE3VUGrcinofLMu92401iZaWYEy12N\/W9qJpSmGiliuXVcHNp9ZmySXHCNe8Ep5XjJMcgxxftEFA0iyDBC7okIV7W6g8dvC4gMqQg1sRF9WLbqSIwKpJ3PFbnuBVMolht43I2K\/mSbVEMUFxr0Nf6+CfyMbnOgfN0opnQW\/k6nQB+d\/2yUVcjhUpqoDiGNHDR2vW\/OBerbCrTJkY+uwhVVp5R6PjXwOUtMzMAzwnSKDLaM+PH2+oe65YtUfcQ3JzZG9mCi6NtfhYYClqkIpzl5V+DMLQwKGoxyxIVx\/QwSOxCyoN3FvotFXASFDYuFoTtrGGHykZQHc9cbK8+dDQp2qXG+uha+yTHlxIQJ2Tq3f1Nscw2Ay\/wgr+UzGDWIlyWbad3YsSMXNUBnpSihv2vLDlAw0P+Rul932S1LxKmK4JZtocO3VZtQyiQJHrIa5WsQ4oorgTt+sFEzljC+NytFCxuvZ\/N6eESPTNL6l0RGfy8sDnJpbGUoKIl\/s0WgLTqzZzqv9mrFNJ\/g6Yv053ssPaIbdmmITn+rzfyHpNrkVAJ7COtaqwegndg7qn08btbc0qy2nkeNpVDmz0H4f4xUW04NJ6+GDwBshMSj5ExaRUYpskqt\/fBf\/ktpadNOgZKvvch8bTMp\/bvM5mvzmsCNQLljS5pFpDR4D5GC97G6s2s14Lb4MRwNhizJ0+5pG43PHwom+UgkVSpoSwO7BOGxd8UXFdCBWHfnhijv5HJmj2Kro87qasKMOM1KsNXKDDGn\/CBdIP0jTRxkJy21TaK0OjmbKEmN7DsVF1tSOCMMkSaWFRj5cUgysW8Ro3orts8ImAmGYehW3BLvXmGUqIcusGILUo8n9no+kcByRK8HSzhUyOrZABwOqnpwQsgO8aPcshrAmsekjJjKocu6C1PInXhj32xihaMRgTlp4UgN9d5p6XepgP8JFK9Dfv5+D3vFplDRofzKNenpElWt23lJLh579KRkBZzAvRp9+aX5Dtxul4x6xYGjAGN1QI4ChMmywITwrRjACpHyd+KlBcLAjT6cYdXlRWdMnvHJrWTE1U3i6HJDYjCemxF1X51ejGPUK6K8OT+2sc3\/kfBbc3B8UBY2+IIcFa7uaeE0W5EbCfp4sM8S5VgWT3uluB6iBNCe2DRkbqvUOHZeImSf87yVKgK+11nNUCW6kg28UM7Hw+2SQ7OSWxB7uuwCkJz743B8qPe9RPz2qXlhtgLNfSHjBibWK+UU5\/E3SYut2+vrKH3VKCo13Sl+DBPLTaaHxdPHKGJPtGT1VhlDg2deLiKeY0hGO0hsIAFY5DaRnSLpYgyBl5pB72kz1Rf\/HXhoFA8mM8hxKcrR+38yvzbl3yvfG7NO1Ez+RjawePZORuUdAbEH2gT+MFopOI+YGYXWPFV8KTmImnpc0e4j76+3Ow4xaaCwN4gtsrRnsb4GiSb6MTh42pGbi8KLnNwmrSES64+V0Z2VD5l\/QCHWZ6BziTXluFaaGB0eAyLOZT31qzm6F00a6uO4F83G8ue0kZhOdA6THuu4MZCTqtTJd3zvZe8m7mhnR6Qa3kNwpMeoer68dlbhdTbkiTSX88uguo5Y\/R2zdaCCXLDneAcedf6iCXan\/N4VlzDaaTKuLhchg3cE2YEXkbxlR7oH5cucxVRxPLmUdJ5LQku\/gCpszFTLSQBgUGdB7sjk8pMaeKa8ix+DWaehN15dPUwW74BUXnnq31tmMvrz3lTMqy8az4S9j4CwZnn24C4y\/Q525zcwv36DRr1Z\/frMiufOmTcRJ1ec2t\/95MGX6HLDjQnpk+hj0Dhnq4l9Xp2nTmdIXRKL3jum3Id\/kmDnI0LZmC0SE+lSWhAb8iqHiyv1lPLbibI+RmyNUMuz\/Iq1+b0+bNSUEzXMx502G+hIpxr5aXCFNbKSXJWd9HtjG4pEAOxDCPsPLN1xn8defKBGds+nWvAkq2eyN3cq3K1SprhvKYwxzr\/ADU9XMs2T5dKquo7erPGhzv5NAMERQcgXcdF4ZgcNgzfa0K8gwhJl8dxeM6r9yTDNqd4bJP4H2\/+s26yypVDgiHPUdq0lTjqe7Smm4DXn5UkaWBGJpID7MX99woa7ctbsa9s88eEIbtbdGX032DqK\/qFkIwQSB8EvaO3IqYgCB9apRBZxrNfVOd0iT5SXrAlxQzAmIwGqhkQeZdVov3pIDI8BLit+8ySPPc2z4+N2o3qvVRgyY8Zf9rSmts53KTFlMW6S3KHCjCsqV7ZhVFF47p7Ax5eyGNkTQVPTNgleEcrxEWEk3aD5K9KN34PD5tgzx7ytc4MGooHfLJVL45zBXa2BUwJluYPimis5MxzeKz73G++IK9eWxZ0DhJEvnqnmIDKopKPtKJ+lZX2QMpKW5PNn7KsAb7hcC1koZ1B8krxoBqUz6Y6uAa69jJcRhNfSMlo+3070nalZROZw4tSUZIr\/asTsngUft\/IEC\/qmI4ogCc4lKgEc\/x+KsWZw+H7BN385F\/jh+UpolLeDSySWpKmv52Yux4i8ydiSMpW6cDM6akOfTehdrSQNP1wpgGChdc94yhZlv6fIaSyOwEAtosqPCTJNh5PR8ePkjnEjDzuyMFh\/jXHHbXJEui2wi3JfVbSXYjrL9MyGuHV1\/XJvkgFNSQGgdRZYBJ8HrHfXgkikzXAI75Kskpc9nwdsLSMDxiV+UF\/TZ7GdD0T6BLJHyBJ+TLgmd6NeFmGG2EVcoGAF64e8d9GfKp\/ZpFXy7GgjkQf3kGG527eWqbRBa5keum1S7tDM43CAFPjOHDnuXjx9EEljrWm1+rMfZx8mksWxxreEs0WQpOhvbORHr6\/dUHgJcYwHY4nD7QgFvRiMwgvtmGnm1pzC5YSu7LKvaeDTkrjFLThZLPCdT+y+IFsl\/Qw4ShReHcvmgQOcAJyIVya6v4OdTHL0JOygqvHkaugPxQczA0D5xmyv\/s8xVoav3lc8\/F8oZnI2Ptols27DIPlNHN2Kvizu47JJhvUoVOYjZUwlFvG5+mpvsHHrHewms3QKE\/7uuFIq9ybwbz4\/S5ktNWCoNRxwD3a1XoJiRJ7TqXvWc5SVnQRy3xwgIoWEmlSZN4DSrbtqNW8vPQiaEtJQtk4JxPo5\/j9WnQbR2Ly1ImdRVWW4FDDm6XkdHLwoNJgFHat5EHu42Qdbcs+WrQSLLAveldbdXwR2BGGQBkbbvEmM0j0xWGi\/hJTX7hQqYsbZJgGwWxuay7xtM4ul5CSVCP+eOMt2Opq3AU4hBKJrgECwGQC3ya3veTCWfy43iDCsvu9\/D2jxulgQGZIY6Nl58sp8IQehlCNNlrsP7xZgFqUVqKubnQtGkKxCo3MgIKBIT1C0z8zCwvGLSJzPBhAX9cD5Mtv84lfWvjQHW35gi4rfvG8qFwHl8FUcZ7\/NnvMySiw+JYFU6KzL0UWvtZU6k1kUZfgicMH7TZTdMhhuOYO5k09Rl3kluX4gsWxRQ4MUkd12l7Qbj9gPeaz4S94p1ws5HjCYaQVD38nsWjoUl\/qAUeX3+Ga\/TsEqd7ShpV1OwX94sh63oyJoX3\/mfiqDiLeGLHHmAhjuvp4RXR\/NbayM5YGaS1MiDLc8+G73dKpkRm3lS44FOIHHw\/\/J9omqIiuvbC4hlGME\/yO1o65QB9yOH12WEEJKBlaCBQTg4fN9LFQq1OcV2dFGzP7SghGoET0tSN8dskhUhgQBoijbpiqUdr4Jk9O+nB4Qv\/lE3oA4\/Xo+nU5x0Ejh3EahjjRCVsStGS7jO5nPOnkhBR4NWt4JoBkgN+IL8rColTzEWQAkTY2O0hB0unWBhuTGBGnOpPywjezrFyZX73X\/sHHjQapXvwRdbJ2nVvm9mW4jfuoeeBzluQ8gCWSQp9mS+ekPx9eSp3fa1ASyYuWewMNR3ubPCHQM2NL6hR+vdoX+hchuw3vRzKh8Ag8Z\/GlB9pCVaJH+T3hzT0z0I7IOWq\/OXoI4B2WXOkYL3FMFnERO\/b6o08CJnYNvKXtaoeLKAVqDYAftQJI9fWFdk6BL84slWGaxmVup1wVNt40qW\/yR9vbgHqkm\/Zk\/yhNo\/VKidz3bbYSGqXhC2sj1LLjIKoVd3J0uyL1If5beSX3o2BHRbi0ZfLntwzsnlaPfaw0t9nFXmgLEEUh0gG\/fi4EOpChC43T4W4+hKd43I76zD3C8Y97e+MbryhzGIXaxBgx5GOGQgZVO4WeSn5Tn4Ys2CMoJJgTJnvh0QQ7Y962ppH1xcActgPLnuxXpW49Btv0nM5IcfL1gCyEConZ5GfnAoEyI9jc7S1W21tEJltFywysVeABKqjfcxiAGIa5Ok92WRA\/i3oezhyz4popcezW2o++MH3IAxFeNWRgVma\/E04V+NINQ5EN+MzRwYFV7sDEIh9djpnzrypFrpMHrPe\/j8anbG8hMmj6E7Bh7wotCSfz4h8FzLa11zjodyEm4nRI8KevS8zdc7j41JgLaNdZWUow2zFzOcqbYCUd9qhHu1t7yce5dxvBS2M0eVtxL8pdTfqXLXMoGbJWVbR2YdDU1mG7ehk\/5EU+bmFQXLO5jgQjx9\/Dxs+a0dRXFq8XyoTGPwQSiTYktnTa878HBPA7f8GRdQTeiO0oO14eMXpMbVxDv\/IAfu5A9EgQSB3cKLMxAkIY2oe2+MH4GdBHZt48cSWDzKuKjDAGks016GUaX0ryVxhz45nQZkH16aeLaCKAu1K9U\/xWQ00zx0RuaK8+B+\/+1gPy0TxyVHm8FwQjOaVq3IalGAWHhvpcakQ6NxOx2hVsJCxlIxMUBgpxv1vVSwip6OdaTuxpCXy6aLAZmIRxcH6SQYef4Db78jOXBsSEEbynBt8Jz8TmrhoXtOQ\/x8lN\/3K4OI5dJAm+KdswO0eUGLw=="}
It looks like a dict with a different Base64 string in the GameData key. However, Base64 decoding, which gives me a bunch of binary data:
02 01 14 c2 a9 69 f2 22 d1 bd 5c 10 7d 6f 96 b4 .....i."..\.}o.. e1 e2 9c 55 a3 51 ac 6d e7 5c a5 dc c2 c2 37 6c ...UQm\....7l 3e 2e 07 7d 89 23 b1 6d 11 6f bf 0e a0 da e4 ab >..}.#.mo..... d9 18 17 4d cc aa 73 d6 17 b9 f7 55 15 ed 60 b9 ...M..s....U..`.
which is incompressible:
>>> len(game_data) 4114 >>> len(game_data.encode("zlib")) 4125
It is not zlib encoded:
>>> game_data.decode("zlib") Traceback (most recent call last): File "<pyshell#126>", line 1, in <module> game_data.decode("zlib") File "C:\Python27\lib\encodings\zlib_codec.py", line 43, in zlib_decode output = zlib.decompress(input) error: Error -3 while decompressing data: incorrect header check
And this is not even zlib without a header:
>>> def inflate(data): import zlib decompress = zlib.decompressobj( -zlib.MAX_WBITS # see above ) inflated = decompress.decompress(data) inflated += decompress.flush() return inflated >>> inflate("roflcopters".encode("zlib")[2:]) 'roflcopters' >>> inflate(game_data) Traceback (most recent call last): File "<pyshell#130>", line 1, in <module> inflate(game_data) File "<pyshell#128>", line 6, in inflate inflated = decompress.decompress(data) error: Error -3 while decompressing: invalid distance too far back
I tried using this online Objective-C compiler along with various classes such as NSUnarchiver , NSKeyedUnarchiver and NSPropertyListSerialization , but so far no luck. It all seems to give a result that at least has recognizable lines in it, so even if they are used, something else should go on.
The only similarity between the different parties was that they all start with 0x0201 . Everything else seems completely different, even for subsequent updates for the same match, which makes me wonder if there is any obfuscation / encryption ...
Any tips on where I can go from here?