Mach-O Helper Toolset.
As some of you may have already been aware, for the past few weeks I have been working on Libhelper. This is a small library aimed at assisting the handling and parsing of Mach-O files, Image4 files and other things related to iOS Security analysis.
To test the library I had been writing a few tools - two of which I'm releasing today. I've also been working on HTool but that is still a little while off yet.
The tools I'm releasing today as part of the "Mach-O Helper Toolset" are macho-section
and macho-split
. There is not much to go over with the tools themselves, so I'll give some quick usage information and then discuss the toolset and my plan for it in the future.
Mach-O Section Tool
The aim of macho-section
is to quickly carve out a segment/section of a Mach-O file. So, for example, if you would like to rip __TEXT.__const
from a Mach-O you can do so like so:
$ macho-section kernel.macho __TEXT __const
-----------------------------------------------------
macho-section 1.0.0 (macho-helper-100.14.1) - Built Thu Jan 9 00:00:33 2020
-----------------------------------------------------
Attempting to seperate __TEXT.__const from kernel.macho
Wrote file to __TEXT.__const.dat
$
You'll then have the relevant file available, so if you extracted a section with executable code you could pass that to a disassembler.
Mach-O Split Tool
The macho-split
tool takes a Universal Binary / FAT file that contains multiple Mach-O's of different architectures and splits them into individual Mach-O files. Here is an example:
$ macho-split some_fat_fil
-----------------------------------------------------
macho-split 1.0.0 (macho-helper-100.14.1) - Built Thu Jan 9 00:03:15 2020
-----------------------------------------------------
[*] some_fat_file: Mach-O Universal Binary. Found 4 architectures.
some_fat_file (for architecture x86_64): Mach-O 64-bit Executable x86_64
some_fat_file (for architecture arm64_32): Mach-O 32-bit Executable arm64_32
some_fat_file (for architecture arm64): Mach-O 64-bit Executable arm64
some_fat_file (for architecture arm64e): Mach-O 64-bit Executable arm64e
[*] macho-split00.x86_64 ...done
[*] macho-split01.arm64_32 ...done
[*] macho-split02.arm64 ...done
[*] macho-split03.arm64e ...done
You can then handle the Mach-O's how you'd like. The following example demonstrates HTool analysing the segment commands for macho-split-01.arm64
$ htool -l macho-split01.arm64
HTool Version 1.0.0~Alpha; Tue Jan 7 22:39:25 2020; libhelper-1000.836.27.12/BETA_X86_64 x86_64
LC 0: LC_SEGMENT_64 Off: 0x000000000-0x100000000 __PAGEZERO
No Section 64 data
LC 1: LC_SEGMENT_64 Off: 0x100000000-0x100084000 __TEXT
Off: 0x100004b30-0x10004ed20 303600 bytes __TEXT.__text
Off: 0x10004ed20-0x10004effc 732 bytes __TEXT.__stubs
Off: 0x10004effc-0x10004f2f0 756 bytes __TEXT.__stub_helper
Off: 0x10004f2f0-0x10004f9c0 1744 bytes __TEXT.__const
Off: 0x10004f9c0-0x100083c6e 213678 bytes __TEXT.__cstring
Off: 0x100083c70-0x100083ff8 904 bytes __TEXT.__unwind_info
LC 2: LC_SEGMENT_64 Off: 0x100084000-0x1000d0000 __DATA
Off: 0x100084000-0x100084020 32 bytes __DATA.__got
Off: 0x100084020-0x100084208 488 bytes __DATA.__la_symbol_ptr
Off: 0x100084208-0x1000842a8 160 bytes __DATA.__const
Off: 0x1000842a8-0x1000c0ebc 248852 bytes __DATA.__data
Off: 0x1000c0ec0-0x1000c9684 34756 bytes __DATA.__common
Off: 0x1000c9688-0x1000ce420 19864 bytes __DATA.__bss
LC 3: LC_SEGMENT_64 Off: 0x1000d0000-0x1000d7000 __LINKEDIT
No Section 64 data
...
Mach-O Helper Toolset
Now to discuss my aims for this "Toolset". As I develop and test libhelper I'll probably write more of these - in fact if you look at the sourcecode you'll see macho-dump
which aims at dumping bytes from a start address for a given size. So more of these tools will be added.
Next is the way I'm versioning the toolset. All the tools are built from the same source file, libhelper/tools/macho_toolset.c
to be specific, so I decided I needed a way of both keeping track of individual versions of the tools, and that single codebase as a whole. Therefore, there is the toolset version, and the actual tools version. Here's an example:
$ macho-section -v
MachO-Helper macho-section Version 1.0.0 (macho-helper-100.14.1)
Build Time: Thu Jan 9 00:00:33 2020
Default Target: darwin-x86_64
Libhelper: libhelper-1000.836.27.12
Toolset: macho-helper-100.14.1
This is the -v
version output for macho-section
. First we see the version for macho-section
as version 1.0.0, beside that the version of the toolset - macho-helper-100.14.1
. Underneath is some more detailed information such as the compile time (to further help me keep track of things), the target as this will eventually work on both arm64 and Linux and the version of Libhelper linked against the toolset.
Summary
So, time for the download links! You can grab the tools from the Downloads which will also list historical downloads. Libhelper is not yet available as a pre-compiled library, however feel free to compile it and submit any changes you'd like to see on it's GitHub.
Thanks for checking this out, let me know about any suggestions and/or issue you have on Twitter.