WiiUSharp.Nus 0.7.0

dotnet add package WiiUSharp.Nus --version 0.7.0
                    
NuGet\Install-Package WiiUSharp.Nus -Version 0.7.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="WiiUSharp.Nus" Version="0.7.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="WiiUSharp.Nus" Version="0.7.0" />
                    
Directory.Packages.props
<PackageReference Include="WiiUSharp.Nus" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add WiiUSharp.Nus --version 0.7.0
                    
#r "nuget: WiiUSharp.Nus, 0.7.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package WiiUSharp.Nus@0.7.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=WiiUSharp.Nus&version=0.7.0
                    
Install as a Cake Addin
#tool nuget:?package=WiiUSharp.Nus&version=0.7.0
                    
Install as a Cake Tool

WiiUSharp

.NET libraries for Wii U file formats and title concepts.

Not affiliated with or endorsed by Nintendo. Wii U is a trademark of Nintendo.

The NFS container format was worked out from nfs2iso2nfs by sabykos, piratesephiroth and FIX94, the NUS package layout from NUSPacker by Maschell (timogus) and CDecrypt by crediar, and RPX compression from wiiurpxtool by CBH. WiiUSharp.Nfs, WiiUSharp.Nus and WiiUSharp.Rpx are new implementations of those formats, not ports of their code.

No keys ship with these packages. The common key, title keys and htk.bin are yours to supply.

Packages

Package Targets Purpose
WiiUSharp net48, net6.0, net8.0, net10.0 Title identity and presentation: TitleId, GroupId, ProductCode, Region, Language, per-language names, and the ImageSlot / BootSound formats a title ships with.
WiiUSharp.Nfs net48, net6.0, net8.0, net10.0 The vWii disc container (content/hif_*.nfs): header, sparse part table, per-sector AES, 250 MB split.
WiiUSharp.Imaging net48, net6.0, net8.0, net10.0 Turns PNG, JPEG, BMP, WebP or TGA into the exact TGA an ImageSlot needs. SkiaSharp + TargaSharp; no System.Drawing.
WiiUSharp.Audio net48, net6.0, net8.0, net10.0 Turns WAV, MP3 or AIFF into bootSound.btsnd: 48 kHz stereo 16-bit, six seconds. NAudio.Core + NLayer; no Windows codecs.
WiiUSharp.Nus net48, net6.0, net8.0, net10.0 Packs a code/content/meta folder into an installable title: FST, hashed and plain contents, fake-signed TMD and ticket. Downloads a title's package from the update server and unpacks it back into those folders.
WiiUSharp.Rpx net48, net6.0, net8.0, net10.0 RPX/RPL executables: load with every section plain, replace section bytes, save compressed or not with the CRC table rebuilt.
dotnet add package WiiUSharp
dotnet add package WiiUSharp.Nfs
dotnet add package WiiUSharp.Imaging
dotnet add package WiiUSharp.Audio
dotnet add package WiiUSharp.Nus
dotnet add package WiiUSharp.Rpx

Usage

Title metadata

using WiiUSharp;

var game = new Game(
    new TitleId(TitleType.Demo, 0x12345678),
    new GroupId(0x5678),
    new ProductCode(ProductCode.EShop, "FAAE"))
{
    Region = Region.All,
    Names = LocalizedName.ForAllLanguages(new LocalizedName("Super Metroid")),
};

string id = game.TitleId.ToString();            // "0005000212345678"
ImageSlot icon = ImageSlot.Icon;                // iconTex.tga, 128x128, 32 bpp

Title images

using WiiUSharp.Imaging;

TitleImage.Convert("icon.png", ImageSlot.Icon, @"title\meta\iconTex.tga");   // resized to 128x128, 32 bpp, uncompressed, no footer

var problems = TitleImage.Problems(new TgaFile("bootTvTex.tga"), ImageSlot.BootTv);   // empty when it fits

Boot sound

using WiiUSharp.Audio;

BootSoundConverter.Convert("boot.mp3", @"title\meta\bootSound.btsnd");   // resampled, stereo, first six seconds

BootSound sound = BootSound.Load(@"title\meta\bootSound.btsnd");          // header + samples of an existing one

NFS container

using WiiUSharp.Nfs;

var key = NfsKey.FromFile(@"title\code\htk.bin");

// read: a seekable stream of the decrypted payload, no temp file
using Stream payload = NfsReader.Open(@"title\content", key).OpenPayload();

// write: pack, encrypt and split in one pass
new NfsWriter(key).Write(payload, new DiscDataSpan(0xF800000, gameLength), @"out\content");

The payload is a Wii disc image with its game partitions decrypted. Converting to or from a normal ISO needs Wii partition crypto, which WiiUSharp.Nfs does not implement — supply an IPartitionCipher and use NfsConverter. See .docs/WiiUSharp.Nfs.md.

Packing a title

using WiiUSharp.Nus;

var packer = new NusPacker(CommonKey.Parse("<wii u common key>"));
NusPackage package = packer.Pack(@"title", @"out", TitleKey.Parse("13371337133713371337133713371337"));
// out\title.tmd, title.tik, title.cert, 00000000.app (FST), 00000001.app ... and a .h3 per hashed content

Title values come from code/app.xml; pass a TitleInfo to override them, your own ContentRule list to change which files share a content, or a real title.cert to replace the generated stub. Output is fake-signed and installs with the usual signature patches. See .docs/WiiUSharp.Nus.md.

Downloading and unpacking a title

using WiiUSharp.Nus;

var commonKey = CommonKey.Parse("<wii u common key>");
var titleKey = EncryptedTitleKey.Parse("<title key as the ticket stores it>");   // what title key lists carry

var downloader = new NusDownloader(new HttpClient());
await downloader.DownloadAsync(TitleId.Parse("00050000101BAF00"), @"package", titleKey, commonKey);
// package\title.tmd, title.tik (built from the key; retail games have none on the server), 00000000.app ... and .h3 files
// With the common key given, content 0 must decrypt to an FST before anything large is fetched.

new NusUnpacker(commonKey).Unpack(@"package", @"title");   // title\code, content, meta — every hash verified

Nothing is needed to download but the title ID; the keys only decrypt. See .docs/WiiUSharp.Nus.md.

Executables

using WiiUSharp.Rpx;

RpxFile rpx = RpxFile.Load(@"title\code\WUP-JAAE.rpx");   // compressed sections are inflated on load
Section rodata = rpx.FindSection(".rodata")!;
rodata.Data = Patched(rodata.Data);                        // any byte change, any length
rpx.Save(@"title\code\WUP-JAAE.rpx", compress: true);     // CRC table rebuilt, layout as wiiurpxtool writes it

See .docs/WiiUSharp.Rpx.md.

Building

dotnet build WiiUSharp.sln
dotnet test WiiUSharp.sln

Requires the .NET 10 SDK (global.json). dotnet pack -c Release produces the NuGet packages.

License

MIT — see LICENSE.

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Framework net48 is compatible.  net481 was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.7.0 0 9/15/2026
0.6.0 29 9/14/2026
0.5.0 32 9/14/2026

0.7.0: NusDownloader and NusUnpacker; TMD, ticket and FST parsing.