Reverse Engineering Tools

From iPhone Development Wiki
Revision as of 14:28, 12 June 2020 by Cynder (talk | contribs) (→‎IDA)

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.

Dynamic analysis

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.

Cycript

Cycript allows you to run your own code in an attached process out-of-the-box, with some JavaScript-syntax goodies to make writing code more convenient. It allows for useful runtime analysis of a program (such as for instance getting the complete view hierarchy, or checking out the properties of an object), and it allows for easy prototyping of a tweak (by hooking methods with a Substrate bridge, changing objects freely and calling functions, etc.).

Logify

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.

weak_classdump

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")

See the weak_classdump section of Cycript Tricks for another example.

InspectiveC

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.

Runtime View Debugging

Reveal

Reveal comes with advanced visualisations, comprehensive inspectors and the ability to modify applications on the fly, you’ll be debugging view layout and rendering problems in seconds.

Reveal Loader will dynamically loads libReveal.dylib

Spark Inspector

Spark Inspector has a three-dimensional view of your app's interface and the ability to change view properties at runtime

FLEX

FLEX is an in-app debugging and exploration tool for iOS.

FLEXing will help you load (the up-to-date) FLEX into your applications by holding the status bar.

Static analysis

The following tools can be used to analyze an executable.

Clutch

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#

dumpdecrypted

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

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.

IDA

IDA, or IDA Pro, (Interactive Disassembler) is a popular program for disassembling binaries. It supports a plethora of processors. IDA has tons of features and has been in development for more than a decade. It's typically regarded as the industry standard for Reverse Engineering.

A much more extensive page has been written over IDA on this wiki.

It is a commercial application, and it requires some time getting used to it. For analyzing the dyld_shared_cache, Versions 7.3 and higher have included an integrated "cache subsystem" that allows analysis of specific frameworks in the cache.

In previous versions, Deep Instinct's dsc_fix.py script can be useful for fixing external references in libraries extracted from the dyld_shared_cache. Do note this script is written in python 2, and it is no longer compatible with current versions of IDA.

IDA Pro

IDA Pro is the "Full version" of IDA. The latest released version is 7.5 (changelog)

The standard license cost for IDA Pro + a single Decompiler is about $4248. When purchasing additional decompilers alongside this, each additional one is given a 50% discount, making it slightly more tolerable for an individual.

It's capable of disassembling any of the listed processors, although decompilation must be purchased per-processor, and is very far from cheap.

At the advice of many veteran developers, if you're currently attending university, heavily consider reaching out to your university and seeing about the possibility of them providing a license. Many developers have ended up with their own License going this route.

IDA Home

Although IDA's price model has long been out of reach for most hobbyists, they have made a (fairly poor) attempt at rectifying this with the release of IDA Home.

IDA Home does not include a decompiler, and does not provide the option to purchase one as an add-on.

IDA Home is available for $370 a year and comes with support for a single processor type (for example, an ARM copy will not open x64 binaries at all).

This product is marketed towards "Hobbyists"; Although some may find value, especially in the debugger bundled with it, most would advise against purchasing it. I (kritanta) personally purchased it in order to evaluate whether IDA Pro + Hex-Rays would be worth the price, and felt satisfied with the product, although it's very clear it mainly exists to encourage users into buying Pro.

IDA Freeware

IDA's latest "Freeware" version available is 7.0, available here.

It's capable of disassembling (not decompiling) x64 binaries, so if you intend on opening Simulator Runtime binaries, this will work.

It's a subpar way to evaluate the product as many other free products offer much more than the freeware version.

Hopper

Hopper is a newer disassembler and decompiler that offers an excellent choice for hobbyists that don't have several thousand to spare. Although the pseudocode it offers is lacking, It's more than capable of handling shared caches, arm64e frameworks, and other things IDA also covers.

Do note (as this information isn't listed publicly anywhere) that the Debugger included only works on x64 systems.

otool

The otool command displays specified parts of object files or libraries. It can also disassemble:

Example usage:

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

strings is a simple utility that will print all the strings in a given binary.

Example usage:

bash$ strings crash_mover
moveLogsAtPath
Could not open and lock %s: %s. Proceeding with copy anyway.
Extensions
...

nm

nm is a utility that displays the symbol table of a given binary.

Example usage:

bash$ nm CoreTelephony
000234c4 t +[CTCall callForCTCallRef:]
0001ee90 t +[CTEmailAddress emailAddress:]
000199b8 t +[CTMessageCenter sharedMessageCenter]
0001db54 t +[CTMmsEncoder decodeMessageFromData:]
...