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 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/Stanza.app root# ./Stanza dyld: Symbol not found: _OBJC_CLASS_$_UIReferenceLibraryViewController Referenced from: /private/var/mobile/Applications/196F82D9-3A9A-4A4A-AA97-49C55FB28A21/Stanza.app/./Stanza 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 clutch.hackulo.us source), then do the following on the device:
CzajPAD:~ root# clutch Stanza Cracking Stanza... /var/root/Documents/Cracked/Stanza-v3.2.ipa
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/Stanza.app/Stanza 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.
Payload/Stanza.app/Stanza 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!