Introduction
HTool is a simple analysis tool originally based on otool, which is shipped with Xcode Developer Tools, and inspired by jtool created by Jonathan Levin. In the long term, I plan for HTool to have a wide range of functionality from analysing Mach-O files, Kernel’s, iBoot and SecureROM, quick disassembly of binaries, working with DYLD Shared Cache’s etc. HTool will also ship with Mash, or Mach-O Shell, which aims at providing an lldb-like interface for analysing the types of binary that I’ve just mentioned, along with disassembly. HTool is designed to primarily run on macOS and iOS, however support for Linux is being actively worked out and will come soon.
There are no dependencies. You will be able to download and run with (hopefully) no issues. HTool heavily relies on Libhelper for it’s Mach-O capabilities, which is Opensource. You can check out Libhelper here. However, unlike Libhelper I have no current plans to Opensource HTool, but please refer to the FAQ for more on this. You can also skip to Downloads if you aren’t interested in the docs.
h3@kirkwood % htool --help
-----------------------------------------------------
HTool Beta - Built Wed Jan 15 20:03:23 2020
-----------------------------------------------------
Usage: htool [options] FILE
OTool Legacy Options:
-h: Dump Mach-O (or DYLD Shared Cache) header
-l: List Load Command/Segments in the binary
-L: List shared libraries used
-S: List Symbols
Analysis Options:
--hex: Hexdump
-k List Kernel Extensions (KEXTs)
-K Extract Kernel Extension by Bundle ID
-s Split a SEPOS Firmware image
Disassembly Options:
TODO
Environment Variables:
H_ARCH Select an Architecture. x86_64, arm64, arm64e.
I’ll go over each of these options one-by-one and briefly discuss the uses for each.
OTool Legacy Options
I decided to implement a number of otool’s standard features, the majority of which I’ve built on and expanded so now fall under other areas. However, a couple haven’t changed much so that’s what I’ll cover first.
Dump a Mach-O Header
As I have already discussed in my first blog post about Mach-O files, they have formatted headers so one can identify what the file does, how much data it holds and how to load it. Printing this header is easy - run htool with the -h command, followed by a path to a file. In the case of the next few examples, I shall use lldb as the file path which can be identified using the following command: $(which lldb).
HTool -h command example.
The output is fairly self-explainatory. One can see the files magic, which should be 0xfeedfacf in the case of a 64-bit file, and 0xfeedface in the case of 32-bit files. Again, as I outlined in my article there are multiple types of Mach-O and this is identified by the Type: Mach Executable line. The CPU type, this being a single-architecture binary (more on that later), is shown as arm64, however this output can also represent sub-architectures such as arm64e or arm64_32. Finally are the number of Load Commands and the size of the region containing them.
Now, there are multi-architecture Mach-O’s. They’re FAT files, or Universal Binary as they’re called by Apple. They have a small header which details each architecture and where it begins. HTool can handle these too and prints them out in a fashion similar to file.
h3@kirkwood % htool -h <some_fat_file>
HTool Version 1.0.0~Alpha; Sat Jan 11 20:26:52 2020; libhelper-1000.861.67.4/BETA_X86_64 x86_64
[*] /Users/h3adsh0tzz/Research/binaries/JTool/jtool_old: Mach-O Universal Binary. Found 4 architectures.
/Users/h3adsh0tzz/Research/binaries/JTool/jtool_old (for architecture x86_64): Mach-O 64-bit Executable x86_64
/Users/h3adsh0tzz/Research/binaries/JTool/jtool_old (for architecture arm64_32): Mach-O 32-bit Executable arm64_32
/Users/h3adsh0tzz/Research/binaries/JTool/jtool_old (for architecture arm64): Mach-O 64-bit Executable arm64
/Users/h3adsh0tzz/Research/binaries/JTool/jtool_old (for architecture arm64e): Mach-O 64-bit Executable arm64e
To actually use HTool on one of the listed architectures, see the H_ARCH environment variable.
Dump Mach-O Load Commands
Load Commands define a lot about a Mach-O, and especially for iOS Kernel analysis they can be a useful source of information as Apple add and remove a range of segments between major versions. You can print all the commands in a file with the -l option. Each command is labelled from 0 to however many commands there are, this is in the order of which they appear in the raw binary. As much data is put onto a single line as possible, so one can grep through. The way this is formatted is inspired by jtool.
HTool -l command example.
A quick example of using grep on HTool output, the following demonstrates using grep to find the __DATA segment from the output. The command grep -5 displays 5 lines before and after the thing you’re looking for is found.
HTool -l command example (grep).
Please note, not every single command is implemented. If you are working with a file and the data beside the load commands name is blank please report it to me so I can add that command to both HTool and Libhelper. Another thing you will have most likely noticed is the (placeholder) string next to each section. This is a planned feature that will display a short description of the sections, for example __TEXT.__text will have (Normal) beside it, __TEXT.__cstring will have (C-String Literals) etc.
Dump Mach-O Shared Libraries
The LC_LOAD_DYLIB commands from the -l output can be viewed in more detail with -L, which prints the Shared Libraries. Some extra version information is printed with this command.
HTool -L command example.
List Symbols
The symbol listing functionality is similar to that of nm. This is still a bit of a shakey feature as some of it’s functionality is not implemented, or not implemented fully, nevertheless it’s included in this beta.
You can list the symbols of a Mach-O with the -S option along with the path to the file.
HTool -S command example.
Analysis Options
Hexdump
During testing I wrote a hexdump rip-off to check areas of files I had loaded, and ended up implementing it as it’s own operation. It acts the same as the hexdump command.
HTool --hex command example.
List Kernel Extensions
Handling kernel extensions is - so far - the most advanced feature. HTool can handle both styles of iOS Kernel Cache with Split and Merged KEXTs. There are two options currently, listing and extracting. You can list the KEXTs within a kernelcache with -k.
HTool -k command example.
Each KEXT is listed with it’s kernel pointer, Bundle ID and version. In the case of the new, Merged-style caches the pointers are untagged because it’s easier that way, but I can change that if enough people request it.
Part of my Kernel cache analysis framework(?) is demonstrated here. The type, version and compile date can be detected, along with the amount of KEXTs contained. I’ll expand this further in the coming weeks.
Extract a Kernel Extension
Once you have a list of the KEXTs, or if you already know which one, use the -K options to extract it. The format for this command should be -K BundleID filename.
HTool -K BundleID filename command example.
Also in this example I demonstrate some of the features I’ve already covered for identifying and confirming that the extracted file is indeed a Kernel extension.
Split SEPOS Firmware
Last, but certainly not least, is extracting SEPOS components from a decrypted Image4. This functionality is currently available in Img4Helper, however I felt it was more at-home in HTool. I won’t be removing it from Img4Helper, or at least not anytime soon.
To extract a SEPOS firmware image, use the -s option. Ensure you get the case correct, because -S is nm.
HTool -s command example.
Again I expand on this a bit more with some very basic analysis by looking at the header of the SEP kernel and it’s __DATA segment. I’m planning to get analysis for SEP, iBoot and other firmware components like was demonstrated with the Kernel and KEXTs.
Environment Variables
There is only one environment variable implemented at the moment, that is H_ARCH. There will be more in the future if more are needed.
H_ARCH
Not much to discuss here, if you are working with a FAT file just make sure you set this env to the architecture you want to work with, for example (Apologies for the spelling mistake):
HTool H_ARCH env example.
Summary
If you read through all of this, thank you. I hope I made sense but if there is anything you’re still unclear about then feel free to ask me. These docs will be updated as I release new versions of HTool.
(Expected) Frequently Asked Questions
-
Opensource?
– No, not yet at least. I haven’t made my mind up whether I’ll opensource it or not. With Libhelper I felt there was a good use for it being opensource. I may turn some of HTool into a library but that’s not a promise. -
Does it support 32-bit files?
– No, again not yet. This, however, is on my list of TODOs because it annoys me too. This is primarily a change that needs to be made to Libhelper, so feel free to contribute and help me out :-). -
Where is Mash?
– Mash is still in early development and I’m prototyping things. I’d hope to have a beta released sometime in Feburary. -
It’s crashed
– I’m not suprised, it’s early days. Let me know on Twitter and I’ll get it fixed for the next release. Please give as much detail as you can, and test on the latest version if you can - since I may have already fixed it.
Downloads
I’ll keep historical downloads here in case I break something with a new release.
Version 1.0.0 (Beta 1)
Initial release of HTool, currently most functionality is either limited, not included or buggy, but it’s in a fair state for a beta release (at least by Apple’s standards). New functionality will be added with subsequent releases.
Linux support is on the way, but don’t hold your breath for it.
| Platform | Version | Link |
|---|---|---|
| macOS | htool-v1.0.0-b1 |
Download Latest |
| iOS | htool-v1.0.0-b1 |
Download Latest |