IDA Pro

From iPhone Development Wiki

Crucial Performance Tips

  • Close the function window while analyzing to speed up processing about 10 times, typically.
    • Initiating a search in the Functions window while analyzing will slow down IDA to the point of insanity. Don't do this if you plan on REing anything before the heat death of the universe.
  • When analyzing massive files, close all of the windows inside IDA (IDA View-A, functions, output, etc). Processing will speed up anywhere from 5x to 100x.
  • Disable Lumina. If enabled, it will irreversibly "fix" names by setting them to completely incorrect values. This will waste your time and hurt your analysis.
  • IDA seems to operate on one thread. This means when doing anything remotely intensive, it will appear to freeze. This is normal. Don't Force Quit.
  • If you're on an OS with the ability to create "desktops", it's suggested you give IDA it's own. It will block your UI while loading otherwise.

A majority of the information in this article details the process of reverse engineering using the dyld_shared_cache, as doing such is poorly documented in official documents.

Terms used

  • "Module" represents a Framework or library located in the dyld_shared_cache.
  • "Segment" or "Module Segment" refers to a specific segment of a framework.
    • The text segment contains code.
    • IDA 7.3 and greater include the ability to load only data segments on-demand without processing the text segment.

Analyzing the dyld_shared_cache in IDA Pro 7.3 and later.

Helpful link: https://www.hex-rays.com/products/ida/support/idadoc/1705.shtml

IDA 7.3 and later includes a powerful, improved shared cache toolkit. It eliminates the need for simulator binaries, and makes analysis possible when you cannot get access to simulator binaries (InternalUI builds, no macOS, no x64 decompiler, etc.)

Everything described here was performed on a licensed copy of IDA Pro 7.5.


Analyzing a specific framework from the dyld_shared_cache.

Do not "Load module and dependencies" option on "high level" frameworks. In iOS 13, with SpringBoardHome this results in loading 720 modules. This takes upwards of 2 to 3 days on an 8-core 4GHz 32GB-of-ram PC. In newer versions, due to consolidation, that number is down to ~400. You'll still be unable to use your PC for a few days at best.

IDA 7.3 introduced powerful new tools for dealing with the cache. You can now load a single module and selectively load only segments you need from other locations in the shared cache. It can be a pain, but the alternative is much, much worse.

Load the framework you're interested in

  1. Select the "Load single module" option. Ensure you do not select "with dependencies".
  2. Wait for the module you selected to load. It shouldn't take long.

For this example we'll be using FrontBoard.framework.

Loading is the easy part. Now we get to go through the process of correcting IDA's failures, as certain functions tend to fall apart in the dyld_shared_cache subsystem.

Red addresses

Swap to the "IDA View", as it doesn't work properly in the pseudocode view, and right-click a red address. We are going to assume that the one you clicked was a reference to libobjc.dylib, although it could be any library or framework in the cache.

You'll see an option to load "libobjc.A:__OBJC_RO" or something similar, or an option to load the entirety of "libobjc.A". If you don't need to reverse the contents of "libobjc.A" (you don't), you should simply load only the segment IDA suggests. This allows you to avoid absolutely destroying your RAM and CPU when working in the cache, while also allowing you to make sense of the code within it.

If the address is still red:

IDA likely failed to recognize any information in the segment. This can be caused by a damaged database, if IDA crashed while processing data.

Click the address and you'll be taken to the memory location, and if that assumption is correct and you can see vertical strings of letters:

  • In the Menu, click Edit -> Other -> Objective C -> Reload Objective C Info, then navigate to the function you're disassembling.
  • Right-click the red address and re-load the segment. Check "Do not show again for this session" unless you like repetition.
  • In the Menu, click Edit -> Other -> Objective C -> Reload Objective C Info (yes, again).
  • Right-click the far left string on the IDA View that holds the name of your target framework.
  • Load the entire framework (2nd option), not a specific section.
  • Right-click the red address and load the segment again.

Your address is probably still red. If so, you've damaged your database. We'd advise deleting the database and starting from scratch. This is the fastest option.

off_xxxxxxxxx (random hex address prefixed by "off_") in your assembly

What causes this?

These represent data variable offsets. You're most likely looking at a class ref or similar objc item that failed to load.

Fix

  1. In the IDA View, double-click the off_x variable to be taken to the classrefs segment
  2. Right-click the red memory address and load the suggested module segment.

A name will appear. Good. Go back to your function.

  1. Edit -> Other -> Objective C -> Reload Objective C Info

If it changes from off_x to selRef, classRef, or something similar, you can move on.

If it does not change, see below

What causes this?

IDA improperly guessed the type of a struct it loaded due to a missing segment.

Fix

  1. Double click the pink text if you haven't yet to be taken to the class definition in __objc_data
  2. Click the _OBJC_CLASS... item to select that line
  3. Open Edit -> Struct Var
  4. Select objc_class and hit OK
  5. A red memory address will appear. Load that segment.
  6. Make your way back to your function that you're disassembling.
  7. Edit -> Other -> Objective C -> Reload Objective C Info

Repeat this for any variables you feel are worth spending the time correcting.



Working with pseudocode from the dyld_shared_cache

Something you'll likely become familiar with is the statement (self + 10), where 10 is any 2 digit number. In objc source, you would see this as an ivar. If you've loaded in the relevant class information, you can help IDA display these ivars properly in the pseudocode view like so:

  • Right-click the a1 or self variable on line one
  • Click Y or "Set ivar type"
  • Change the class of self/a1 to the class shown next to it.
  • Change a1 to self if need be

Ivars should now be properly generated and shown in pseudocode.



Simulator Binaries: the recommended solution on older IDA versions

The iOS simulator runtime is for you. x64 binaries that don't have the "Red Address" issue are available.

Find them here: /Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 12.4.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks

You may need to change the name of the folder for the simulator versions you have downloaded and installed.

Types and Functions Definitions

IDA Pro does provide you a limited amount of types and functions definitions from Objective-C. The binaries however may import more functions or pack more types that IDA Pro does not have knowledge about. For example, the parameters of dispatch_async function may not be detected correctly. It may have only one parameter or not at all, making your binary analysis more difficult, not to mention when you work on different binaries and you face many other incorrectly typed functions. Use https://github.com/PoomSmart/IDAObjcTypes to import the types and definitions to fix this once and for all.