No description
  • Erlang 97.9%
  • Rust 2%
Find a file
2026-07-06 21:34:59 +00:00
assets feat: add Windows right-click "Unpack with fsdecrypt" context menu 2026-06-28 14:56:45 +02:00
fixtures fix: extract exFAT OPTION containers that contain empty files 2026-07-06 22:06:38 +02:00
scripts test: add unit tests and a local Docker test runner 2026-06-28 11:44:35 +02:00
src fix: skip NTFS DOS (8.3) short-name entries when extracting 2026-06-28 14:03:30 +02:00
tests test: add synthetic, committable e2e fixtures (base/delta app + opt) 2026-06-28 13:37:37 +02:00
.gitattributes test: add unit tests and a local Docker test runner 2026-06-28 11:44:35 +02:00
.gitignore chore: gitignore AGENTS.md 2026-06-28 15:06:31 +02:00
Cargo.lock chore: release version 0.1.9 2026-07-06 23:34:43 +02:00
Cargo.toml chore: release version 0.1.9 2026-07-06 23:34:43 +02:00
install-context-menu.bat feat: add Windows right-click "Unpack with fsdecrypt" context menu 2026-06-28 14:56:45 +02:00
LICENSE initial commit 2024-07-21 23:59:02 +07:00
README.md feat: add Windows right-click "Unpack with fsdecrypt" context menu 2026-06-28 14:56:45 +02:00
uninstall-context-menu.bat feat: add Windows right-click "Unpack with fsdecrypt" context menu 2026-06-28 14:56:45 +02:00

fsdecrypt

Decryptor and extractor for SEGA arcade filesystem containers (fscrypt format). Works on Windows and Linux, no admin privileges required.

Installation

Requires Rust.

cargo build --release

The binary will be at target/release/fsdecrypt (or fsdecrypt.exe on Windows).

Usage

fsdecrypt <FILES>...

Examples

# Extract a game APP container
fsdecrypt ABCD_1.00.00_20240101120000_0.app

# Extract an OPTION/DLC container
fsdecrypt ABCD_A001_20240101120000_0.opt

# Extract multiple files at once
fsdecrypt game_v1.app game_v2.app extras.opt

# Decrypt only (outputs raw .ntfs/.exfat image, no extraction)
fsdecrypt --no-extract ABCD_1.00.00_20240101120000_0.app

Delta Updates

Games often ship incremental updates as a separate .app file. Just pass the update file — fsdecrypt will automatically find the base in the same folder and merge them:

fsdecrypt ABCD_1.01.00_20240215143000_1_1.00.00.app

You can also pass both explicitly:

fsdecrypt ABCD_1.00.00_20240101120000_0.app ABCD_1.01.00_20240215143000_1_1.00.00.app

The output folder is named after the input file (e.g. ABCD_1.01.00_20240215143000_1_1.00.00/).

Windows Right-Click Menu

Two batch files add an "Unpack with fsdecrypt" entry (with an unpack icon) to the right-click menu of .app and .opt files:

  • install-context-menu.bat — install the menu entry
  • uninstall-context-menu.bat — remove it

Just double-click install-context-menu.bat. No administrator rights are needed — it installs under the current user only (HKCU) and leaves the normal double-click association untouched. Right-clicking a file then runs the full extraction and keeps the console window open until you press a key.

install-context-menu.bat finds fsdecrypt.exe automatically when run from the repo root (it looks in target\release then target\debug) or when placed next to the binary. The icon is taken from assets\fsdecrypt.ico (or fsdecrypt.ico beside the script). The menu stores the absolute path it found, so re-run it if you move the exe.

On Windows 11 the entry appears under Show more options (the classic menu).

External Key Files

For games not in the built-in key database, place a file named {GAME_ID}.bin in the working directory:

  • 16 bytes for key only (IV derived automatically)
  • 32 bytes for key + IV

Testing

Tests run locally (there is no hosted CI). The unit tests are plain cargo test; the Linux x86_64-musl release target is exercised via Docker when you need it.

cargo test            # unit tests (IV derivation, timestamp decoding, key lookup)
scripts/test.sh       # native tests + smoke test, then the same in a musl container
scripts/test.sh --no-docker   # skip the Docker/Linux step

scripts/test.sh uses the clux/muslrust image to build and test the static Linux binary — the same way release artifacts are produced — so both targets can be validated from any host.

End-to-end fixtures

The tests/e2e.rs test decrypts real containers placed in a fixtures/ directory at the repo root and checks that each extracts successfully. That folder is git-ignored — the proprietary sample containers are never committed — and the test is a no-op when it is empty, so just drop a few .app/.opt files in fixtures/ and run cargo test (or scripts/test.sh) to exercise the full decrypt-and-extract path.

License

BSD Zero Clause License (0BSD)