miigrate is a Linux/Windows tool that rescues Wii U and vWii savedata and Miis from a dying or broken console and packages them for restore onto a different console with SaveMii /ProcessMod — offline, straight from dumps, with no working homebrew needed on the original console.
It reads Wii U savedata (game and system titles) and the Mii databases from a WFS image
or drive (the mlc internal storage or a usb drive), and vWii savedata + Miis from a
SLCCMPT (Wii NAND) dump — including injects (Wii/GameCube games installed as Wii U titles,
whose saves live on the vWii NAND). The result is a SaveMii /ProcessMod-compatible SD backup
you drop onto a card and restore on the new console; a single --type auto
run can do the whole console at once.
# MLC image (needs only --otp)
miigrate --input mlc.img --type mlc \
--otp otp.bin --output ./sd
# USB image (needs --otp and --seeprom)
miigrate --input usb.img --type usb \
--otp otp.bin --seeprom seeprom.bin --output ./sd
# USB or MLC image + a vWii NAND dump — to also back up *inject* savedata
miigrate --input usb.img --type usb \
--otp otp.bin --seeprom seeprom.bin \
--slccmpt slccmpt.bin --output ./sd
# vWii SLCCMPT / Wii NAND dump (needs only --otp)
miigrate --input slccmpt.bin --type vwii \
--otp otp.bin --output ./sd
# auto (whole console): --input is a *folder* of dumps; identify everything and run
# the MLC + vWii passes. Add --usb to also back up a USB image.
miigrate --type auto --input ./dump --output ./sd
miigrate --type auto --input ./dump --usb ./dump/usb.img --output ./sd--output is treated as the SD root — the batch set is written under
wiiu/backups/batch/, ready to drop onto a card.
You can point --output directly at the root of an inserted SD card (for example D: on Windows or /mnt/d on Linux); the backups then land exactly where SaveMii expects them. Nothing is overwritten — if a custom repo already exists, the old one is renamed with a timestamp suffix.
| Option | Meaning |
|---|---|
--input <file> |
WFS image (mlc/usb/plain) or SLCCMPT dump (vwii). With --type auto this is a folder of dumps instead |
--type <usb|mlc|plain|vwii|auto> |
image type (default usb). vwii reads a vWii NAND (SLCCMPT) dump; auto scans a folder (see Auto mode) |
--otp <path> |
OTP dump (required for mlc/usb/vwii; auto-detected in auto) |
--seeprom <path> |
SEEPROM dump (required for usb; not used by vwii; auto-detected in auto) |
--slccmpt <path> |
vWii NAND (SLCCMPT) dump (optional, usb/mlc): back up the savedata of Wii injects installed as Wii U titles. Decrypted with the same --otp. Without it, injects are only reported |
--usb <file> |
auto only: explicit path to a USB WFS image to also back up |
--output <dir> |
SD-root output directory |
--verbose |
print each extracted path |
--dump-usr-dir |
recovery mode: skip the WFS header, read /usr directly (for corrupted images) |
--wide-permissions |
savedata will be restored with permissive 666 permissions, mimicking the old SaveMii restore process. Use this option only if a permissions problem appears when running the game. See the matrix below |
--add-unknown-system-titles |
System titles may need their exact original permissions, so the default process backs up only the ones it recognizes. Use this flag if you need the savedata of a system title the extract process does not know; it will be restored using wide 666 permissions (use this at your own risk!). See the matrix below |
The --dump-usr-dir, --wide-permissions, and --add-unknown-system-titles flags apply to the Wii U (WFS) path only. vwii always writes plain FILES with no permission sidecar, so none of them are relevant.
--type auto turns --input into a folder of dumps and figures out the rest, so a
full console migration is a single command instead of three. It identifies the files by
their characteristics — no fixed names required:
- OTP (1024-byte file) and SEEPROM (512-byte file) by exact size.
- SLCCMPT (vWii NAND) by size (512/528 MiB), confirmed by its
SFFSsuperblock. - MLC image as the WFS image whose header decrypts with the MLC key. (A USB image is
never auto-picked as the MLC — pass it explicitly with
--usb <file>.)
If it finds more than one candidate for any of OTP, SEEPROM, SLCCMPT or the MLC image, it stops and lists them, asking you to keep exactly one and remove the extras.
It then runs the passes in order into a single SD tree:
- USB (only with
--usb <file>) — savedata + injects. - MLC — savedata + injects + Miis, into the same batch/timestamp as the USB pass, so both land in one restorable BackupSet.
- SLCCMPT — the vWii savedata +
RFLMiis, as a separateISFS-XBackupSet.
# folder holds otp.bin, seeprom.bin, mlc.img, slccmpt.bin (+ optional usb image)
miigrate --type auto --input ./dump --output /mnt/sd
miigrate --type auto --input ./dump --usb ./dump/usb.img --output /mnt/sd--verbose, --wide-permissions and --add-unknown-system-titles apply to the Wii U
passes as usual; --otp, --seeprom and --slccmpt are ignored (they come from the folder).
An inject is a Wii or GameCube game repackaged as a Wii U title. It is installed on the Wii U side (in the WFS image), but its savedata lives on the vWii NAND (SLCCMPT), not in the WFS — so it is handled like a Wii U title on restore, while its save has to be read from a NAND dump. miigrate detects injects the same way SaveMii does and treats them as follows:
- GameCube injects — cannot be managed here: GameCube saves are memory-card files handled by Nintendont, not stored on the NAND. miigrate warns and names each one, and never backs it up.
- vWii (Wii) injects — backed up only if you pass
--slccmptwith the console's vWii NAND dump. The save is read from the NAND (under the embedded Wii title's IDs) and written into the Wii U batch under the inject's Wii U IDs, soSaveMiirestores it straight back onto the installed inject. Without--slccmpt, each vWii inject is reported but not backed up.
The run summary lists how many injects were not backed up, split into GameCube (restore from Nintendont) and vWii (needs a --slccmpt dump). Injects that are backed up join the normal Wii U (WFS-X) batch and restore through Wii U Save Management exactly like any other Wii U title.
A Wii U USB drive is WFS-formatted and encrypted per console, so it still needs --otp and
--seeprom. You can point --input straight at the raw device instead of an image file —
miigrate opens it the same way as wfs-tools' wfs-extract:
# Windows — run from an *Administrator* shell.
# Find the drive number first: Get-WmiObject Win32_DiskDrive
miigrate --input \\.\PhysicalDrive3 --type usb --otp otp.bin --seeprom seeprom.bin --output D:\# Linux — run with sudo for raw-device access (find the device with `lsblk`).
sudo miigrate --input /dev/sdb --type usb --otp otp.bin --seeprom seeprom.bin --output /mnt/sdThe upstream wfs-tools can also dump the drive to an
image (wfs-extract) or mount it read-only as a browsable filesystem (wfs-fuse, Linux/macOS)
— e.g. sudo wfs-fuse /dev/sdb /mnt --otp otp.bin --seeprom seeprom.bin. See its
README for full usage and how to locate the device.
Just copy the contents of the <output> directory to the root of the SD card you use to boot into Aroma, and then launch SaveMii /ProcessMod in the new console.
Take a look at this step-by-step tutorial for a detailed walkthrough.
The on-disk layout, the SaveMii permission sidecar, and the permission matrix are documented in tech_details.md.
Requires:
- GCC 14+ / LLVM 18+.
- CMake 3.21+
- Ninja.
- Visual Studio 2022, version 17.9+.
git clone --recurse-submodules git@github.com:w3irDv/miigrate.git
cd miigrate
export CC=gcc-14 CXX=g++-14
cmake --preset default
cmake --build --preset releaseBinary: build/default/miigrate/Release/miigrate.
The default binary links Boost/Crypto++ statically but still needs the system
glibc/libstdc++, so it is not portable to older Linux distributions. For a binary that runs on any x86-64 Linux regardless of distro, build fully static:
cmake --preset static
cmake --build --preset static-releaseBinary: build/static/miigrate/Release/miigrate.
On Windows, use the windows-static preset instead:
cmake --preset windows-static
cmake --build --preset windows-static-releaseBinary: build\windows-static\miigrate\Release\miigrate.exe.
Unit tests (pure format/permission helpers):
cmake --preset default -DSAVEMII_BUILD_TESTS=ON
cmake --build --preset release
ctest -C Release --test-dir build/defaultwfslib— WFS library (w3irDv/wfslib,quota-size-accessors, forked from wfslib).isfslib— ISFS library (w3irDv/isfslib).vcpkg— dependency manager (microsoft/vcpkg).
- Thanks to koolkdev for wfs-tools and wfslib, and to everyone who contributed to reverse-engineering the WFS filesystem.
- Thanks to parannoyed and hakito for Wii NAND Extractor.
- Devs and REs in the Wii U scene!!
- Vibe-coded on top of wfs-extract and SaveMii /ProcessMod.
