in Games, Programming, Tutorial, Unity

A practical tutorial to hack (and protect) Unity games

If there’s a term which is often misunderstood, that’s for sure hacking. When it refers to softwares, it usually gets a negative connotation which smells of piracy and copyright infringements. This post will not cover any of these topics; quite the opposite, I strongly discourage readers from taking any action which will damage (directly or indirectly) other developers. That said: yes, this post will be a practical tutorial to hack into Unity games. You can use the techniques and tools described in this post to check how safe your games are. If you’re a developer, you’ll also find useful snippets of code and technique to add an extra layer of protection to your games.

Introduction

At the heart of hacking, there’s knowledge: understanding how Unity3D compiles games is essential if you want to hack them. This post will show how resources are compiled into Unity3D, how they can be extracted and (when possible) repacked. This allows not just for extreme modding, but also to advanced debugging. Unity3D often works as a black box, and from a version to another many features have been radically changed. Over time, this has caused several issues which can only be understood by comparing how the same code has been compiled against the different versions. Decompiling a game is also the ultimate way to find its secrets. That’s actually how the solution to the last secret in FEZ has been discovered.

fez

Finding the Unity3D files

If you have a Unity3D game, chances are you’ll have it on Steam. To access its folder, find the game in your library and explore its properties. “Browse local files…” in the “Local files” tab will open the folder where the game is stored.

local files

When a game is compiled for Windows with Unity3D, is always packed in the same way. The destination folder will have the executable file, let’s say Game.exe, and a folder called Game_Data.

Diving into PlayerPrefs

The most common way Unity3D games store data is by using PlayerPrefs. If you’re on Windows they’re stored in the system registry. You can access them by using a tool called Regedit which is already installed on Windows. PlayerPrefs are stored in the folder HKEY_CURRENT_USER\Software\[company name]\[game name]:

regdit

While UnityGraphicsQuality contains the launch configuration and is created by the Unity3D launcher, all the other entries are created by the game. Many games use PlayerPrefs to remember particular settings, achievements or progress. More substantial data, such at the actual save games, are often stored in proprietary formats hence they’ll not be covered.

How to protect PlayerPrefs

You cannot prevent users from messing up with the system registry. Hence, you cannot prevent them from altering your PlayerPrefs. What you can do, however, is adding a checksum which will detect any edit. To do this, you need to save another value which is somehow calculate taking into account all the other ones.

// Download: https://www.patreon.com/posts/3301589
public class SafePlayerPrefs {

    private string key;
    private List<string> properties = new List<string>();

    public SafePlayerPrefs (string key, params string [] properties)
    {
        this.key = key;
        foreach (string property in properties)
            this.properties.Add(property);
        Save();
    }

    // Generates the checksum
    private string GenerateChecksum ()
    {
        string hash = "";
        foreach (string property in properties)
        {
            hash += property + ":";
            if (PlayerPrefs.HasKey(property))
                hash += PlayerPrefs.GetString(property);
        }
        return Md5Sum(hash + key);
    }

    // Saves the checksum
    public void Save()
    {
        string checksum = GenerateChecksum();
        PlayerPrefs.SetString("CHECKSUM" + key, checksum);
        PlayerPrefs.Save();
    }

    // Checks if there has been an edit
    public bool HasBeenEdited ()
    {
        if (! PlayerPrefs.HasKey("CHECKSUM" + key))
            return true;

        string checksumSaved = PlayerPrefs.GetString("CHECKSUM" + key);
        string checksumReal = GenerateChecksum();

        return checksumSaved.Equals(checksumReal);
    }
    // ...
}

(download SafePlayerPrefs here)

The class above is just an example and works with strings only. It requires the developer to specify a secret key and a list of all the items you want to be protected:

SafePlayerPrefs spp = new SafePlayerPrefs("MyGame", "PlayerName", "Score");

It can then be used as follow:

// Set PlayerPrefs as normal
PlayerPrefs.SetString("PlayerName", name);
PlayerPrefs.SetString("Score", score);

SafePlayerPrefs.Save();

// To check if there has been an edit
if (SafePlayerPrefs.HasBeenEdited())
    Debug.Log("Error!");

Before savings it calculates a checkum on all the protected properties. If the player alters one of the value, he won’t be able to regenerate the checksum and cause the application to detect the change.

Decompiling .NET

During compilation the source code of a program is converted from a Human readable language into a set of instructions, compatible with the target machine which will execute them. During this process, most of the original source code is lost. Comments and indentations are completely stripped away since they serve no purpose for machines. Very often the code is also optimised, a process which changes its structure into a more efficient one. Decompilation is the process which takes an application and converts it back into its source code. When you’e running a piece of software on your machine, you have de facto all of its code. When compiled for Windows, Unity3D stores its compiled resources in the Managed folder of the game data. They are bundled in DLL files. The ones we are interested in are Assembly-CSharp.dll, Assembly-CSharp-firstpass.dll and Assembly-UnityScript.dll.

files

Exploring the content of a DLL is a very easy task and there are several programs which can do it for free, such as ILSpy and dotPeek.

window

This technique is particularly effective for Unity3D games because very little optimisation is actually done. Morever, Unity3D doesn’t attempt to change or hide variable names. Since they are preserved, understanding the decompiled code of a Unity3D game is actually very easy.

How to protect your source codes

Despite this, there are some precautions one can take. Unity 3D Obfuscator is a useful application which takes a compiled game and obfuscates its .NET code. Despite being very good at its job, many classes which are referred from outside of the DLL cannot be renamed since this would break their connection.

HtmlImage

If a part of your code is sensitive and should not be accessed, you might want to move that to a server.  For instance, updating scores directly from your game is often a bad move since this might allow players to hack with your code.

Unpacking assets and resources

The majority of resources in Unity3D are bundled in a proprietary format. These files are stored in the _Data folder and have the .assets and .resource extensions. Currently, the best program to explore and extract these files is Unity Assets Explorer.

asset

Unfortunately, the interface is very poorly designed and the program comes with several critical bugs. Despite these limitations, it is able to extract the majority of textures from the game. They are extracted in the most unfortunate format, DDS. If you want to visualise them outside Unity Assets Explorer, you may need Windows Texture Viewer.

This technique also exports shaders. They are already compiled and, to the best of my knowledge, there isn’t a tool to decompile them into Cg / HLSL. Despite this, they can still be imported into another project and they’ll work just fine. Remember that stealing a an asset is an act of piracy.

Capture the geometry

There’a another aspect which has not been discussed yet: 3D models. Most models are scattered in different assets files, and some other might be generated procedurally within the game. An interesting approach is to dump them directly from the graphics card memory. When a game is running, all the data about the textures and models of the scene you’re currently playing are loaded into memory. 3D Ripper DX is a nice program which allows to grab all the geometry currently on the screen. It is not the easiest to use and you’ll need to read its guide. It also requires 3D Studio Max to import the models it exports.

ripper

Hacking into the game’s memory

A very well known tool to hack games is called Cheat Engine. It read the memory where you game is and allows to change it arbitrarily. This tools is very advanced and if you don’t know what you’re doing there’s a high change you’ll just crash everything.

Cheat_Engine_5.4

This application takes advantage of the fact that is very rare for a game to protect its variables. Health and ammos, for instance, are often store in float variables; changing them will automatically alter your stats in the game. Cheat Engine allows to scan the memory of the game for a certain value. For instance, let’s imagine you have 100 bullets; you can do an initial search for all the memory locations which contain the value 100. Then shooting a bullet and search for all those memory locations which now contain 99. By repeating this approach you can easily discover the majority of variables within a game. Editing them is a little bit tricky; games generally make the assumption their variables are not externally modified, so this can corrupt the state of the current play. More often, you’ll just end up with a segmentation fault and the game will crash.

How to protect the memory of your game

Cheat Engine works only because variables often have no protection. It is easy to make it ineffective just by being more careful in the way you manipulate them. The class SafeFloat can be used to replace normal floats, with the advantage that it will store them “encrypted”:

// Download: https://www.patreon.com/posts/3301589
public struct SafeFloat {
    private float offset;
    private float value;

	public SafeFloat (float value = 0) {
        offset = Random.Range(-1000, +1000);
        this.value = value + offset;
	}
	
	public float GetValue ()
    {
        return value - offset;
    }

    public void Dispose ()
    {
        offset = 0;
        value = 0;
    }

    public override string ToString()
    {
        return GetValue().ToString();
    }

    public static SafeFloat operator +(SafeFloat f1, SafeFloat f2) {
        return new SafeFloat(f1.GetValue() + f2.GetValue());
    }
    // ...the same for the other operators
}

(download SafeFloat.cs here)

You can use SafeFloat as follow:

SafeFloat health = new SafeFloat(100);
SafeFloat damage = new SafeFloat(5);

health -= damage;

SafeFloat nextLevel = health + new SafeFloat(10);

Debug.Log(health);

If you are displaying your health on the screen, hackers can still intercept that number and change it. But it won’t change the actual value stored in the memory.

Conclusion

Unfortunately there’s very little you can do to protect your games. Once they’re installed onto a player’s machine, you’ve been handling all of your code, textures and models. If someone wants to decompile your game and steal your assets is just a matter of when, not if.

Despite this, there are sensible techniques you should employ when developing a game. You don’t need to live in a panic room, but at least don’t leave the door open when you’re going out.

Other resources

  • Unity3D Attack By Reverse Engineering: An interesting article which highlights common security flaws in the way scores are handled in most Unity3D games;
  • disunity: Disunity is the best tool to explore and extract assets files. Unfortunately is not compatible with Unity5;
  • Unity Studio: an interesting tool to visualise and extract 3D models from assets file. Not compatible with Unity5.
💖 Support this blog

This website exists thanks to the contribution of patrons on Patreon. If you think these posts have either helped or inspired you, please consider supporting this blog.

Patreon Patreon_button
Twitter_logo

YouTube_logo
📧 Stay updated

You will be notified when a new tutorial is released!

📝 Licensing

You are free to use, adapt and build upon this tutorial for your own projects (even commercially) as long as you credit me.

You are not allowed to redistribute the content of this tutorial on other platforms, especially the parts that are only available on Patreon.

If the knowledge you have gained had a significant impact on your project, a mention in the credit would be very appreciated. ❤️🧔🏻

Write a Comment

Comment

74 Comments

  1. Hi,

    thank you for the interesting article.
    I wonder if the SecureString class can come into play anywhere e.g. secure the memory values at runtime

  2. Hello

    Thanks for this article. That triggered my curiosity, so I want give a try.
    Just a little remark about how to find the code (thank the “other ressources”).
    (In my case after a search on all my computer, I cannot find any file with .unity3d extension)
    A solution is just to reload web page and print the network communication with firefox development tools. The request with the bigger size is the retrieve of unity3d application 😉

    Regards

  3. Hi Alan! Superb article, I am interesting as 3d modeler. What about security uploading the game to a website (webGl I think It is)?

  4. In Unity 5.4 the IL2CPP scripting backend for Android is no more experimental, and it turns JIT to AOT, so the APK will not contain the C# source code in DLLs.

    • A proper cheksum also requires a solid understanding of how the data is packaged and arrange. This is waaay more complicated and prevents people from using trivial softeare such as CheatEngine. Of course, if you understand the code and re-generate the checksum, you can bypass it. 😀

      • Ok, then I understand it correctly 😀

        It’s definitely useful, and gives me some ideas 🙂

        Btw, thanks for writing your article(s), they are always good to read, and there is always much to learn from them.

  5. Great article! if some of you are looking for some more tips about creating a game, I highly recommend this blog too: blog.theknightsofunity.com

    • Hey Andrea!
      I don’t think I can help you with this unfortunately.
      Mostly because many developers are not happy with changes behind made to their source code! These changes often break the game, and can potentially affect other players if you there is a leaderboard or an online scoring system! 😮

    • Just want you to know… it’s people that want to hack important variables that cause Indie developers to stop developing. You wanting to make a hack to give unlimited cash, completely defunds a game. So, in the end, all that all of us get is ten thousand rip-off games from China and India. Or, it gets us so many aim-bot cheats that games that we enjoy get shut down because the user base is tired of cheaters.

      What I am saying is *you* are the plague that is killing the industry. And yeah, my finger is pointed at you. So, no… I would never help you in this kind of endeavor.

  6. how i hack unity vr games so i can see at gameview window right eye instead of left eye? i know command at unity for this is stereoTargetEye

    • Hi Jeik!

      Despite the title, the point of this tutorial is not to hack games, but to learn how to develop more robust defences against those attacks.

      While I find rather fun to decompile games I played to changed or mod them, I would strongly discourage readers from hacking other games for personal gain against others. Wheather that be financial or not.

      In particular, I would not attempt to change online games, since this could potentially disrupt servers and mess up leaderboards.

      • I’m on board with Alan here. If you hack a single player game, the only person you are really hurting is yourself. If you do it with a multiplayer game, you’re hurting everyone involved in playing the game with you.

        PLUS – you are taking the vision that the game developer had, and destroying it. So… please stop “hacking” games to make cheats. That’s not the point of this.

  7. Hi Alan,
    Did you tried turn some collisions off using CheatEngine?
    Variables we written our self we can protect them any ways we want but if it’s Unity’s variables. How can we protect them.

    • Hey!
      I have never tried to turn collisions off with CheatEngine.
      I usually use other softwares to change and recompile the DLLs, when I want to do some changes.
      It is unlikely you’ll be able to change Unity’s DLLs. However, it is also exceptionally unlikely that players will hack into them.
      Unless your game is *exceptionally* popular, I wouldn’t bother spending time on this.

  8. hi
    very interesting article
    the subject is become super important when we have gambling game under develop targeting Android.
    besides every things you mentioned, there are authentication and authorization problems.Encoding and decoding in-game or communication data.
    what is your suggestion on these? is android safe enough? because we know with a rooted android simulator and other hack/crack/spy/sniff programs, you can do everything you want, it is just a matter of time

    • Hey!
      Thank you.
      I don’t have much experience with mobile development so is hard to tell.
      I would always encrypt the data, even if just with a simple checksum.
      Any system can be hacked, but is just about making it hard enough to discourage 99.99% of players.

    • Hey!
      It all depends on the technology the game is based on, and on how the data is stored.
      For instance, it could be stored in external files that can be modified. Or it can be compiled directly in the game source code.
      And it could be procedural, or baked into textures. So it’s very hard to answer this question as it varies so much between different games.

  9. Hi,

    wonderful article, but i have a question with the safe floats.
    Is it possible that you can edit them directly in the inspector?

  10. Safe float is not a very good method….simply adding to the float does NOTHING to prevent hackers from searching unknown value and follow it with increased/decreased value scans….shoot even after finding the first value they wanted they know exactly how much is added to every float and can follow it up with exact scans afterwards….. yes, protect memory; but use a better method.

    also, an app called DnSpy will not only decompile to let you look at a games source dlls, but it will also let you modify and recompile as a tip. dotPeek and the other mentioned decompiler just let you look, but dnspy lets you recompile the source into a hacked version of the app.

    • Hi! Thank you for your comment.
      This was a very simple example, but you can also multiply it with another value (possibly negative or positive) so that you won’t be able to track the “up” or “downs”.
      Or you can change the random value added/multiplied every 10 uses or so.

  11. Yep just tried ILSpy on my own game and *poof* there’s 3 years of work available right in front of my eyes. Scary.

    Thanks for sharing and letting us know about these risks.

  12. I’m not finding the assembly-unityscript.dll file in this unity file, I’ve found the other two, but the third one isn’t in the managed folder.

  13. Hi, I’m trying to use this to mod a unity game which has recently added an update encouraging mods. All of the things in this article work for viewing the files of the unity game, but I don’t know how to actually edit any files.

    • Hey!

      Assets (and models in general) are one of the hardest things to extract.
      I would honestly not worry about that, unless your game in insanely popular.
      Most of the time, is simply easier to re-do the assets from scratch, rather than extracting and cleaning them.

  14. What about the IL2CPP buidled Games ? ? ? problem that i have on UWP i canbt get proccesses that are running on machine to detect services.

  15. Hi, Thanks for the awesom post/tutorial, I’m making a Game with unity and I really concern about this topic, almost paranoic haha. But this Tutorial is really usefull. As you say, after hours and hours of searchig about this is not a matter of “If” but “When”. So, I have 1 Question:

    1.- It could works if I put 2 obfuscator in my proyect, one from Asset store directly in my proyect (there are a few plugin/assets obfuscator out there) and then use other like “Unity 3D Obfuscator” once I build my proyect?

    Than you again.

    • Hi! Thank you for the kind message!

      I think the most important question is: is this time well spent? If you are working on a game that has leaderboards or multiplayer, then you may want to add an extra layer of security. But checkums are usually more than enough.

      If you are trying to protect your assets, they can very easily be redone regardless of how well you are protecting them.

      For the code, is there any reason why it should be protected so much? If there really isn’t, then I would honestly not get too worried!

    • Usually, yes. With Google encouraging software piracy — their official statement is “make your game to where people want to buy it.” Google’s been supplementing apk sites because countries are restrictive to their citizens. And, google does absolutely nothing to protect the apk files whatsoever. So, you can easily assume that with one of those sites, and ILSpy, your game is as good as hacked. It’s disturbing, really, because that means that you won’t make a dime off of your mobile game until you become “huge”. Note: 99.95% of all mobile developers *lose* money on their games, even though the mobile gaming industry is in the billions of dollars (range) and google touts that to lure in more people to make games… because google makes money off of you, whether you make money or not.

  16. I would say this is one of the best article I’ve read.. From beginning to end you nailed it totally. To write this you might have worked hard for research.
    Thanks for sharing this good article.

  17. hello ty very much for the article, I was wondering is this is still transferable to recent versions of unity. I have been thinking about unity preservation for a while now specially after this talk https://www.youtube.com/watch?v=T3u7bGgVspM.

    trying searching more info about unity preservation and this blog is one of the very few resources around. ty !

Webmentions

  • hack prevention – central November 29, 2023

    […] A practical tutorial to hack (and protect) Unity games […]

  • Unity: Documentação e Tutoriais | November 29, 2023

    […] A practical tutorial to hack (and protect) Unity games […]

  • 치트 방지 방법 | 쉬운 건 옳다 November 29, 2023

    […] A practical tutorial to hack & protect Unity games – Alan Zucconi […]