This script decodes the date-added timestamps present in the internal $Catalog file created by EnCase for APFS volumes.
The $Catalog file is a collection of APFS directory-entry records each having a key (j_drec_hashed_key_t) and some data (j_drec_val_t).
The 64-bit date-added timestamp represents the time the directory-entry was added to the directory. It follows the 64-bit inode number of the associated file/folder in the j_drec_val_t structure, which is always 18-bytes in length. The timestamp represents the date-added as the number of nanoseconds since 1st January 1970, i.e., the UNIX epoch.
The script will target the records belonging to blue-checked entries in the current view. Alternatively, the record of the entry that is currently highlighted.
The structure of the records in the Catalog file is not always consistent, so the script uses keyword-searching to find each one.
This should work reasonably well provided that each record's key and data is adjacent. Whilst this tends to be the case, it's not always guaranteed - the key and data are rarely stored together on disk.
A copy of each $Catalog file will be cached in RAM the first time it's processed. This improves performance considerably, particularly when locating directory-entry records from the same volume. That said, the examiner should avoid running the script across a large number of APFS volumes simultaneously.
The script uses a .NET DLL to calculate a 22-bit hash based on the inverted CRC-32C of the target file/folder's name as a UTF-32 string.
This hash forms part of the j_drec_hashed_key_t structure; it is used to generate a binary search-term that will exactly match the parent inode-number, hash and name-length (22 and 10-bits respectively), name, and target inode-number of the target record.
On non-case-sensitive APFS volumes, the name of each file/folder is folded to lower-case before being hashed. The script accounts for this automatically by reading the relevant flag from each volume superblock.
The script is unable parse snapshot-volumes because EnCase does not include the volume superblock in its output.
Output is via the console window and bookmarks. The latter will consist of one bookmark for the target file/folder and another for the directory-record that's been decoded.
For more information, please see the following Twitter post:
This script was developed for use in EnCase training. For more details, please click the following link: