HFSleuth − HFS+/HFSX file system inspection tool
HFSleuth [ commands ... ]
HFSleuth is an powerful tool meant to interface with, diagnose, and potentially fix HFS+ and HFSX file systems. It offers the ability to inspect and traverse these filesystems on mounted or unmounted partitions, as well as disk image files (.dmg). The HFS+ logic is entirely self contained and written from scratch, and uses only POSIX APIs, making it suitable for use on other UN*X like systems (e.g. Linux).
The tool requires read access to raw disk (/dev/rdisk*) files to work with unmounted partitions, a permission usually given only to root/operator. For DMG manipulation, it requires no permissions other than the obvious readability of the DMG file.
While originally accepting (many) options, HFSleuth is, at present, designed to be used interactively. This makes sense, considering the processing required when loading an HFS+/HFSX file system. The tool is easily scriptable, as it accepts its commands from standard input (<)
HFSleuth provides a rich command line environment. Typing "?" or "help" will display the list of the commands. Commands may be abbreviated, so long as the abbreviation is not ambiguous.
HFSleuth> ? dump Dump B-Tree node from current B-Tree listfs List all mounted file systems and their types alloc Output the allocation bitmap to an HTML file fs Set active file system for operations to specific mount point or device attributes Display the Attribute B-Tree details catalog Display the Catalog B-Tree details volinfo Display the volume header of the selected file system snapshot Save a snapshot of the current B-Tree (catalog or attribute) search Search for leaf by CNID debug Toggle Debug traces on/off verbose Toggle verbose mode on/off color Toggle color on/off xml Toggle XML Output on/off pull copy file to /tmp (requires active file system) dir list files (requires active file system) - synonymous with ls ls list files (requires active file system) - synonmous with dir cd Change directory (requires active file system) help Display this help ? Display this help ! Shell command quit Quit this program version Display version
fs filesystem
Specifies which file system HFSleuth will operate on. The argument can be a disk special device, mount point (OS X only), or a DMG file. HFSleuth will read the filesystem, optionally reading through any Apple Partition Map (APM) or GUID Partition Tables (GPT) to automatically locate a suitable HFS+ (or HFSX) partition. The HFSleuth prompt will change to display the volume label of the selected filesystem, along with the current working directory (initially, "/", the root).
Running this command later with no argument will display the currently selected file system. Running it again with a different argument will change the selected file system to another.
listfs (OS X or iOS only, not Linux)
Displays a list of presently mounted HFS+ or HFSX filesystems, along with their mount options.
volinfo
Displays the HFS volume header of the currently selected file system. Output is similar to the following
SIG: 2b48 This is a drive of 464.785156 GB Volume Header: Signature: 0x482B (H+) Version: 4 Attributes: 80002000 - journaled, Number of Files: 852022 Number of Folders: 212377 Free Blocks: 76658969 Total Blocks: 121840668 Block Size: 4096 ClumpSize: 65536 Created on: Sun Oct 9 03:38:34 2016 Modified on: Mon Nov 14 12:24:49 2016 Next CNID: 2455931 Catalog B-Tree: 129792 blocks from 562573 Attribute B-Tree: 148992 blocks from 16269 Last Mounted by: 4846534a (HFSJ) - Journal info block is @e8c
allocation
Displays allocation bitmap statistics. The allocation bitmap (contained in the Volume Header) is a data fork representing all the blocks in the file system. This command will print out the number of available allocation blocks, as well as dump the bitmap into an HTML table view (/tmp/allocation.html). For DMGs, this map is always "perfect" (non-fragmented, one big contiguous chunk with free space at the end). For an actual file system, it can be quite interesting, with "holes".
Note that the resulting HTML file can be downright huge, and can hang safari. I’m working on exporting to a better format (e.g. GIF). This still shows a valuable map of the disk fragmentation.
catalog
This command selects the filesystem catalog to be the active B-Tree, and dumps its details. The catalog holds all the files in the system (but not their extended attributes). The output of this command will be something like the following:
HFSleuth(SSD:/)> catalog catalog B-Tree dump: Tree type: 0 Tree depth: 4 Root node: 25781 First leaf: 42192 Last leaf: 24523 Leaf records 2128800 Total nodes: 64896 Free nodes: 6539 Node size: 8192 Map node: 43264 Compare: CF - Case Folding (case-insensitive)
snapshot
This command saves the entire catalog to a file in /tmp. This is useful for (currently experimental) features, such as snapshot comparison, as well as undeletion of files (assuming their fork blocks have not been overwritten). Note the file created can be rather large, with a size of (catalog Total Nodes * Node size). In the example above, this would amount to 461MB.
search target
Search the file system for a file matching Catalog Node ID (CNID) number, or pathname specified in target. Functionally similar to find(1) -inum or -name, but much faster.
pull pathname
Retrieve the file specified by pathname, and copy it to /tmp. Especially useful for extracting a specific file from an unmounted file system, or from a disk image, even more so on non-Apple OSes.
HFSleuth supports directory navigation commands, presently "cd" and "ls". The "cd" command changes the working directory (and the indication on the prompt), and is symbolic-link aware. The "ls" command functions like an "ls -li", showing the CNID (inode number) and a long listing for each file in the present working directory. It additionally supports the ’-h’, ’-O’ and ’-@’ modifiers (as per the standard ls(1)). HFSleuth also supports the "!" character as a shell escape.
xml |
Toggle XML output on/off
color |
Toggle color output on/off (can also set externally with JCOLOR=1)
debug
Toggle debug output on/off. Useful for gaining insight into what happens "behind the scenes" (such as B-Tree lookups), as well as finding bugs. May be very verbose. (can also set externally with JDEBUG=1)
HFS+/HFSX use UTF-16, in PPC (big endian) format. Most UNIX terminals use UTF-8. HFSleuth therefore emits all of its output in UTF-8, and translates its input to UTF-16. This has been tested with various languages and character sets, but it is more than possible something in the Unicode translation logic is buggy. If you can’t see or access your favorite UTF-16 encoded file, just let me know.
HFSleuth first accompanied the author’s book, "Mac OS X and iOS Internals - To The Apple’s Core". The tool is provided as one of the free downloads provided for the book, and the latest version can always be obtained at http://www.newosxbook.com/. HFSleuth shares no code with any open sources, Apple’s or otherwise. It relies on zlib and bz2lib for decompressing disk images.
The inspiration for HFSleuth came from Amit Singh’s "HFSDebug", which accompanied his excellent tome "Mac OS X Internals - A systems approach" (http://www.osxbook.com). That tool, however, has only been supplied as a PPC binary, which made it incompatible with OS X as of Lion, when Rosetta (the PPC emulation) was removed. Additionally, it has been superseded by FileXRay, a commercial tool.
\x00\x00\x00\x00HFS+ Directory Data, being a directory name containing NULL bytes, is improperly displayed in "ls". This will be fixed sometime in the future, as it breaks the elegant unicode logic implemented (thanks, Apple!)
Experimental functions deemed too unstable may not work in the publicly available version of this tool (and would likely be entirely disabled). If you feel daring, and would like to assist in beta-testing and improving this tool, simply contact the author anytime. Comments and suggestions for improvements are naturally welcome at the book's forum.
11/11/2016 - Development resumed,
- support for file compression (type 4, zlib) added | |
- support for file compression type 8 (for MacOS compression as of 10.10) |
put
The inverse of pull, allows uploading a file to an HFS+/HFSX partition or DMG.
support for file compression type 8 (for MacOS compression as of 10.10)
Extensibility via DYLD_INSERT_LIBRARIES/LD_PRELOAD
Allowing third party libraries to provide callbacks which will be called from HFSleuth
hdiutil(1)