mirror of
https://gitea.tendokyu.moe/beerpsi/fsdecrypt.git
synced 2026-09-22 22:17:55 +03:00
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
3.4 KiB
3.4 KiB
fsdecrypt
Decryptor and extractor for SEGA arcade filesystem containers (fscrypt format).
Handles AES-128-CBC encrypted container images used on SEGA Nu/ALLS arcade hardware, automatically parsing the embedded BootID header to identify the game and container type, then decrypting and extracting the contents.
Features
- Decrypts OS, APP, and OPTION (DLC) containers
- Extracts NTFS-based containers (OS/APP) including internal VHD images
- Extracts ExFAT-based containers (OPTION/DLC packs)
- Preserves file timestamps during extraction
- Built-in key database for 70+ game titles
- Supports external key files for unlisted games
- Progress bars with transfer speed and ETA
Installation
Requires Rust 1.56+ (edition 2021).
cargo build --release
The binary will be at target/release/fsdecrypt (or fsdecrypt.exe on Windows).
Usage
fsdecrypt [OPTIONS] <FILES>...
Arguments
<FILES>...- One or more encrypted container files (.app,.opt, etc.)
Options
--no-extract- Decrypt the container to a raw image file without extracting its contents-h, --help- Print help-V, --version- Print version
Examples
# Decrypt and extract an APP container
fsdecrypt SDXX_1.00.00_20240101120000_0.app
# Decrypt and extract an OPTION container
fsdecrypt SDXX_A001_20240101120000_0.opt
# Process multiple containers at once
fsdecrypt game_v1.app game_v2.app extras.opt
# Decrypt only, skip extraction
fsdecrypt --no-extract SDXX_1.00.00_20240101120000_0.app
Output
By default, the tool extracts container contents directly:
| Type | Extracted contents |
|---|---|
| OS | internal_{seq}.vhd |
| APP | internal_{seq}.vhd |
| OPTION | Directory with all DLC files |
With --no-extract, a raw decrypted image is written instead:
| Type | Output filename |
|---|---|
| OS | {os_id}_{version}_{timestamp}_{seq}.ntfs |
| APP | {game_id}_{version}_{timestamp}_{seq}.ntfs |
| OPTION | {game_id}_{option}_{timestamp}_{seq}.exfat |
External Key Files
For games not in the built-in database, place a key file named {GAME_ID}.bin in the working directory:
- 16 bytes: AES-128 key only (IV will be derived automatically)
- 32 bytes: AES-128 key (first 16 bytes) + IV (last 16 bytes)
How It Works
- The first 128 bytes of the container are decrypted using a hardcoded master key to obtain the BootID header
- The BootID contains metadata: game ID, container type, block layout, and an IV mode flag
- The game-specific AES-128 key is looked up from the built-in database (or read from an external
.binfile) - If no IV is hardcoded or the container uses a custom IV, the IV is derived by trial-decrypting the first data page against the expected filesystem header (NTFS or ExFAT magic bytes)
- Each 4096-byte page is decrypted independently using AES-128-CBC, with a per-page IV computed by XORing the file IV with the page's file offset
- The decrypted stream is parsed as NTFS or ExFAT depending on container type, and contents are extracted
Container Types
| Type | ID | Filesystem | Description |
|---|---|---|---|
| OS | 0x00 |
NTFS | Operating system image |
| APP | 0x01 |
NTFS | Game application and assets |
| OPTION | 0x02 |
ExFAT | Downloadable content / option packs |
License
BSD Zero Clause License (0BSD)