How to Reverse Engineer a Unity Game
In this tutorial, you’ll use ILSpy and AssetStudio to extract code and assets from a compiled Unity game. By Eric Van de Kerckhove.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
How to Reverse Engineer a Unity Game
15 mins
In the context of software, reverse engineering is the practice of analyzing a system to extract design and implementation information. This is often used to better understand how software functions. One method of reverse engineering is decompiling, which performs the opposite operations of a compiler to convert executable programs back into human-readable code.
You can decompile Unity games using specialized tools to extract the code and most assets. Here are some common use cases where this can be useful:
- Recover the lost code and assets of a game you made.
- Take a look at the source code or 3D models of a game to study and learn from.
- Mod a game by replacing assets with your own.
In this tutorial, you’ll use ILSpy and AssetStudio to decompile a Unity game on Windows. Along the way, you’ll learn how to:
- Use ILSpy to decompile a game’s code
- Save the code to your computer
- Inspect assets using AssetStudio
- Extract audio and 3D models from a game
While I’ll be covering Windows applications in this tutorial, there are alternatives for Linux and macOS out there with the same functionality like AvaloniaILSpy and UnityPy. I’ve also added some more software considerations at the bottom of the tutorial, some of which are cross-platform.
Getting Started
Click the Download Materials button at the top or bottom of this page to download the sample game, Avoiding Responsibility. Extract the zip file to a folder for use later on. If you want, you can play the game on Windows by running Avoiding Responsibility.exe. You can quit the game by pressing Escape or Alt + F4.
Granted, there’s not much going on except for some red “responsibility” crystals falling down from above while a cheery tune plays in the background. It won’t be the game of the year anytime soon, but that’s not the focus of this tutorial. In the following sections, you’ll pick this game apart to access its source code and assets.
Tool requirements
On to the tools! Both ILSpy and AssetStudio need the .NET 6 SDK to work. To check if you already have this SDK installed, open a Command Prompt by opening the Start menu, entering “cmd” and pressing Enter. With the Command Prompt open, enter the following command and press Enter to execute it:
dotnet --list-sdks
If you have .NET 6 SDK installed, there should be a 6.X.X
entry in the list:
If there’s no 6.X.X
entry, or you get an “dotnet is not recognized” error, you’ll need to install the latest version of the SDK from here: https://dotnet.microsoft.com/en-us/download/dotnet/6.0
Choose the installer version that matches your CPU’s architecture and download it. In most modern systems, this will be x64:
Now install the SDK and re-run the dotnet --list-sdks
command in a Command Prompt to verify it’s installed.
Downloading ILSpy and AssetStudio
With the requirements out of the way, head over to the releases page of ILSpy: https://github.com/icsharpcode/ILSpy/releases
Click on the Assets button at the bottom of the changelog of the latest release and click on the ILSpy_selfcontained_x64 zip to download it.
Once the download finishes, extract the zip to a folder for use in the next section.
Next up is AssetStudio, the download process here is similar to IlSpy. To start off, head over to the releases page: https://github.com/Perfare/AssetStudio/releases
Click the Assets button if the assets aren’t visible straight away and click on the .net6
link to download the .NET 6 version of AssetStudio.
Extract the contents of the zip to a folder for later use.
Extracting Source Code
To extract the code from the sample game, you’ll need to use ILSpy, which is a an open-source .NET assembly browser and decompiler. Unity games use C# for their scripts, which get compiled to Intermediate Language, or IL for short. IL is a lower level language than C#, but still higher level than machine code. Here’s what IL code looks like:
.method public hidebysig static void Main() il managed
{
.entrypoint
// Code size 11 (0xb)
.maxstack 8
IL_0000: ldstr "Hello, World"
IL_0005: call void [mscorlib]System.Console::WriteLine
(class System.String)
} // end of method HelloWorld::Main
By default, Unity compiles all scripts together into a single file named Assembly-CSharp.dll. As a Unity developer, you can choose to group scripts in additional assembly definitions files, which will generate extra assembly files once you compile your game. ILSpy can read the IL code in these files and convert them back to C# classes.
Time to take a look at what IlSpy offers! Open the ILSpy folder and double click on ILSpy.exe to start ILSpy. If your requirements are in order, this is what you’ll see once the application loads:
Exploring ILSpy
The interface is split up into two main sections: a list of loaded assemblies on the left and the decompiled C# code on the right. ILSpy has some commonly used .NET assemblies loaded by default like mscorelib
and System
.
To load the sample game’s CSharp assembly, click on the folder icon in the menu bar or press CTRL + O on your keyboard to open a folder browser window.
Navigate to the Avoiding Responsibility folder you unzipped earlier, there should be a file named Avoiding Responsibility.exe in there. From there, navigate to the Data folder, named Avoiding Responsibility_Data in this case and open the Managed folder in there. In short: Game folder / Data / Managed.
You should see a list of DLL files in there.
Double-click Assembly-CSharp.dll to load the assembly in ILSpy. If all went well, a new entry was added in the Assemblies list on the left named Assembly-CSharp.
To inspect the assembly, click on the little + button on the left of the entry to expand the assembly. This unveils the following items:
- Metadata: This contains information on the assembly, including its headers and strings.
- References: A list of other assemblies this assembly references. ILSpy will automatically load in these assemblies when you’re inspecting code that references them, so don’t be surprised if the Assemblies list gets filled up with more assemblies.
- A “-” namespace: The sample game doesn’t use namespaces in its code, but other projects can have a list here of the different namespaces used. This is where the source code lives.
Expand the -
namespace to get your first glimpse of something familiar — a list of classes! Next, click on the Rotate class and you’ll see the source code being shown on the right.
You may have to click the + buttons in the code to expand the methods, but it’s all right there: