Code Injection set up
Author(s): Dararo
This guide will take you thought the steps to get a working Code Injection environment to make your own patches and/or compile patches from other people in Gen V games (White 2 recommended).
This is a practical guide so it doesn't stop to explain the reason behind the steps, it is NOT a replacement for the Code Injection guide, but it should help getting started in a practical way. It should also do the trick if you only want to compile a patch, even if you can't code yourself.
Disclaimers:
- The guide uses Windows 10 and Visual Studio, you can use other operating systems and IDEs as long as the tools are compatible, but most steps in this guide will not be valid for you and you will have to find out how to do them in your set up
- The guide assumes a general knowledge of C/C++ and basic UI navigation capabilities
- This is one way to set up your environment, there are diferent ways to do this
Before starting I recomend creating a CodeInjection folder to store all code injection related files and applications.
Table of Contents
Environment set up
File structure
- Create an Empty C++ Project inside of the
CodeInjectionfolder, for this guide it will be called PW2Code - Create a folder named "ExternalDependencies" at
CodeInjection/PW2Code - Clone the SWAN repositiory in the
CodeInjection/PW2Code/ExternalDependenciesfolder - Clone the NitroKernel repositiory in the
CodeInjection/PW2Code/ExternalDependenciesfolder - Clone the ExtLib repositiory in the
CodeInjection/PW2Code/ExternalDependenciesfolder - Clone the libRPM repositiory in the
CodeInjection/PW2Code/ExternalDependenciesfolder - Create
CodeInjection/PW2Code/Patches(here will go all your code)
File structure should look like this:
- CodeInjection
- PW2Code
- ExternalDependencies
- ExtLib
- libRPM
- NitroKernel
- swan
- Patches
- PW2Code.sln
- PW2Code.vcxproj
- PW2Code.vcxproj.filters
- PW2Code.vcxproj.user
- ExternalDependencies
- PW2Code
VS Project set up
- Open the project with Visual Studio
- In the "Solution Explorer" view, click the
Show All Filesbutton (shows all the files in the project folder)
- In the "Solution Explorer" view, select all the folders, "Right-Click" it and select the
Include In Projectoption
- In the "Solution Explorer" view, "Right-Click" the project and select
Properties - Go to
Configuration Properties -> VC++ Directories -> Include Directoriesand select<Edit...>
- In the "Include Directories" window, paste
$(ProjectDir)ExternalDependencies/swan,$(ProjectDir)ExternalDependencies/NitroKernel/include,$(ProjectDir)ExternalDependencies/ExtLiband$(ProjectDir)ExternalDependencies/libRPM/includeor use the...button to look them up
- Click
Okand remember to clickAcceptin thePropertieswindow to save the changes
Now whenever you create a CPP file in the Patches folder you will be able to include any SWAN header and use its definitions.
CTRMap set up
For more in-depth CTRMap installation instructions check this guide.
- Download CTRMap-Community Edition
- Download the CTRMapV plug-in
- Open CTRMap, select the CTRMap checkbox and click
Launch - In the "CTRMap Project Manager" window, go to the
Gamestab, click theAdd ROMbutton and select your USA White 2 NDS file - In the "CTRMap Project Manager" window, go to the
Additional plug-instab and click theInstall plug-inbutton - Select the CTRMapV plug-in that you downloaded and install it
Now you can create Gen V CTRMap projects compatible with Code Injection.
CTRMap project set up
This steps are required everytime you create a new project where you intend to use Code Injection, but only once per project.
- Open CTRMap, select the CTRMap checkbox and click
Launch - Click
File -> Create New Projectand select the path of the project, for this exampleCodeInjection/CTRMapProject - Click the
Openbutton to open the project - Download PMC
- In CTRMap, go to the
Extrastab and click theInstall/Update PMCbutton and select the PMC you downloaded (PMC_W2.rpmfor White 2,PMC_B2.rpmfor Black 2) - Make sure there is a patches directory at
vfs/data/patches, if there isn't create one - Download the latest NitroKernel DLL, if you use DeSmuMe download the
NitroKernel_DeSmuMe.dll(recomended) - In the file explorer, go to the
CodeInjection/CTRMapProject/vfs/data/patchesfolder and add the DLL you downloaded
This Project is now ready to inject your ASM, C and C++ patches.
Making a Code Injection patch
In this guide we will make a Code Injection patch for White 2 that doubles the amount of items the player gets, although pretty much useless this should teach the basic steps to make a patch from start to finish.
- This guide uses White 2 since it is more researched but it also works for Black 2 if you have the correct IDBs
External Tools
This are the tools you will need to get started making your Code Injection patches:
- ARM GNU Toolchain
- IDA Pro (any disassembler works, but most of the research and documentation has been done in IDA and thus stored in IDB files which you will have to convert if you are using a different program)
- White 2 IDBs (you can get them in the Kingdom of DS Hacking Discord )
- DeSmuMe, make sure that the console is enabled at
Tools -> Console -> Enabled
IDB research
We want to duplicate the amount of items the player gets so we want to look in the IDBs for the function that Adds an Item.
Looking in the Bag.idb in IDA and filtering the functions using "Ctrl + F" and looking for "AddItem", we find the BagSaveAddItemCore (this function is located in the ARM9 overlay so it can be found in most IDBs).
This research process will vary depending on what you are trying to implement, keep in mind not every part of the game has been researched at the same level so this step is most of the time the most time-consuming part.
IDA pseudocode to compilable code
Now that we have located the function we want to change we can create a CPP file called DoubleItems.cpp in out Patches folder in Visual Studio.

Make sure all your functions are defined and declared inside of the scope of extern "C" { <declarations> }
We can start by pasting the pseudo-code from IDA to the CPP file:
BagItem *__fastcall BagSave_AddItemCore(BagSaveData *bag, u16 item_idx, u16 quantity, HeapID heapId)
{
BagItem *bagItem; // r0
bagItem = BagSave_GetItemHandleAddCheck(bag, item_idx, quantity, heapId);
if ( !bagItem )
{
return 0;
}
bagItem->ItemID = item_idx;
bagItem->Count += quantity;
return bagItem;
}
You will see many errors, now we have to define any struct, function or global variable that the function contains.
We don't have to declare functions or struct pointers that don't get used as a struct, defining them is enough (this is called forward declaration).
- Always remove
__fastcall, it is not necesary and we avoid a compiler warning - We need to tell CTRMap that this function is overriding another one so we use a "tag" before the function name, in this case "THUMB_BRANCH" ->
THUMB_BRANCH_BagSave_AddItemCore(for more info on the relocation type tags check the Code Injection guide ) - General
typedeflikeu16are in theswantypes.hfile so we include it ->#include "swantypes.h" - The
HeapIDdefinition is in thegfl/core/gfl_heap.hfile so we include it ->#include "gfl/core/gfl_heap.h" BagSaveDatais only used as a pointer so we can use forward declaration ->struct BagSaveData;- Even though
BagItemis also a pointer we do use it as a struct so we need to declare it and define it:
- 6.1. Go to IDA and open the IDB in use (
Bag.idbin this case) - 6.2. Go to the
Local Typestab (if you don't see it useView -> Open Subviews -> Local types) - 6.3. Press "Ctrl + F" and type "BagItem" and click on the slot with the same name once
- 6.4. Press "Ctrl + E", copy the C struct and paste it in the CPP

- The function uses a function called "BagSave_GetItemHandleAddCheck" we can double click it in IDA to get the declaration ->
BagItem * BagSave_GetItemHandleAddCheck(BagSaveData *bag, u16 item_idx, u16 quantity, HeapID heapId); - To make the changes we want we can analyze the function and see that the quantity to add is added to the bagItem::Count, so to double the items given we can multiply the quantity by 2 ->
bagItem->Count += quantity * 2; - Finally we want to print a console message (this is very useful since we can't use breakpoints):
- 9.1. We include the print header ->
#include "kPrint.h" - 9.2. We make a print call at the end of the function to notify us of what happened ->
k::Printf("Added %d of the following item -> %d\n", bagItem->ItemID, bagItem->Count);
Now the patch is done and we should have the following code without any visible errors:
#include "swantypes.h"
#include "gfl/core/gfl_heap.h"
#include <cstdarg>
#include "kPrint.h"
struct BagSaveData;
struct BagItem
{
u16 ItemID;
u16 Count;
};
extern "C"
{
BagItem* BagSave_GetItemHandleAddCheck(BagSaveData* bag, u16 item_idx, u16 quantity, HeapID heapId);
BagItem* THUMB_BRANCH_BagSave_AddItemCore(BagSaveData* bag, u16 item_idx, u16 quantity, HeapID heapId)
{
BagItem* bagItem;
bagItem = BagSave_GetItemHandleAddCheck(bag, item_idx, quantity, heapId);
if (!bagItem)
{
return 0;
}
bagItem->ItemID = item_idx;
bagItem->Count += quantity * 2;
k::Printf("Added %d of the following item -> %d\n", quantity * 2, bagItem->ItemID);
return bagItem;
}
}
Compiling a patch
These instructions assume you followed the previous steps, your SWAN headers and other External Dependencies are in the CodeInjection/PW2Code/ExternalDependencies folder and your code in the CodeInjection/PW2Code/Patches folder.
- Open a cmd terminal in the PW2Code folder (in the "File Explorer" window go the the PW2Code folder, click the path input box, type "cmd" and clik "Enter")

- Paste the following command in the terminal:
arm-none-eabi-g++ Patches/DoubleItems.cpp -I ExternalDependencies/swan -I ExternalDependencies/NitroKernel/include -o DoubleItems.elf -r -mthumb -march=armv5t -OsGeneral structure of the command for a C++ patch:arm-none-eabi-g++ [patch path] -I [include directory path] -o [output path] -r -mthumb -march=armv5t -Os
-I is used to provide Additional Include Directories, which are used to search included files outside of the local folder. Since our External Dependencies include files relative to their respective local folder (#include "swantypes.h") using -I allows this files to compile without changing the source to include from our local folder (#include "../ExternalDependencies/swan/swantypes.h").
In this particular example we only use -I to include the SWAN and NK directories since they are the only ones we use, you can use it to include as many External Include Directories as you need.
I recommend that you set the output file to be in a specific folder for the ELF files, to keep stuff organized.
Injecting a patch
You can use the ESDB in the SWAN headers but I recomend making your own using this guide.
Once you have the correct ESDB follow these steps:
- Open your CTRMapProject and go to the "Extras" tab
- Click the
Convert ELF to DLLbutton and select the correct ESDB, then the ELF file you just compiled and create the DLL - If the
Install to /patchescheckbox is not enabled you will have to manually move the DLL to theCTRMapProject/vfs/data/patchesfolder - Now you can go to
File -> Export ROMand your patch should be applied in the exported ROM
The patch has been applied to the ROM, and if you play the game you should receive double the items whenever you are given them, also a message should be displayed in the console.
For example, if you buy 5 pokeball you should get 10 in your bag.
