Reverse Engineering Tools
While developing a tweak, you may find these tools useful to analyze how iOS and apps work, and to find where to interpose your functionality.
The following tools are useful for analyzing a program during runtime.
GDB / LLDB
When writing software, a debugger can help determine what is causing a crash, to find backtrace information on certain points of a program, and so on. Attaching the debugger to normal processes running on the iPhone can be done with the description on debugserver, and see Debugging on iOS 7 for more context.
While not a runtime analysis tool, Logify takes an Objective-C header file containing a class interface and generates a Logos file hooking all methods in the given class, and for each hook logging the call of the method (with parameters) to the syslog. Logify allows for convenient analysis of what methods of a class get called during runtime, and when.
class-dump (described below) can't analyze an executable and generate header files with class interfaces (due to App Store app encryption, other encryption, malformed binaries etc.), another option is to get these definitions from the runtime.
weak_classdump is a Cycript tool which attaches into a project and generates
class-dump-like output files.
weak_classdump can be used to dump a single class, like this:
iPhone$ cycript -p Skype weak_classdump.cy; cycript -p Skype 'Added weak_classdump to "Skype" (1685)' cy# weak_classdump(SkypeAppDelegate, "/tmp/") "Wrote file to /tmp/SkypeAppDelegate.h"
It can also be used to dump all the classes in a bundle (in this case, the main bundle):
iPhone$ cycript -p Skype weak_classdump.cy; cycript -p Skype 'Added weak_classdump to "Skype" (1685)' cy# weak_classdump_bundle([NSBundle mainBundle], "/tmp/SkypeHeaders")
weak_classdump section of Cycript Tricks for another example.
InspectiveC allows you to log message hierarchies of certain objects, classes, and selectors. It is very useful if you're trying to figure out how a certain method or class works without having to go into the assembly. You can temporarily use InspectiveC in your tweak to log objects as needed.
The following tools can be used to analyze an executable.
Clutch decrypts app executables, plugins and frameworks. Requires iOS7 and above:
iPhone:~ root# Clutch -b com.atebits.Tweetie2 ... Finished dumping com.atebits.Tweetie2 to /var/tmp/clutch/2AC9E1CA-450D-4267-8601-D76375B0354B Finished dumping com.atebits.Tweetie2 in 27.3 seconds iPhone:~ root#
App Store app executables are encrypted. dumpdecrypted can generate a decrypted executable out of it:
iPhone$ DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/mobile/Applications/.../Application.app/Application iPhone$ ls Application* Application #original executable Application.decrypted #decrypted, generated executable
(Or see weak_classdump above.)
class-dump, class_dump_z, classdump-dyld
From a given executable, class-dump and class_dump_z will generate header files with class interfaces. (class-dump may produce better headers than class-dump-z for recent binaries.) This allows for an analysis of what methods exist in the executable, which can help you guess which ones to hook to get given functionality.
All default (private and public) libraries on iOS are combined into a big cache file to improve performance in
/System/Library/Caches/com.apple.dyld/dyld_shared_cache_armX (see dyld_shared_cache for more details). If you want to class-dump private frameworks, you can either install Xcode and class-dump the frameworks on your Mac using the above tools, or you can use classdump-dyld, which works right on your device (classdump-dyld can also be installed via its package hosted on BigBoss). Remember that the resulting files are not the original headers, so use them with caution.
You can also find other developers have done this process for many frameworks and compiled this information into repositories:
Disassemblers are useful when you need an in-depth analysis of a binary. These programs convert the compiled code into assembly for your examination. Assembly is hard to understand for beginners and is platform-dependent (ARM assembly is very different from x86 assembly), so you need a good knowledge of assembly to find disassemblers useful. For disassemblers to work with applications from the App Store, the executable has to be decrypted.
It is a commercial application, and it requires some time getting used to it. For analyzing Objective-C applications, KennyTM's fixobjc2.idc script is useful for exposing Objective-C method definitions and calls.
Hopper is quite new and only supports a small subset of the features that IDA has. It is fast and has a nice user interface. However, the produced assembly code is not as good as the one produced by IDA.
The otool command displays specified parts of object files or libraries. It can also disassemble:
bash$ xcrun -sdk iphoneos otool -arch arm64 -tV FaceCore /Applications/Xcode.app/.../PrivateFrameworks/FaceCore.framework/FaceCore: (__TEXT,__text) section 0000000000001100 stp fp, lr, [sp, #-16]! 0000000000001104 add fp, sp, 0 0000000000001108 stp x20, x19, [sp, #-16]! 000000000000110c sub sp, sp, #16 ...
strings is a simple utility that will print all the strings in a given binary.
bash$ strings crash_mover moveLogsAtPath Could not open and lock %s: %s. Proceeding with copy anyway. Extensions ...
nm is a utility that displays the symbol table of a given binary.
bash$ nm CoreTelephony 000234c4 t +[CTCall callForCTCallRef:] 0001ee90 t +[CTEmailAddress emailAddress:] 000199b8 t +[CTMessageCenter sharedMessageCenter] 0001db54 t +[CTMmsEncoder decodeMessageFromData:] ...