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.

5 (4) · 1 Review

Download materials
Save for later
Share

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.
Note: With great power comes great responsibility. The reverse engineering techniques described in this tutorial are intended for legal use cases like recovering projects you made yourself or for educational use. Stealing code and assets and claiming them as your own is illegal and I am not responsible for any legal consequences.

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.

Screenshot of a game in which a grey cutout of a man moves on a wooden stage while red crystals are shattering into pieces.

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:

A command line interface showing 6.0.400

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:

Windows x64 is highlighted

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.

ILSpy_selfcontained_x64

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.

AssetStudio.net6

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:

The interface of ILSpy

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.

The open button of ILSpy

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.

A file named Assembly-CSharp.dll

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.

A Rotate class

You may have to click the + buttons in the code to expand the methods, but it’s all right there:

Source code of the Rotate class