Files
beerpsi_fsdecrypt/README.md
T
JujuforceandClaude Opus 4.8 a73f71e3de test: add e2e fixture decryption test
Decrypts real .app/.opt containers dropped into a git-ignored fixtures/ dir
(copied to a temp dir first so extraction never touches the fixtures), asserting
each produces a non-empty extraction. No-op when fixtures/ is empty, so the suite
stays green without the proprietary sample data.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 12:28:00 +02:00

87 lines
2.6 KiB
Markdown

# fsdecrypt
Decryptor and extractor for SEGA arcade filesystem containers (fscrypt format). Works on Windows and Linux, no admin privileges required.
## Installation
Requires [Rust](https://www.rust-lang.org/tools/install).
```bash
cargo build --release
```
The binary will be at `target/release/fsdecrypt` (or `fsdecrypt.exe` on Windows).
## Usage
```bash
fsdecrypt <FILES>...
```
### Examples
```bash
# 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:
```bash
fsdecrypt ABCD_1.01.00_20240215143000_1_1.00.00.app
```
You can also pass both explicitly:
```bash
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/`).
## 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.
```bash
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`](https://hub.docker.com/r/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](LICENSE) (0BSD)