HaroohieClub.Wiinject 3.0.0

dotnet add package HaroohieClub.Wiinject --version 3.0.0
                    
NuGet\Install-Package HaroohieClub.Wiinject -Version 3.0.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="HaroohieClub.Wiinject" Version="3.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="HaroohieClub.Wiinject" Version="3.0.0" />
                    
Directory.Packages.props
<PackageReference Include="HaroohieClub.Wiinject" />
                    
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 HaroohieClub.Wiinject --version 3.0.0
                    
#r "nuget: HaroohieClub.Wiinject, 3.0.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 HaroohieClub.Wiinject@3.0.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=HaroohieClub.Wiinject&version=3.0.0
                    
Install as a Cake Addin
#tool nuget:?package=HaroohieClub.Wiinject&version=3.0.0
                    
Install as a Cake Tool

<h1 align="center"> <img src=".branding/logo/png/wiinject_blue.png" alt="The Wiinject logo, a red Wii with PowerPC assembly written on the side" style="width: 300px"/> <br/> Wiinject <br/> </h1>

Wiinject is a cross-platform tool for injecting ASM hacks into Wii games using Riivolution memory patches. Pass it a folder containing .s PowerPC assembly files and/or .c C files and a series of injection sites and it will assemble the files and give you a memory file and a series of Riivolution XML memory patches.

Usage

Prerequisites

Wiinject requires the following to run:

CLI Options

  • -f|--folder – The folder where your source files live.
  • -m|--dolphin-map|--map|--symbols – A Dolphin symbols map for any built-in functions you want to reference by name; if you're using Ghidra, this can be exported directly from there.
  • -a|--arena-lo – The arena-lo value, specific to each game. See below for how to determine this.
  • -o|--output-folder – The folder to output the Riivolution patch.xml & assembled ASM bin file to.
  • -n|--patch-name – The name of the patch to output. The patch will be output to {output_folder}/Riivolution/{patch_name}.xml and the ASM bin will be output to {output_folder}/{patch_name}/{hack_name}.bin.
  • -p|--input-patch – The base Riivolution patch that will be modified by Wiinject to contain the memory patches. A blank base template will be created if this is not provided.
  • -j|--ninja-path – The path to the Ninja build executable (e.g. /usr/bin/ninja)
  • d|devkitppc-path= ‐ The path to a devkitPPC installation (e.g. C:\devkitPro\devkitPPC or /opt/devkitpro/devkitPPC)

Determining the Arena-Lo Value

The arena-lo value is the lower bound for heap allocation -- i.e., the end of the executable code section for the ROM. By patching this value teo be higher, we can add extra space for inserting extra code.

To determine this value, run the game in Dolphin with the log viewer present and OSREPORT_HLE logs enabled. Shortly after the game starts up, you should see a line that looks something like:

Core/HLE/HLE_OS.cpp:95 N[OSREPORT_HLE]: 800c6afc->800c6ae8| MEM1 Arena : 0x802c83c0 - 0x817789c0

The first value after MEM1 Arena (in this case, 0x802c83c0) is your arena-lo that you'll need to provide to Wiinject.

Structuring Your Source Code and Preparing Your Initial Patch

Wiinject expects the folder where your source lives to have one subdirectory for each patch element you wish to generate. For example, if you'd like your final Riivolution patch to contain one optional patch for translating the game and another for reducing monster spawns, name one subdirectory something like Translation and the other ReduceMonsterSpawns. Then, place your source files relevant to those patches in those directories.

When preparing your input patch, make sure you set up the options yourself and ensure that the patch names in the options match the names of the subdirectories in your source folder. Finally, add any patch elements that have non-memory patches. Wiinject will automatically create patch elements that don't exist and append to ones that do.

If you've followed along, your input patch should look something like this:

<wiidisc version="1">
  <id game="R42069" />
  <options>
    <section name="Translation">
      <option name="Translation">
        <choice name="Enabled">
          <patch id="Translation" />
        </choice>
      </option>
    </section>
    <section name="Quality of Life">
      <option name="Reduce Monster Spawns">
        <choice name="Enabled">
          <patch id="ReduceMonsterSpawns" />
        </choice>
      </option>
    </section>
  </options>
  <patch id="Translation">
    <folder external="/Game/files" recursive="true" disc="/" />
    <folder external="/Game/files" />
  </patch>
</wiidisc>

Writing ASM

To write an assembly file that Wiinject can parse, however, you need to use special function names.

Here is a sample Wiinject-compatible assembly file:

hook_80017250:
    start:
        add 5,5,0
        mr 26,3
        cmpwi 5,3
        beq end
        li 5,2
    end:
        blr

hook_80017254:
    mr 3,26
    blr

repl_80017260:
    mr 5,25
    li 6,7

ref_801BBB38:
    li 6,7
    blr

The hooks indicate which instructions to replace with a branch instruction to the function provided. The repl indicates a location to start overwriting instructions directly with the instructions provided. The ref indicates a location to write a reference to the function provided (useful for hooking into functions that use bctrl, etc.).

Source & Building

Wiinject.sln can be opened in Rider or Visual Studio and built from there. You can also build Wiinject.sln from the command line on any platform that supports .NET 10.0 with dotnet build in the root directory. If you're struggling to get Wiinject to run properly after compilation, try explicitly running with the RID of the platform you're building for (e.g. dotnet build -r osx-arm64 HaroohieClub.Wiinject.Cli/HaroohieClub.Wiinject.Cli.csproj).

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  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 was computed.  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 Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.1

    • No dependencies.
  • net10.0

    • No dependencies.

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
3.0.0 118 9/8/2026