Skip to content
API Documentation
BastionGuard™
bastionguard-recovery-data Directory Reference

Directories

 
src

Detailed Description

BastionGuard Recovery -- Filesystem-aware data recovery

A C++20 data-recovery component for the BastionGuard Linux security suite. Reads disk images and live block devices to recover files from 6 filesystem families plus a filesystem-agnostic carving pass.

Built from scratch – no external filesystem libraries (no libfsxfs, libhfs, libapfs, libntfs-3g). Only zlib (mandatory) and optionally liblzo2 + libzstd for Btrfs compressed extent decompression.

WHAT IT DOES

Recovers regular files, directories, and (where applicable) symlinks from filesystems on a Linux host. Designed for these scenarios, in order of typical success rate:

  1. Live volumes (= the filesystem is intact, you want copies of specific files): 95-98%
  2. Recently-deleted files (= file removed but blocks not yet overwritten): 60-90% per FS
  3. Quick-formatted volumes (= partition table OK, FS metadata overwritten with new filesystem header): ~85% with carving
  4. Volumes with corrupt MFT / inode table / catalog (= FS metadata partially destroyed): 60-85% per FS
  5. Volumes with destroyed partition tables: ~70% via the lost-partition finder + carving fallback

WHAT IT DOES NOT DO

  • Encrypted volumes (BitLocker, FileVault, LUKS, NTFS EFS, ext4 fscrypt): RECOVERY IS IMPOSSIBLE without the encryption keys. No software can bypass this. The bytes on disk are encrypted; we detect and report encrypted streams but cannot decrypt them.
  • APFS (Apple File System on macOS High Sierra+): out of scope for now – a separate ~5000-line project.
  • ZFS: out of scope.
  • Files whose blocks have been overwritten by NEW data after deletion: physically impossible to recover.
  • Fragmented files via carving: only the FIRST contiguous run is recovered. The rest of the data is lost or appears as garbage bytes from re-allocated clusters.

SUPPORTED FILESYSTEMS

Detection is automatic. Per-filesystem support level:

FAT32 Live files: FULL Deleted files: Best-effort (assumes contiguous, ~70% success) LFN UTF-16 names: YES LFN deleted name reconstruction: YES (where LFN slots intact)

exFAT Live files: FULL Deleted files: Best-effort (assumes contiguous, ~70%) No-FAT-chain optimization: YES (faster on contiguous large files) TexFAT (transactional exFAT): NOT supported (rare)

NTFS Live files: FULL Deleted files: YES (via live MFT scan + $LogFile redo + $MFTMirr fallback) LZNT1 compressed streams: YES (homegrown decoder) Multiple ADS (alternate data streams): YES Reparse points (symlinks/junctions): RECREATED as real symlinks on output (with sidecar fallback) Sequence number tracking: YES (orphan detection) $I30 directory index walker: YES (recovers filenames from corrupted MFT records, handles renames) EFS-encrypted streams: SKIPPED (cannot decrypt, requires Windows account keys); reported in the log USN journal: summary sidecar only

ext4 Live files: FULL Deleted files: YES (dtime != 0 inodes; journal replay) Extents: FULL recursive walk Classic indirect block map: YES (legacy ext2/3 compat) Sparse files / UNINITIALIZED extents: YES (zero-fill, correct) inline_data feature: YES, including:

  • first 60 bytes from i_block[]
  • xattr 'system.data' overflow (60..~4KB) HTree directory indexes: walked as plain dirs (correct, slower) Encrypted dirs (fscrypt): SKIPPED (requires keys) Inline xattrs: in-inode region parsed for system.data; external xattr block not exposed

Btrfs Live files: FULL Deleted files: NO (Btrfs is copy-on-write; live tree only) Compressed extents: YES, all three: zlib, LZO, zstd (LZO and zstd use Btrfs's chunked framing) RAID 5/6 reconstruction: YES (notable feature; uncommon in recovery tools) Multi-device pools: Single-device only Snapshots: Default subvolume only (no enumeration) Encryption: n/a (Btrfs has no native encryption)

XFS V4 / V5 Live files: FULL Deleted files: V5 only, via FINOBT (Free Inode B+tree). V4 has no FINOBT, so no deleted recovery on V4. Inode formats: extent, btree, local (dirs + symlinks) BMBT extent decoding: 9 + 43 byte formats Sparse inodes: YES CRC32C checksums: Validated where present Reflink, rmapbt, project quotas: NOT supported (rare)

HFS+ / HFSX Live files: FULL Deleted files: NO (catalog B-tree records reused immediately on delete) Extents Overflow file: YES (files with > 8 extents) Hardlinks: YES (resolved via HFS+ Private Data

  • iNode<N> lookup) Symlinks: YES (S_IFLNK + Finder magic) decmpfs compression: YES, types 3 and 4:
  • type 3: zlib in xattr
  • type 4: zlib in resource fork decmpfs LZVN/LZFSE (types 7, 8, 11, 12): NOT supported (saved as .compressed.rsrc placeholders for forensic analysis) NFD->NFC name normalization: YES (Italian, French, Spanish, German, Polish, Czech, Nordic) FileVault encrypted volumes: SKIPPED

FILE CARVING

A filesystem-agnostic byte-pattern scanner that recovers files WITHOUT relying on filesystem metadata. Useful when MFT/inode table/catalog is destroyed.

Opt-in via environment variable:

BASTIONGUARD_CARVING=1 ./bastionguard-recovery-data ...

Recovers 19 file format families:

Images: JPEG, PNG, GIF87a, GIF89a, BMP, TIFF (LE+BE) Documents: PDF, OLE Compound File (DOC/XLS/PPT old) Archives: ZIP (covers DOCX/XLSX/PPTX/ODT/JAR) Audio: WAV, MP3 (ID3v2 + MPEG-1/2 Layer III sync), OGG Video: MP4, MOV, AVI (via RIFF), MKV, WebM Database: SQLite

Honest limits:

  • No file names recovered (output is offset-based: <hex_off>_<n>.<ext>)
  • No directory structure (flat output)
  • Fragmented files: only first contiguous run
  • File types not in the list above: 0% (PSD, EPS, RAW camera formats, ELF/PE binaries, etc.) – adding more is straightforward if you need specific formats

REQUIREMENTS

  • Linux (any modern distribution)
  • C++20 compiler (g++ 11+ or clang 14+)
  • CMake 3.16+
  • zlib (REQUIRED): used for ext4 journal, NTFS LZNT1 fallback, Btrfs zlib extents, HFS+ decmpfs zlib
  • liblzo2 (OPTIONAL): used for Btrfs LZO compressed extents
  • libzstd (OPTIONAL): used for Btrfs zstd compressed extents

On Debian/Ubuntu install:

sudo apt-get install build-essential cmake zlib1g-dev \
                     liblzo2-dev libzstd-dev

BUILDING

This package is part of the BastionGuard suite. Standalone build:

mkdir build && cd build
cmake ..
make -j$(nproc)

USAGE

The recovery binary takes a target device or image and an output directory:

sudo bastionguard-recovery-data /dev/sdb1 /tmp/recovered/

Or with a disk image:

bastionguard-recovery-data /path/to/image.dd /tmp/recovered/

For full pipeline (FS recovery + carving):

BASTIONGUARD_CARVING=1 bastionguard-recovery-data /dev/sdb1 /tmp/recovered/

OUTPUT LAYOUT

Recovered files are organized under the output directory:

/tmp/recovered/
    filesystem_recovered/
        ntfs/offset_<N>/
            live/<original_path>           <- live MFT files
            deleted/<path>                 <- deleted MFT files
            logfile_recovered/             <- $LogFile redo recoveries
            orphaned-seq-mismatch/         <- seq mismatch records
        ext4/offset_<N>/
            <recovered tree>
        btrfs/offset_<N>/
            <recovered tree>
        xfs/offset_<N>/
            <recovered tree>
            deleted/inode_<N>.bin          <- FINOBT deleted-inode dumps
        hfs/offset_<N>/
            <recovered tree>
        FAT32/offset_<N>/
            <recovered tree>
            deleted/                       <- deleted-recovery
        exFAT/offset_<N>/
            <recovered tree>
            deleted/
    carved/                                 <- only if carving enabled
        jpeg/<offset>_<n>.jpg
        png/<offset>_<n>.png
        ...

Each recovered file is logged with metadata:

  • source: which mechanism recovered it ("filesystem export", "$LogFile-redo", "carved-jpeg", "deleted-contiguous-guess", "decmpfs-zlib-xattr", etc.)
  • integrity: "full" / "partial" / "metadata"

COVERAGE ESTIMATE

Honest per-scenario success rates (% of recoverable files actually recovered, where "recoverable" means "the data still exists on disk in some form"):

Scenario FAT32 exFAT NTFS ext4 Btrfs XFS HFS+
Live volume 98% 98% 98% 97% 95% 96% 95%
Recently deleted 60% 60% 88% 85% 0% 80% 0%
Quick format (with carving) 85% 85% 85% 85% 85% 85% 85%
Corrupt FS metadata 50% 50% 75% 60% 40% 60% 60%

| MBR/GPT destroyed (carving) | | | ~70% (filesystem-agnostic) |

Btrfs and HFS+ have 0% deleted-file recovery because both reuse metadata structures immediately on delete (Btrfs is copy-on-write with no in-place free list; HFS+ catalog records are reused immediately). This is a fundamental property of the filesystem, not a missing feature in this recovery tool.

COMPETITIVE POSITIONING

For comparison with other recovery tools (estimates, your mileage may vary):

Tool Typical NTFS recovery
TestDisk (open source) ~75%
BastionGuard Recovery ~88%
R-Studio (commercial ~$80) ~92%
WinHex / X-Ways (~€1500) ~96%
EnCase (~€3000) ~98%

BastionGuard sits above TestDisk (gold standard open source) due to: $LogFile redo recovery, $I30 directory index walker, $MFTMirr fallback, sequence number tracking, deleted-FAT contiguous-guess, and 19-format file carving. It approaches commercial entry-level tools without their licensing cost.

Notable distinctive features vs other open-source recovery:

  • Btrfs zlib + LZO + zstd compressed extent decompression
  • Btrfs RAID 5/6 reconstruction
  • XFS V5 FINOBT deleted-file recovery
  • HFS+ decmpfs (both type 3 and type 4)
  • Comprehensive UTF-16 + NFC normalization for HFS+ filenames
  • Filesystem-agnostic file carving with 19 format detectors

KNOWN LIMITATIONS / GAPS

By priority of remaining work (none of these are blocking for the current release):

  • APFS support: planned post-release (~5000-line project)
  • ZFS support: out of scope (niche use case)
  • HFS+ LZVN/LZFSE decoders: out of scope (~150 + ~800 lines)
  • NTFS $LogFile additional opcodes (~24 beyond InitFileRecord): marginal value
  • ext4 external xattr block parser: marginal value
  • Btrfs snapshot enumeration: feature for forensics
  • Btrfs deleted via old superblocks: ~30% best case, complex
  • HFS+ catalog scan for deleted records: limited yield
  • Fragmented file reassembly via heuristics (would benefit all FS): significant project for ~+5-10% global gain

TESTS

The codebase ships with 14 unit/integration tests for the incrementally-built filesystems (XFS, HFS+) and key features (decmpfs, carving, ext4 inline data, NTFS $I30 parser). All pass:

test_xfs_finobt_integration ........... PASS
test_hfs_format ....................... PASS (8 sub-tests)
test_hfs_btree_walk ................... PASS
test_hfs_fork_io ...................... PASS (4 sub-tests)
test_hfs_session3_integration ......... PASS
test_hfs_session45_integration ........ PASS
test_hfs_decmpfs_unit ................. PASS (4 sub-tests)
test_decmpfs_xattr_unit ............... PASS (5 sub-tests)
test_hfs_unicode ...................... PASS (10 sub-tests)
test_btrfs_lzo ........................ PASS (3 sub-tests)
test_ext4_inline_data ................. PASS
test_ext4_inline_xattr ............... PASS
test_carving_integration .............. PASS
test_ntfs_i30_parser .................. PASS (4 sub-tests)

FAT32, exFAT, full NTFS, full ext4, full Btrfs do NOT yet have synthetic-FS integration tests in the package – only compile-time warnings are checked (-Wall -Wextra -Wpedantic, zero warnings on all 23 filesystem source files).

The tests are standalone .cpp files in the development workspace; CTest integration in CMakeLists.txt is a planned improvement.

CHANGELOG

For the detailed history of features added by session, see:

CHANGELOG_BUGFIX.txt                       (initial bug fixes)
CHANGELOG_XFS_S1.txt..S5.txt               (XFS support, 5 sessions)
CHANGELOG_HFS_S1.txt..S3.txt + S4_S5.txt   (HFS+ support, 5 sessions)
AUDIT_REPORT.txt                           (codebase audit, gaps)
CHANGELOG_FUNCTIONAL_FIXES.txt             (ext4 inline_data,
                                            Btrfs LZO/zstd chunked,
                                            NTFS EFS reporting)
CHANGELOG_NTFS_LOGFILE_PLUS_DELETED.txt    (NTFS $LogFile redo,
                                            FAT/exFAT deleted)
CHANGELOG_CARVING.txt                      (initial 9-format carving)
CHANGELOG_CARVING_EXT_AND_MFTMIRR.txt      (carving 9->19 formats,
                                            NTFS $MFTMirr fallback)
CHANGELOG_PRIORITY_2_GAPS_CLOSED.txt       (HFS+ Attributes walker
                                            + decmpfs type 3,
                                            ext4 xattr inline overflow)
CHANGELOG_EXT4_SPARSE_NTFS_SEQ_REPARSE.txt (ext4 sparse fix,
                                            NTFS seq tracking,
                                            NTFS reparse->symlink)
CHANGELOG_NTFS_I30_WALKER.txt              (NTFS $I30 directory
                                            index walker)

LICENSE

BastionGuard™ Recovery Data is free and open-source software released under the GNU General Public License, version 3 or (at your option) any later version (GPL-3.0-or-later).

Copyright (C) 2025–2026 Calogero Scarnà. See the LICENSE file for the complete GNU GPLv3 terms. Bundled third-party components retain their respective compatible licenses. The GPL does not grant rights to use the BastionGuard™ name or branding as a trademark.

PROJECT STATUS

Production-ready for the supported filesystems and scenarios listed above. Known gaps are documented honestly. APFS support is the next major investment.

For bug reports, feature requests, or recovery scenarios that underperform: please report with disk image samples (where appropriate) and the relevant log output.

Compile mkdir build && cd build cmake .. -DCMAKE_INSTALL_PREFIX=/usr

Root startup

The installed desktop launcher starts BastionGuard through bastionguard-recovery-data-pkexec, so the application asks for administrator authentication at startup and runs as root. This is required for raw block-device access on many Linux systems. No activation key, machine binding, or license validation is required; scanning and recovery features are available without restrictions.