As previously described, ".journal" file keeps track of transactions of HFS+/HFSX file system. This time, I would like to show how recover deleted files using .journal information.
HFS+/HFSX file system has special files, which are $Bitmap, $Catalog, $Extents Overflow and $Attributes. Each has a respective role.
- $Bitmap - to keep track of whether each allocation block in a volume is currently allocated
- $Catalog - to maintain information about the hierarchy of files and folders on a volume
- $Extents Overflow - to maintain more than eight extents in the contents of a file
- $Attribute - to store extended attribute of a file
Here we focus on $Catalog. It is organized as a B-tree structure to allow quick searches through a flood of folder hierarchy. A B-tree structure is described by Apple's Site, consist of nodes, each of which contains records, which consist of a key and data. There are four kinds of nodes.
- Header
- Map
- Index
- Leaf
Of these types of node, we have an interest in the leaf node because it holds actual data records.
So let's get back to the previous sample and explore leaf node of $Catalog. We have already known the structure of transaction block. We continue to parse in accordance with the structure, we arrive at a leaf node of $Catalog.
A node begins with a Node Descriptor. Its structure is as follows.
Node Descriptor
Byte Range |
Description |
Value |
0-3 |
Next Node |
0 (0x00000000) |
4-7 |
Previous Node |
0 (0x00000000) |
8 |
Node Type |
leaf (0xff) (0xff:leaf, 0x00:index, 0x01:header, 0x02:map) |
9 |
Current Height of Tree |
1 (0x01) |
10-11 |
Number of Records |
28 (0x001C) |
12-13 |
Reserved |
0 (0x0000) |
(* The value inside of $Catalog is interpreted as big-endian)
This is a leaf node and holds 28 records. Each offset of each record are located at the end of a node. The node size of $Catalog is declared on Header Record in Header Node (spare someone the details). Typically the node size is 4096 or 8192 bytes. Then we can identify each record of the node.
A leaf node of $Catalog contains four different types of data records.
- Folder record
- File record
- Folder thread record
- File thread record
One of the most remarkable type of node is file record because it contains valuable information about a single file. So we focus on one file record. A record consists of key and data. A key structure is as follows.
$Catalog File Key
Byte Range |
Description |
Value |
0-1 |
Key Length |
58 (0x003A) |
2-5 |
Parent CNID |
2 (0x00000002) |
6- |
File Name |
journal_sample_deleted.txt (Unicode) |
In addition, a data structure is as follows.
$Catalog File Data
Byte Range |
Description |
Value |
0-1 |
Record Type |
File record (0x0002) (1: Folder, 2: File, 3: Folder thread, 4: File thread) |
2-3 |
Flags |
0x0082 |
4-7 |
Reserved |
0x00000000 |
8-11 |
CNID |
28 (0x0000001C) |
12-15 |
Created Time |
2013/08/13 13:27:46 UTC (0xCE2FE4D2) |
16-19 |
Last Written Time |
2013/08/13 13:27:46 UTC (0xCE2FE4D2) |
20-23 |
Entry Modified |
2013/08/13 13:27:46 UTC (0xCE2FE4D2) |
24-27 |
Last Access Time |
2013/08/13 13:27:46 UTC (0xCE2FE4D2) |
28-31 |
Last Backup Time |
N/A (0x00000000) |
32-47 |
Permissions |
UID 99 (0x00000063), GID 99(0x00000063), RWX 0644(0x81) ... snip |
48-63 |
User Info |
0x0000000000000000... snip |
64-79 |
Finder Info |
0x00000000520A34520000... snip |
80-83 |
Encoding |
MacRoman (0x00000000) |
84-87 |
Reserved |
0x00000000 |
88-167 |
Extent Descriptor for Data Fork |
Logical Size: 14 (0x0000...000E), Physical Size: 0 (0x00000000), Total Blocks: 1 (0x00000001), StartBlock: 1531 (0x000005FB), BlockCount: 1 (0x01) |
168-247 |
Extent Descriptor for Resource Fork |
N/A (0x00000000 ... snip) |
According to above record, CNID of journal_sample_deleted.txt is 28, and contents is located at block 1531, 14 bytes. Let's take a look at the corresponding file on EnCase.
However it can see neither a file named journal_sample_deleted.txt nor CNID 28. Then what data is located at Block 1531?
This is a contents of journal_sample_deleted.txt. Journal information enables a relationship between metadata such as file name, size, CNID, time stamp, etc.. And its contents. Unlike the method of file carving, it is possible to trace block fragmentation because file record of the structure holds 8 extents descriptor.