Table of Contents

Binary Extraction with Visual Tooling

Olivia Gallucci and Sophia Larson Syracuse half marathon. Used on post about binary extraction.

When source code is unavailable or incomplete, extracting information directly from binaries is the main way forward (“binary extraction”). Command-line tools can help me learn about the symbols, strings, and structure from macOS/iOS binaries.

Binary extraction with visual tooling was tip #6 in one of my macOS reversing blogs. The post was just so long that I decided to separate it out after the fact.

The first tool I’ll cover is…

strings!

Remember this tool from the beginning of the article?! This simple tool dumps all human-readable strings from a binary. It’s often the first step to get hints about a program’s content. 

For example, error messages, format strings, or configuration file names. These clues can tell me what the binary interacts with or provide keywords to search in OSS repositories. 

Usage is straightforward: strings <binary>. For instance, running strings on an Apple crash report handling tool might show output like:

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

Here, I see an error message and function-like token moveLogsAtPath which suggests the binary has a function or method by that name. These can guide me in reversing or searching Apple’s OSS for similar code.


🌸👋🏻 Join 10,000+ followers! Let’s take this to your inbox. You’ll receive occasional emails about whatever’s on my mind—offensive security, open source, boats, reversing, software freedom, you get the idea.


otool

This is Apple’s object file displaying tool (part of Xcode’s CLI tools). 

otool can provide a lot of Mach-O binary information: headers, load commands, symbol table, and even disassembly of sections. 

For example, otool -tV -arch arm64 /path/to/binary will disassemble the text section of a binary for ARM64 architecture. For example:

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
...

otool -L <binary> lists the shared libraries the binary is linked against. otool -lv <binary> will display the binary’s segments and sections layout. 

These details are useful to identify where code vs. data is, and to ensure I am analyzing the correct architecture slice in a universal (fat) binary.

nm

This tool lists symbols from a Mach-O binary’s symbol table. 

It’s especially useful for libraries and frameworks, which often have many exported symbols (public APIs) and sometimes even private symbols if not completely stripped. Running nm can show me function names and their addresses or symbol types. 

For example, using nm on an iOS framework might reveal Objective-C class names (as $OBJC_CLASS_$_Name) or C functions. On macOS, even userland tools can have symbol tables for their external references. 

If I have a dSYM (debug symbols) for a binary, nm on the dSYM will list all the original symbol names, which is invaluable. In the absence of full symbols, tools like dsdump (an improved nm) can also extract Swift and Objective-C symbols from the binary’s metadata. 

class-dump

As mentioned, this third-party tool extracts Objective-C class interfaces from a binary. 

By running class-dump <binary> (or a specific framework binary), I get header files that list the classes, methods, and properties. This is extremely helpful for reversing GUI apps or frameworks where understanding the objects and methods is important. 

For example, using class-dump on the PackageKit private framework and grepping for PKArchive class reveals methods like + (id) archiveWithPath, which might correspond to functionality that a tool (e.g. pkgutil) is using. 

$ class-dump /System/Library/PrivateFrameworks/PackageKit.framework/Versions/A/PackageKit | grep -A 10 PKArchive
@interface PKArchive : NSObject
{
}
+ (id)archiveWithPath:(id)arg1;
+ (id)_allArchiveClasses; - (BOOL)closeArchive;
- (BOOL)fileExistsAtPath:(id)arg1;
- (BOOL)verifyReturningError:(id *)arg1;
- (id)fileAttributesAtPath:(id)arg1;
- (BOOL)extractItemAtPath:(id)arg1 toPath:(id)arg2 error:(id *)arg3;
# Notice the archiveWithPath: class method in the class-dump output.
# Recall this is the method invoked by pkgutil to initialize a archive object.

Even if I don’t have source code, these method definitions tell me what capabilities the binary likely has and where to focus my analysis.

Mach-O and dyld cache extractors

Both macOS and iOS use a unified shared cache for system libraries (the dyld shared cache). On iOS, nearly all system libraries are packed into a single dyld_shared_cache file to optimize performance, and individual .dylib files are not present on the filesystem. 

To analyze iOS system libraries, I often need to extract them from this cache. Apple provides a private utility for this: dsc_extractor (and an Xcode tool target dyld_shared_cache_util). Apple’s dsc_extractor (used internally when I connect a device in Xcode for debugging) can split out the libraries, but the default output is only meant for debugger symbolication (the libraries may not be fully re-usable binaries). 

With some effort, it appears I can compile Apple’s dyld_shared_cache_util from the open source dyld project and use it to extract all dylibs from a given cache (e.g., dyld_shared_cache_util -extract <cache> <output_dir>), but it may require patching the source and using the exact Xcode version Apple used. 

Fortunately, the community has created improved extraction tools. For example, DyldExtractor (and similar projects) wrap around Apple’s extractor but fix issues like Objective-C selector references and segment misalignments, producing nearly perfect standalone libraries. 

Another tool is Jonathan Levin’s jtool, which can directly parse dyld cache files and extract or analyze them. Using these tools, you can get individual system library binaries for inspection in IDA/Ghidra just like normal Mach-Os.

Read more: 

iOS Simulator binaries

An alternate technique for iOS binaries is to leverage the libraries from the Simulator runtime provided by Xcode. The Simulator (which runs on x86_64 or ARM64 macOS) includes copies of iOS system frameworks as separate, un-cached dylibs, often with full symbol information. As of Xcode 12 and later, the iOS simulator frameworks even include an arm64 slice (for Apple Silicon Macs), making them close to the device binaries, but with symbols intact

For some frameworks, I can find a .framework or .dylib in the Xcode bundle under the Simulator runtime path. I can use this for analysis instead of extracting from a device cache. 

This is a huge time-saver, I get function names and sometimes complete public symbols. Keep in mind not all frameworks available on iOS devices appear in the simulator (for instance, anything truly hardware-dependent or not meant for macOS at all might be absent), but for core frameworks, this is great.


🌸👋🏻 Join 10,000+ followers! Let’s take this to your inbox. You’ll receive occasional emails about whatever’s on my mind—offensive security, open source, boats, reversing, software freedom, you get the idea.


Conclusion

In summary, a combination of these tools (strings for hints, otool/nm for structural info, class-dump for Objective-C introspection, and cache extraction tools for iOS libraries) will provide data about the target binaries.

If you enjoyed this post on binary extraction with visual tooling, consider reading macOS Reversing: Bridging Source and Binary with Open Source as a Guide.

Sources, thanks, and where to learn more about binary extraction

Research and blogs

Tools and repos

Wikis and docs

Portrait of Olivia Gallucci in garden, used in LNP article.

Written by Olivia Gallucci

Olivia is senior security engineer, certified personal trainer, and freedom software advocate. She writes about offensive security, open source software, and professional development.

Discover more from [ret]2read

An OS Internals Newsletter by Olivia Gallucci. Subscribe now to keep reading and get access to the full archive.

Continue reading