Skip to main content

Wiithon

A Python library for reading, patching and rebuilding Nintendo Wii disc images.

PyPI Python License

Installation

pip install wiithon

Requires Python 3.11 or later. Type annotations are shipped (PEP 561).

Quick start

Read a disc image:

from wiithon import WiiIsoReader

with WiiIsoReader("game.iso") as reader:
    print(reader.disc_header.game_title)

    partition = reader.open_partition(reader.get_data_partition())
    for path in partition.list_files():
        print(path)

    data = partition.read_file("opening.bnr")

Patch it and write a new image:

from wiithon import WiiIsoPatcher

with WiiIsoPatcher("game.iso") as patcher:
    patcher.modify_banner_title("My Hack")
    patcher.replace_file("StageData/Foo.arc", new_bytes)
    patcher.add_file("custom/data.bin", b"...")
    patcher.build("patched.iso")

Edit a file inside an archive, without unpacking anything by hand:

from wiithon import WiiIsoPatcher, BCSV

with WiiIsoPatcher("game.iso") as patcher:
    path = "StageData/CannonFleetGalaxy/CannonFleetGalaxyScenario.arc/scenariodata.bcsv"
    with patcher.edit_as(path, BCSV, str_fmt="shift_jis") as bcsv:
        for entry in bcsv.entries:
            entry["LuigiModeTimer"] = 0

    patcher.build("patched.iso")

Patch the executable:

from wiithon import WiiIsoPatcher, DOL

def patch(dol: DOL) -> None:
    dol.write_at(0x80123456, b"\x60\x00\x00\x00")        # nop
    print(dol.read_until_null_at(0x805A1234).decode("shift_jis"))

with WiiIsoPatcher("game.iso") as patcher:
    patcher.patch_dol(patch)
    patcher.build("patched.iso")

What it does

Discs parses the disc header, partition table and File System Table. Partition data is decrypted on the fly, so reading one file does not mean decrypting the whole partition. Rebuilding handles re-encryption, the full H0–H3 Merkle tree and TMD fakesigning, so the result boots in Dolphin.

Building master a new image by copying an existing one, or from an extracted sys/ + files/ directory tree. The PartitionSource interface lets you plug in your own.

File formats DOL, BCSV, RARC, U8, Yaz0, LZ77, BNR with IMET titles. Compressed archives are resolved transparently: a path may cross into an archive, and into a Yaz0 layer wrapping it.

DOL patching read and write at virtual addresses, add text or data sections, find code caves, locate and patch the arenaLo setter, inject code above the arena. A PowerPC instruction encoder is included.

Command line

wiithon iso info game.iso
wiithon iso list game.iso
wiithon iso extract game.iso ./out
wiithon iso cat game.iso opening.bnr

wiithon rarc info archive.arc
wiithon rarc extract archive.arc ./out

wiithon dol caves main.dol

Errors

Anything raised because of malformed data derives from WiithonError:

from wiithon import WiiIsoReader, InvalidDiscError, FstFileNotFoundError

try:
    with WiiIsoReader("maybe.iso") as reader:
        ...
except InvalidDiscError:
    print("not a Wii disc image")

The "not found" variants also inherit from the matching builtin, so except FileNotFoundError keeps working. Invalid arguments still raise the usual ValueError and TypeError.

Documentation

License

MIT see LICENSE.md.

AI Disclosure

Some people can be concerned about AI in project. So for transparency, this section will explain when and what is AI-generated. Everything is reread by me.

  • English is not my mother tongue, i used AI for documentation. I'm writing a first documentation in english/french locally and i'm using AI to translate it and fix my spell mistakes. I'm doing also that for long docstring (because it's written in the API documentation) ;
  • I used generative AI for some mock helper function in unit tests, because it's faster and i tested the mocking stuff by hand before adding them. It's the only code generated by an AI. Everything else that i wrote is not generated by AI ;
  • I used AI personally when i struggle to understand some documentation when 3 websites says 3 differents things for one format (like rarc files, omg).

It's impossible to know if some people used AI in their pull request. I'm not banning AI in pull request but for the base code, i'm suggering to not use it. I put a lot of time to understand everything and i probably forgot some stuff about the beginning but i love so much understanding such things. If you think it's to much AI, it's completely up to you and i understand your position, really !

Metadata

Release files for wiithon 0.1.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for wiithon 0.1.4
File Size Uploaded Provenance Actions
wiithon-0.1.4.tar.gz 2.5 MB With provenance Details for wiithon-0.1.4.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for wiithon 0.1.4
File Interpreter ABI Platform Actions
wiithon-0.1.4-py3-none-any.whl Python 3 none any Details for wiithon-0.1.4-py3-none-any.whl

Total release size: 2.5 MB

Release files / wiithon-0.1.4.tar.gz

Download URL wiithon-0.1.4.tar.gz
Size 2.5 MB
Tags Source
SHA-256 checksum
How to use checksums
39966ac81277be18fa3b009bfef602de58f87b5e62fc45c79a851ca8e262aa39
BLAKE2b-256 checksum
How to use checksums
902e8b0184cf0f1c6dc9efadf9184bf1973aee4fe57b586b613dd4f2c2192f4e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 8, 2026.

Transparency log

Release files / wiithon-0.1.4-py3-none-any.whl

Download URL wiithon-0.1.4-py3-none-any.whl
Size 78.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d82b3deaf4fc9fe09b12ff3b9f0182492ddc49c8c5632595c0194c6dc2550536
BLAKE2b-256 checksum
How to use checksums
cfe3d2380dc6a8137f43bbdcdf6b8058abf7832d02cf682a8684cbde119ae975
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 8, 2026.

Transparency log

Security for wiithon 0.1.4

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for wiithon-0.1.4.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 8, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page