Code Painters The Art of Coding


How to make Stanza work on iOS 4

Stanza is my personal preference when it comes to ePub readers for iPad. Good performance, very comfortable user interface and, last but not least, it's free! Unfortunately, after upgrading to version 3.2 it doesn't work any more on iOS 4.x and I don't want to upgrade my jailbroken iPad yet.. But hey, there's a relatively easy workaround. All you need is a jailbroken iDevice and a hex editor.

The problem

The actual reason for the application crashing on iOS 4.x is simple - it uses new functionality available only on iOS 5. It can be easily checked - open ssh session to your device and try the following (use find / -name Stanza first to check where the application binary is - the exact path is different for each installation):

CzajPAD:/User/Applications/196F82D9-3A9A-4A4A-AA97-49C55FB28A21/ root# ./Stanza 
dyld: Symbol not found: _OBJC_CLASS_$_UIReferenceLibraryViewController
  Referenced from: /private/var/mobile/Applications/196F82D9-3A9A-4A4A-AA97-49C55FB28A21/
  Expected in: /System/Library/Frameworks/UIKit.framework/UIKit

Trace/BPT trap: 5

Clearly the application binary depends on UIReferenceLibraryViewController class which is a new addition to the UIKit - a dictionary service to look up the definition of a word or term from within an app. Unfortunately, the application doesn't use any sort of dynamic loading to access this new API, which renders the binary incompatible with iOS 4 - apparently it wasn't important for Stanza developers. Let's get rid of this cumbersome import!

Step 1: decrypt the binary

The iOS application binaries are stored encrypted, so it's necessary to decrypt it before doing any changes. In the old days it was necessary to use gdb for that task. But these days it's even easier, as there are tools performing all the steps automatically. Let's do it with Clutch. Use Cydia to install it (add source), then do the following on the device:

CzajPAD:~ root# clutch Stanza
Cracking Stanza...

That's it! Use scp to copy the ipa file to your Mac or PC, and unzip it (yes, ipa files are zips, actually). After unzipping you should find Payload/ file - that's our target.

Step 2: hack the imports

The idea is to substitute the name of non-existent class with another one, available on iOS 4. Of course, this will not give you the missing functionality, but it will remove the load-time unresolved dependencies and thus let the application start. Note, that this only works thanks to dynamic nature of Objective-C (i.e. individual methods are not resolved at load time). Everything works fine as long as you don't try to use the dictionary.

Open the Payload/ file in your favorite hex editor (e.g. Hex Fiend for Mac) and search for UIReferenceLibraryViewController occurrences, replace it with UIViewController (there should be 4 occurrences). The new string is shorter, but be careful to overwrite existing bytes, don't insert or delete any bytes. Remember to null terminate a new string, the reminder of the original string can be left as is.

Step 3: update the application

It is possible to zip back the modified ipa file and install it using e.g. Installous, but I think it's not worth the effort in this particular case (unless you want to share the patched application with other jailbroken iDevices). You can as well copy back the modified binary to your iPad using scp, replacing the original one. You're done, enjoy Stanza running on your iPad again!

Of course, Stanza will complain if you try to use dictionary (see below), but everything else works just fine!

  • Facebook
  • Digg
  • Twitter
  • LinkedIn
  • Google Bookmarks
  • Reddit
  • StumbleUpon
Comments (0) Trackbacks (0)

No comments yet.

Leave a comment

No trackbacks yet.