StfsSharp is a pure-managed, read-only C# library for Xbox 360 STFS packages and GOD/SVOD Games-on-Demand containers. It is an independent MIT implementation of the on-disk structures used by Xbox Live Arcade (XBLA), Xbox Live Indie Games (XBLIG) and Community Games packages, plus the SVOD fragment layout used by Games-on-Demand installs.
It has zero runtime dependencies, is trimmable, AOT-compatible, and targets
net8.0, net9.0 and net10.0.
- Single-file STFS packages — open XBLA/XBLIG/Community Games packages, list the file table, read files, stream file data and extract the whole tree.
- GOD/SVOD containers — open a header file or its
.datadirectory, mapDataNNNNfragments, and read the logical disc image with random access or through a seekableStream. - Title metadata — read the plaintext XContent header fields (title name, title ID, disc number/count and content type) from STFS packages and GOD containers without decoding data sectors.
- Deep validation — verify every logical block against its level-0 SHA-1 hash, walk every file block chain, verify the level-0/1/2 hash tables, the top hash and the header hash.
- Safe extraction — reject, sanitize or skip host-unsafe entry names, with collision disambiguation and optional progress/warning channels.
- No game data required — the test suite and fuzzer build deterministic synthetic containers; optional real-corpus tests run only when enabled.
| Requirement | Value |
|---|---|
| Target frameworks | net8.0, net9.0, net10.0 |
| Runtime | .NET 8, .NET 9 or .NET 10 |
| Platforms | Windows, Linux, macOS |
| Dependencies | none |
dotnet add package StfsSharp
using StfsSharp; using StfsSharp.Models; using StfsPackage package = StfsPackage.Open(@"C:\games\5841083C\000D0000\ABC..."); Console.WriteLine($"{package.Info.TitleName} ({package.Info.TitleIdHex})"); foreach (StfsEntry entry in package.Entries) { Console.WriteLine($"{(entry.IsDirectory ? "dir " : "file")} {entry.Path} {entry.Size}"); } byte[] defaultXex = package.ReadAllBytes(package.Find("default.xex")!); package.ExtractTo(@"C:\games\extracted");
if (StfsHeader.TryReadTitle(packagePath, out StfsTitleInfo? title)) { Console.WriteLine($"{title.TitleName} — {title.TitleIdHex}"); } if (GodHeader.TryReadTitle(godHeaderPath, out GodTitleInfo? god)) { Console.WriteLine($"{god.TitleName} disc {god.DiscNumber}/{god.DiscCount}"); }
using GodVolume volume = GodVolume.Open(@"D:\content\4D5307E6"); Console.WriteLine($"{volume.Length} bytes across {volume.Info.DataFileCount} fragment(s)"); byte[] sector = new byte[2048]; volume.Read(0x10000, sector); using GodVolumeStream stream = volume.OpenStream(); stream.Seek(0x10000, SeekOrigin.Begin);
using StfsPackage package = StfsPackage.Open(packagePath); StfsValidationReport report = package.Validate(); if (!report.IsValid) { foreach (StfsValidationIssue issue in report.Issues) { Console.WriteLine($"{issue.Area}: {issue.Reason}"); } }
if (StfsFile.IsContainer(path)) { if (GodHeader.IsGodContainer(path)) { using GodVolume volume = StfsFile.OpenGodVolume(path); } else { using StfsPackage package = StfsFile.OpenPackage(path); } }
| Area | Types |
|---|---|
| STFS packages | StfsPackage, StfsEntry, StfsPackageInfo, StfsPackageKind, StfsTitleInfo, StfsHeader |
| GOD/SVOD | GodHeader, GodVolume, GodVolumeStream, GodVolumeInfo, GodTitleInfo |
| Detection | StfsFile |
| Validation | StfsValidationReport, StfsValidationIssue |
| Extraction | ExtractNamePolicy, StfsProgress, StfsProgressKind |
See docs/api.md for the full surface.
| Content | Supported |
|---|---|
XBLA packages (0x000D0000) |
✅ read-only |
XBLIG packages (0x00000002) |
✅ read-only |
Community Games (0x02000000) |
✅ read-only, treated as XBLIG |
GOD/SVOD containers (0x7000, NXE 0x4000) |
✅ read-only |
| STFS saves/profiles/DLC | ❌ out of scope |
| STFS writing, rebuild, re-signing | ❌ out of scope |
| Signature verification | ❌ out of scope (Validate is structural/hash-tree only) |
dotnet build StfsSharp.sln -c Release
dotnet test StfsSharp.Tests/StfsSharp.Tests.csproj -c Release
dotnet format whitespace StfsSharp.sln --verify-no-changes --no-restore
dotnet pack StfsSharp/StfsSharp.csproj -c Release -o artifactsOptional real-corpus validation (paths are local and never committed):
$env:STFSSHARP_REAL_CORPUS = '1' dotnet test StfsSharp.Tests/StfsSharp.Tests.csproj -c Release ` --filter "FullyQualifiedName~RealCorpusTests"
The fuzzer runs from a synthetic valid container with no game data:
dotnet run --project StfsSharp.Fuzz -c Release -- --seconds 60
- XISOSharp — Xbox disc-image creation, extraction and conversion. Consumes StfsSharp for GOD/STFS input.
- CCISharp — CCI/CCIM images.
- ZArchiveSharp — ZAR archives.
MIT. See LICENSE and THIRD-PARTY-NOTICES.md.