How to access Brilliant Diamond/Shining Pearl's Internal Code

The_Time_Is_Nigh

Well-Known Member
OP
Member
Joined
Jan 7, 2015
Messages
113
Trophies
0
Age
28
XP
328
Country
United States
Whether you’re interested in how the dataminers get their information, or you’re one of the people trying to rebuild the game in Unity, I think this information will be useful to you. I spent a lot of time figuring this out and researching the internal structure for myself over the last couple of days, and while this does not directly allow us to edit the code, this could be a huge boon to remaking the game in a clean project in Unity, and our research of the ROM itself.

As far as my assumptions heading into this tutorial, I will assume that you have a hacked Nintendo Switch – I know that many of you don’t have one, and while you can do this without a hacked Switch, that requires you to have a keys.txt that is illegal to share, and access to the BDSP nsp or xci and a program to dump them. I don’t want to consistently be fielding and rejecting questions of how to get those files.

You will need:

Instructions:


So yeah, if you enjoy tinkering with stuff, and want to tell us about cool stuff you find in the code, there it is. I found an interesting calendar of days that make eggs hatch faster and make Pokemon appear more or less frequently. It's not super relevant so I'm not going to share it here, but this will let more of you join in with the leaks.

EDIT:
Based on info from Falo, I will be updating this as I research Ghidra and dnSpy.
 
Last edited by The_Time_Is_Nigh,

Falo

Well-Known Member
Member
Joined
Jul 22, 2012
Messages
656
Trophies
1
XP
2,389
Country
Germany
That's not code, it's a MonoBehavior Script.
Technically you can really dig into the games code, but you need Ida Pro or Ghidra for this.

Green Joy-Con D-Pad Shells for Nintendo Switch

This is the games code and with dnSpy and a bit of work, you can retrieve the actual source code.
But it's not as easy as some people on twitter claim, il2cpp is not so easy to reverse by copy & paste.
 

HK-51

Well-Known Member
Member
Joined
Nov 13, 2021
Messages
153
Trophies
0
XP
61
Country
Argentina
That's not code, it's a MonoBehavior Script.
Technically you can really dig into the games code, but you need Ida Pro or Ghidra for this.

Green Joy-Con D-Pad Shells for Nintendo Switch

This is the games code and with dnSpy and a bit of work, you can retrieve the actual source code.
But it's not as easy as some people on twitter claim, il2cpp is not so easy to reverse by copy & paste.

oh good. I've already started on making custom locations in blender. Would like to see what happened to that italy place from the pokemon heroes movie among the many other wasted "locations of the week" But I know the modding tools are mostly going to ONLY BE USED FOR FUCKING MEME SHIT AND OTHER AUTISTIC BULLSHIT LIKE "RANDOMIZERS". IS IT SO FUCKING HARD TO NOT TAKE ANY MODDING SERIOUSLY ANYMORE! FUCK OFF WITH DISCORD!
 

The_Time_Is_Nigh

Well-Known Member
OP
Member
Joined
Jan 7, 2015
Messages
113
Trophies
0
Age
28
XP
328
Country
United States
That's not code, it's a MonoBehavior Script.
Technically you can really dig into the games code, but you need Ida Pro or Ghidra for this.

Green Joy-Con D-Pad Shells for Nintendo Switch

This is the games code and with dnSpy and a bit of work, you can retrieve the actual source code.
But it's not as easy as some people on twitter claim, il2cpp is not so easy to reverse by copy & paste.
Will do digging and update this within the next day or so, thank you.
 

The_Time_Is_Nigh

Well-Known Member
OP
Member
Joined
Jan 7, 2015
Messages
113
Trophies
0
Age
28
XP
328
Country
United States
That's not code, it's a MonoBehavior Script.
Technically you can really dig into the games code, but you need Ida Pro or Ghidra for this.

Green Joy-Con D-Pad Shells for Nintendo Switch

This is the games code and with dnSpy and a bit of work, you can retrieve the actual source code.
But it's not as easy as some people on twitter claim, il2cpp is not so easy to reverse by copy & paste.
I've got the code for main in Ghidra, all seems good, but I don't have clean code with function names and namespaces like you. Is that where dnSpy comes in? Do I have to take the names from my dummy DLL in dnSpy and correlate them over to main?
 
Last edited by The_Time_Is_Nigh,

Falo

Well-Known Member
Member
Joined
Jul 22, 2012
Messages
656
Trophies
1
XP
2,389
Country
Germany
Use the "ghidra_with_struct.py" together with a dumped "script.json" and "il2cpp.h", to get working functions and structures.
 

The_Time_Is_Nigh

Well-Known Member
OP
Member
Joined
Jan 7, 2015
Messages
113
Trophies
0
Age
28
XP
328
Country
United States
Use the "ghidra_with_struct.py" together with a dumped "script.json" and "il2cpp.h", to get working functions and structures.

Got that added in, re-running analysis now because it didn't seem to work on the one I analyzed earlier for some reason. This one threw an error too, but added in some function names. Interestingly, the function that you are showing on the your picture doesn't seem to exist right now. :huh: In fact, there is no "Pml.PokePara.Factory" at all.


Edit: Oh, also, not sure how to use the il2cpp.h with ghidra_with_struct.py, I tried multi-selecting, but that didn't work. Does it just have to be in the same folder like it was?
 
Last edited by The_Time_Is_Nigh,

OkazakiTheOtaku

no thanks, I don't want a custom title
Member
Joined
Jul 20, 2016
Messages
1,459
Trophies
1
Location
127.0.0.1
XP
3,038
Country
Japan
oh good. I've already started on making custom locations in blender. Would like to see what happened to that italy place from the pokemon heroes movie among the many other wasted "locations of the week" But I know the modding tools are mostly going to ONLY BE USED FOR FUCKING MEME SHIT AND OTHER AUTISTIC BULLSHIT LIKE "RANDOMIZERS". IS IT SO FUCKING HARD TO NOT TAKE ANY MODDING SERIOUSLY ANYMORE! FUCK OFF WITH DISCORD!
Why does the existence of randomizers offend you so much? Who hurt you?
 
  • Haha
Reactions: The_Time_Is_Nigh

FullLifeGames

Member
Newcomer
Joined
Oct 27, 2015
Messages
7
Trophies
0
Age
121
XP
58
Country
Gambia, The
Got that added in, re-running analysis now because it didn't seem to work on the one I analyzed earlier for some reason. This one threw an error too, but added in some function names. Interestingly, the function that you are showing on the your picture doesn't seem to exist right now. :huh: In fact, there is no "Pml.PokePara.Factory" at all.


Edit: Oh, also, not sure how to use the il2cpp.h with ghidra_with_struct.py, I tried multi-selecting, but that didn't work. Does it just have to be in the same folder like it was?
So I'm as new as you (which why I really would want to join your adventure here), but what I did to get it running was to open up the main file in ghidra with the Switch loader.
Then I went to File > Parse C Source and added the il2cpp.h to a new profile.
Then I went to the Window > Script Manager and added the ghidra_with_struct.py file in there and executed it.
Then I let the analyzers run.

Proof

But I also don't know what I'm doing. Am willing to learn though!

Hit me up, if you need some extra man-power in figuring this stuff out, I'm quite interested as well!
 

Cr4nkSt4r

Active Member
Newcomer
Joined
Mar 2, 2016
Messages
43
Trophies
0
XP
82
Country
Gambia, The
I also got it never to work with Il2CppDumpers il2cpp.h file, because it is missing the standard types.
So when parsing the file in Ghidra, it will just throw a error. And my Ghidra never had the types.h loaded in the Data Type Manager. There exist some issues on the GitHub page of Il2CppDumper, which solutions never worked for me.
So for FullLifeGames or the other people, something is different with their installation or generation, idk.
But since I had a custom modified Il2CppInspector version I've made for other Il2Cpp projects, I generated the header file with it and was able to parse the file, like it should and was able to run the python script without any errors.
After all that, I suddenly had the generic_clib_64 in my Data Types Manager, which also holds the types header file, which wasn't present before.

So it would be interesting, which version of Ghidra and Il2CppDumper was used and what the default Data Type Manager looks like for people where everything seems like to run out of the box.
 
  • Like
Reactions: lattechan

Immortalis202

New Member
Newbie
Joined
Nov 29, 2021
Messages
2
Trophies
0
Age
19
XP
16
Country
Italy
I'm the only one having issue with II2CppDumper? It keeps giving me:
"ERROR: Can't use auto mode to process file, try manual mode."
Using il2cpp versione 24,2.
Dumping game from Yuzu and not using switch
 

Attachments

  • immagine_2021-11-29_194813.png
    immagine_2021-11-29_194813.png
    38.4 KB · Views: 22

amomymous

New Member
Newbie
Joined
Dec 1, 2021
Messages
2
Trophies
0
Age
21
XP
18
Country
Germany
Hi! I am currently trying to manually edit some trainer teams in the masterdatas file (StreamingAssets\AssetAssistant\Dpr). Thanks to the tutorial, I can read it but how can I edit it? Does anyone know please?
Thanks in advance and have a great day everyone!
 

Chicken0895

Active Member
Newcomer
Joined
Mar 7, 2011
Messages
25
Trophies
0
XP
287
Country
United States
I'd like to know how to edit as well. Looks like we can export the asset using AssetStudio and edit in a text editor, but there does not appear to be a way to re-import the file back into the unity asset.
 

INSTRUMENTAL

Well-Known Member
Member
Joined
Nov 13, 2021
Messages
188
Trophies
0
XP
204
Country
Australia
I'd like to know how to edit as well. Looks like we can export the asset using AssetStudio and edit in a text editor, but there does not appear to be a way to re-import the file back into the unity asset.
For mods where you're editing the game files you don't put it back into the game, you use layeredfs to load your edited file over the original file.
 

Supercool330

Well-Known Member
Member
Joined
Sep 28, 2008
Messages
735
Trophies
0
XP
726
Country
United States
There's some good info here, but quite a bit missing. I'm going to assume that people already have the exefs and romfs extracted from the games (SwitchSDTool and hactool work great if you want to avoid running hacks on your SysNAND).

Useful Reverse Engineering Tools:
Il2CppDumper
dnSpyEx
Ghidra
Ghidra-Switch-Loader
AssetStudio

First step is to use Il2CppDumper as described in the original post. This has 5 main outputs: the "DummyDll" folder, a stub "dump.cs" C# file (not that useful), a C++ header called "il2cpp.h", a "script.json" file, and a "stringliteral.json" file (we won't use this at all).

From here, there's a few directions you can go:
  • Use dnSpy to explore the structure of the games code (WITHOUT implementations; all the functions are stubbed)
  • Use Ghidra to de-compile the implementation of the games code (note that this is difficult and requires a basic understanding of C and ASM)
  • Use AssetStudio to explore the games assets
We'll start with dnSpy. To get started, simply open dnSpy and add the Assembly-CSharp.dll from the DummyDll folder. You can now look at the class hierarchy for the games. These classes will only have type definitions and function signature; the body of every function will be empty (or something like return default(bool);). You can find some useful constants and such, but mostly this is useful for finding the name of the class/function you're interested in.

Ghidra is where we can actually figure out how stuff works, but giving it enough information to produce even semi-readable code is a bit tricky. Unfortunately, the Il2CppDumper header file is not immediately compatible with Ghidra (see Issue 443). To work around this, we need to do a regex replace on the header file to replace ": (\w+) {" with "{\n (\1) super;" (can use essentially any decent text editor, or a command line tool like "sed"), and then add the following block to the top of the header:

Code:
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
typedef __int8 int8_t;
typedef __int16 int16_t;
typedef __int32 int32_t;
typedef __int64 int64_t;
typedef __int64 intptr_t;
typedef unsigned __int64 uintptr_t;
typedef unsigned __int64 size_t;

Now, open Ghidra and install the switch loader plugin. Then create a new project and import that "main" file from the exefs. Once this is loaded, make sure to skip automatic analysis (for now); we need to import all the information from Il2CppDumper first. Select "File > Parse C Source..." from the menu, click the "Clear Profile" (eraser) icon, add our modified "il2cpp.h", click the "Save profile to new name" with whatever name (I like "il2cpp"), and then click "Parse to Program". Once this is done, all of the type information from Il2CppDumper will be imported into Ghidra's type manager. Now, open the "Script Manager" ("Window > Script Manager", or "Open Script Manager" on the toolbar), select "Manage Script Directories" (bullet point button), add the Il2CppDumper directory, close the "Bundle Manager", click "Refresh Script List", double click "ghidra_with_struct.py" from the list, and select the "script.json" file from Il2CppDumper. This will go through and pre-populate a bunch of information such as function declarations, parameter and return types, string literal locations, etc. After this is done, run the auto analysis using "Analysis > Auto Analyze 'main'...". Just use the default analysis options, but you can add the Switch specific "IPC Analyzer" if you want (didn't seem to make much difference).

Now, you should be able to find the function names from dnSpy in the "Symbol Tree" panel. You'll likely still need to split, retype, and rename a bunch of local variables before the decompilation makes much sense, but honestly, the Il2CppDumper script does a lot of the work. Do note that the compiler seems to aggressively inline things like bounds checks, and does a lot of loop unrolling, which can make even simple functions look VERY complicated with like 40 conditional that will never actually be false.

One thing you might encounter while exploring the code in Ghidra is something like "SmartPoint.AssetAssistant.AssetManager$$AppendAssetBundleRequest(StringLiteral_X, true, null, null, null)". This "AssetAssistant" library is how BDSP seems to load assets. The first argument (the "StringLiteral_X") is the name of the asset bundle. You can double click on the symbol name to view the value in Ghidra. If you look in "romfs/Data/StreamingAssets/AssetAssistant" you can find these asset bundles.

You can use AssetStudio to open either the top level asset bundle ("romfs/Data/resources.assets") or the individual AssetAssistant bundles mentioned above. Most of the interesting data is actually in the AssetAssistant bundles. If you're looking for data used to populate static objects in the code (such as encounter tables), the "MonoBehavior" assets are usually the ones you're looking for. Some assets may require an "Assembly Folder"; just use the "DummyDll" directory from Il2CppDumper.
 
Last edited by Supercool330,
General chit-chat
Help Users
  • No one is chatting at the moment.
    MaxiTheFox @ MaxiTheFox: hi