Category Archives: iOS Reversing

Gone in 59 seconds: tips and tricks to bypass AppMinder’s Jailbreak detection

There’s a new attempt at jailbreak detection available at It is mostly aimed at Enterprise applications and not AppStore usage. I am not sure about AppStore rules but those tricks will most probably not pass the approval process.

AppMinder provides three levels of jailbreak detection and anti-debugging measures. The different levels are related to self-integrity checking and code obfuscation rates. When you generate a new protection, it will give you some plug’n’pray code to plug in into your existent code base. It is very easy to integrate. There is some polymorphism on each generation – code is different but the high-level operations will be the same. For my analysis I have used the variant C – self-integrity checking level and code obfuscation rate both high.

The core of jailbreak detection is located in a big inline assembler function with random name on each generation, and in a single line to make it a bit more annoying to read. In OS X you can easily convert it to line by line with sed “s/;/\\`echo -e ‘\n\r’`/g”. IDA has some trouble disassembling it but you can help it by manually defining code. It was late and I did not bothered to verify these IDA troubles.
Continue reading

A little vulnerability in The Heist iOS game or how to get (more) free Steam codes for Eets game!

MacHeist released a great puzzle game called The Heist, promising a prize when you managed to open the safe. Since I am a sucker for puzzle games I bought it and gave a brief check on its code. There is a single url in the program and some references to sha256, this being a good indicator that they thought a little about security. I started playing the game and finally opened the safe. Before collecting my prize I started tcpdump so I could see what info would be exchanged with MacHeist servers. The first detail is that plain http is used and the password for the MacHeist account is sent clear text. It wouldn’t be a big deal in a normal world (just an unimportant account) if most people didn’t reused passwords or slight variations of them. Https could (and should) have been used! Let’s continue…

So the exchange of data had two interesting fields called random and signature. The size of this fields matches the size of a sha256 hash so they are probably hashes. Firing up IDA for the second time and searching for strings, the interesting one is found “prize=%@&random=%@&signature=%@&levelData=%@”. It’s a matter of going backward and finding where those fields are being generated. And here lies the small vulnerability 🙂
There is one little piece of information that is easily controlled by us! The device unique identifier and its name are retrieved and then hashed. So to generate different hashes one just needs to change the device name and voila. There are more operations but there’s no interest in analysing them.
You will also need to mess with the preferences file, there is a field with a very suggestive name that you will need to reset to be able to collect again the prize. I think the preferences folder is available even in unjailbroken devices (using a iOS filesystem browser). The author’s should have crypted/obfuscated the preferences file so it’s not a straightforward operation.

And that’s it. Just a little vulnerable implementation 🙂 Back to work or maybe to finish the game!
Have fun,

P.S.: The game is well worth the 99 cents!

Update: Gdbinit for iOS v0.4 that fixes the missing r12 register and has some code cleanups. I completely forgot to release this one 🙂 Thanks to Luis for remembering me!
SHA256(gdbinit-ios-v0.4.gz)= 5a943545ad58650bd55d7762945b239802b72cb85d8bf700ec7b23e291a7e977

An interview with CrackZ and (incomplete) source code to Contract Killer “trainer”

I just found a nice interview with CrackZ here. He nails the point that curiosity and intellectual challenge trumps above everything else but also demonstrates the process from not caring about the impact of his acts to something more “ethical”. His site is still one of the best resources for Windows reversing, especially regarding dongles.

I have also decided to publish an incomplete version of my trainer for Contract Killer. I see that cheating is widespread so I think there’s not much impact from doing this. If the authors disagree on this feel free to contact me and I will immediately remove it. This code can fully “decrypt” the save file but encryption is missing the crc32 part, so you have to reverse a little if you want to make it work 🙂 No pain, no gain!

Have fun,

SHA256(decrypt.nonworking.c)= 321b641e6c0f3c73417e97420fe6c10baea39c1c262f414b4e00f626db0d7993

P.S.: Updated the source code. I had a stupid bug in a fread where I was reading 4 x int, resulting in overwriting the offset variable when compiled in 32bits. Stupid typo 😉 This new version works fine when compiled either in 32 or 64bits.

P.S.2: Added a new version, which adds error checking and fix a bug when adding the crc32. If you are trying to show an example at least try to do it right 😉

Newsflash: How to fuck up 40 million USD – The New York Times paywall and its iPad app

This will be a story in development, which is kinda of funny taking in account the target in question. I might be wrong on all this but my instinct is hinting me that I’m not.

After the Contract Killer post I got very much interested in verifying these kind of implementations in other apps. This morning I had a flash into my mind about checking what happened with the NY Times app. The so-called paywall was implemented very recently although very ineffectively judging by quite a few hacks around it and some articles questioning the $40 million investment in this system. If the web implementation has problems, I thought that the apps could also have some, so it’s time to research 🙂

As usual I disassembled the binary and started looking around to have a general view of the implementation. Gdb seems to have problems disassembling the binary (alignment issues?) because it doesn’t correctly recognize the instructions 🙁
Anyway, after flagging some interesting methods and execute some initial tests, I remembered to verify how were the articles stored inside the app. Well, they are inside a sqlite3 database and to my surprise, all articles are downloaded in full!!! I did a database dump and could find all restricted articles, with full text. I need to have at least one more day to verify if more issues will be downloaded in full. I would dare to say YES!

What needs to be done is to bypass the two protections: allow to scroll to other pages inside each section (you are restricted to first page inside each section) and allow to read any article inside the restricted sections (a registration required pop up appears and you can’t read everything or change pages). As a bonus, it should also be fun to remove the ads (and the damn usual spyware analytics).

Once again, there is blind trust in the app. Ok I have to concede that the vast majority of iOS users don’t have their devices jailbroken BUT they can still access the filesystem, grab the sqlite3 database, parse it and voila, game over. This is a bad security model! And it’s not that hard in this case to control the data that is sent to the legit subscriber and to non-subscribers.

Back to the disassembler and debugger. Let’s prove if I’m wrong or not on this 🙂


P.S.: No, it’s not a April’s fool joke 😉

Update: My theory was correct and I am now able to read and browse all articles. The protection is more or less like most Mac applications, a boolean flag 🙂 Sucks !!!
There are still some issues, for example in some sections I have to change iPad orientation to be able to browse the available articles. Nothing special and that can’t be fixed by wasting some more time messing around with code. I am a bit disappointed with this implementation, it is really weak and not well thought. NY Times doesn’t seem very interested in having a tight paywall. The method to patch has a suggestive name 😉 Nothing else to see here. Next!!!

Update #2: There is a new version of this App. The old version still works and downloads all the articles. I have tried to patch the new version with the same trick but some articles are deleted (database is empty for those). Without any patch, the articles are still downloaded in full, so most probably there is an additional protection somewhere. Oh well, these guys don’t even make it fun. The paywall seems to be just an excuse for something 🙂
Another interesting result. Refresh articles with original binary, then replace with the patched binary and voila, all articles in full, with the bonus that scrolling between all articles works without any further patch!

Hacking a freemium iOS app: Contract Killer … or unlimited play without spending a dime (or any other currency)

Let me start this post with a little rant. The iPad is a great product but it’s full of spyware and that sucks big time. One might argue that it’s not spyware, it’s just sending bits of information. Well, for me it’s damn spyware because I’m not authorizing the apps to send any information, much less unique pieces of information that can identify you forever. I can’t even conceive why the enterprise world will adopt the iPad with these kind of problems. If I was the CSO or CIO I would fight against this, and I mean real hard fighting. It sucks, seriously! It sucks so much, that I tried to firewall one of the ad networks and it starts connecting to different Amazon EC instances, more or less like a botnet client (this should be an interesting reversing project). The argument of high-availability for such behavior is weak – there are many HA solutions. If I want to firewall your shitty ad-network, let me, don’t try to fight it.
All this spyware crap is one of the reasons why I’m not fully using the iPad for web browsing and other more personal tasks. Apple should allow a Little Snitch like app, so users can have some control about what is going out of their devices. I really like Apple in some points, but this one pisses me off!

Back to the interesting juice… I was reading today some articles and I saw the announcement of this game, Contract Killer, based on a freemium business model – in app purchases. I decided to give it a try. After a while you need to buy energy credits so you can proceed in the game. Of course I was already more interested in exploring a way to remove that limitation than playing (I played a few rounds, it gets boring…). A reversing brain is a dangerous brain 😉

The credits information is written into a save game file. This can be found at the Documents/default folder, with the name savebh.dat (by the way, the app has the name These are binary and seem packed/crypted (by the way, if you want to have fun with virtual fishes and don’t want to wait, you can use the same trick with iQuarium – edit the plist file with the properties, it’s not encrypted nor packed – BBEdit can handle it fine).
Checking around the disassembly (don’t forget you need to decrypt the binary, use Crackulous for example) you find two interesting methods: CBH_XorCrypt::Decypher and CBH_XorCrypt::Cipher (CSaveManager class is also interesting, it calls the encrypt method). If you breakpoint on the Cipher method and try to buy some bullets, debugger will break :-). Prototype is CBH_XorCrypt::Cipher(char *, int), meaning that R0 holds the unencrypted data and R1 its size. Do a x/30s $r0 and see the XML file 🙂

So my idea was to modify memory before it’s encrypted. I tried to modify one byte from the money, by computing the offset from R0 where it’s located and modifying its value – for example, from 500 to 900. This doesn’t work for some reason, probably some further checks. While doing this, I reversed the crypt routine (it’s a simple xor with a table) so I could write a small decryptor.

But before this, I was trying to breakpoint and modify the decryption. It happens when the game is loaded. Since you can’t load it from gdb (it’s not launched into the screen, so you can’t interact with the app), the only solution is to attach gdb. My dirty method is to launch gdb with the following command:
gdb –pid=`ps ax | grep Bounty | grep mobile | awk ‘{print $1}’`

Open the game in iPad and quickly launch this command, so we can attach gdb as soon as possible, hopefully before decryption. Voila, it works. Now the trick is to let the program decrypt the save game, and then modify memory as in the crypt method. Well, it works 🙂 And the new save game will use the new value so it means credits, experience, points, hits, guns, etc etc etc.
Now you just need to code a decryptor/encryptor and customize the whole XML file! Beware that the first 4 bytes in save game are a CRC32 and the next byte is the initial XOR key. I will not publish code on this to avoid any legal trouble (although these guys really deserve something like this due to the amount of spyware crap they use…!!!).

The security model applied here is weak because I have control of the data and I can manipulate it at my own pleasure. One of my ideas about the failure to modify at crypt stage was online storage of information regarding each player. I started sniffing traffic and that’s how I saw the amount of spyware 😉
Probably a large majority of freemium games suffer from this kind of problems if there’s no data synchronization between the app and somewhere I don’t control (as it happens in online games, where only registered keys are allowed to play in servers).

Back to on track to what I was doing before this, damn curiosity!

Have fun, and fuck spyware (yeah I’m really annoyed ;-))

P.S.: I know how metrics are important to business, I’m a firm supporter of that. But how does sending my iPad name, referral cookies and other stuff qualifies as useful and benign metrics? It doesn’t! Developers should record useful metrics such as software versions and other anonymous info that allows them to know their customer base and improve their work but that’s it. Stop there, don’t be fucking greedy and stupid.

P.S.2: Just finished my little cryptor/decryptor. Everything works fine although the game crashes if some fields are abused (trial & error). It’s easier to reverse and rip the program crc-32 implementation – it’s easier and fast. Unfortunately, the game is boring and too repetitive 🙁 I’m addicted to Doodle Jump!

Another update to gdbinit for iOS and ARM support to and

I have fixed some of the missing stuff in gdbinit for iOS. Now the jump conditions are displayed for ARM and Thumb modes and the “stepo” command is working for ARM and semi-working for Thumb (to be fixed in the next release). Also implemented minor cosmetic changes 🙂

The tools to show Mach header information and calculate offsets to be patched were also updated to support ARM binaries. is by default interactive (you can choose from the available architectures in the binary, if fat), and is able to modify the entry point for the architecture you choose. also supports two more options to display only the LC_UNIXTHREAD segment (where the entrypoint is shown) and the LC_ENCRYPTION_INFO (required information to manually dump iOS binaries). It’s time to learn some Objective-C/Cocoa and convert them in graphical apps, although I still prefer command line for day to day operations.

That’s it for now 🙂

SHA256(gdbinit-ios-v0.3.gz)= 90c7117aa33be72c87de66ac6b75d5c60e423539eb399e9faadcf0bd5569fb8b

The latest version can always be found here.
SHA256( 2b091f2ea5fddce3ca22251b8d81578ba708811d4a3d2fdce8ae0c8a7972f1b3
SHA256( 715481e62978c183ccd82311acb6ccced2d12cab76a0c9ffb0345d653bce37ba