Modding a Unity Game; Modding Part 1
Little Intro
Hi people, I predict most of you must be following me from my Grow Stone Online mod which unexpectedly grew in popularity extremely fast (https://platinmods.com/threads/grow-stone-online-pixel-mmorpg-all-in-one-mod-mod-menu-19-features-v1-200.2008/#post-24861). I did spend a lot of time and effort on it especially because it was my first mod and my learning experience with android modding (Unity game to be specific).I'm starting this little blog to share what I've learned in hopes of helping people that want to start learning to mod too or help game developers that want to strengthen their apps against mods by understanding how they are made.
I will base these tutorials mostly around Grow Stone Online (the game I modded for those that don't know), but I think I will use other games as examples too. So maybe you can build your own mods! Or if you are a developer (hi Kernys) you can understand the logic behind modding to prevent it in your games.
I just want to warn modders that hacking games may ruin the game for everyone (online games) to a point where it can shut it down, so I recommend you use your powers responsibly.
By no means am I an experienced modder, but I am sharing the knowledge I gained from my experience from modding Grow Stone Online. Perhaps in the future when you mod games, you can give me some credit if this helped ;)
Oh and you should know some C#, knowing how Unity works is a plus.
I will be releasing many tutorials.
How Do I Start?
Tools
Here are the tools that I use (I will explain later):
ILSpy + reflexil, DnSpy (some may prefer .NET Reflector) - for dissembling the dll's you find in the Unity game.
APKTool - "A tool for reverse engineering 3rd party, closed, binary Android apps."
One_Click_Signer - Simple APK Signer after you modify an APK for unrooted phones.
Using the tools
When I first started, I used ILSpy and the plugin called reflexil. The ILSpy lets you look at the code inside the DLL files (.NET assemblies) in C#, IL, or Visual Basic. This is a tool that let's you look at how the program works without the source code. The reflexil plugin let's you directly change the IL code (the modding part).Here's a well written tutorial I used to get started with ILSpy.
DnSpy is a similar tool (https://github.com/0xd4d/dnSpy) except it's a lot more powerful (like editing the generated C# code and compiling it for you). I suggest you use ILSpy and reflexil, to begin, so you know what is happening at the core of it and what exactly you are doing by directly changing the IL code. There will many situations where you will need this skill as DnSpy isn't perfect.
The APK tool is for dissembling the apk file to get smali code from classes.dex (you probably won't know what I'm talking about but this will be a topic far off in the future) and dissembling rest of the apk. It can also recompile and resign the apk. You probably won't need this for most games.
The one click signer is obviously a tool for signing your apk easily. You need to sign your apk to install it onto an unrooted phone. If you are rooted, you can patch your phone with luckypatcher to bypass signature check and install an unsigned apk. More on it later.
The Modding Part
This won't be a follow me kind of tutorial, where you can do what I'm doing. For this part, I'll be using Grow Stone Online (GSO) to demonstrate what and how you can edit. This isn't a tutorial on how to directly mod GSO, but rather something you can learn from by looking at my though process. The reason why this isn't a "follow me" tutorial is because GSO added new versions of AppGuard, which you probably won't be able to bypass. I suggest you find another unity game to mod using what you learned here.
Also, I suggest you try playing the game GSO if you havn't. The game is actually a lot of fun and it will help you understand what I'm doing better.
Finding a Unity Game
This tutorial is for unity games so, if you want to see if your game is made with unity, you should download your game from online as an apk, or from the google play store and extracting the apk using an APK Extractor.If you look inside using winrar, you will see this:
if you look inside lib/armeabi-v7a/ and you see libunity.so, then you got yourself a unity game. However, some games might be using C++ with unity, which requires a different method.
To check if you can mod it using this tutorial, go to assets/bin/Data/Managed. If you see an Assembly-CSharp.dll, you find a suitable game to mod!
*NOTE* Once you load up the Assembly-CSharp.dll and it doesn't get loaded (says something about not finding assembly or something," then it is encrypted. I suggest you find another game to mod. It is probably encrypted by an anticheat which may be easy or not easy to bypass, but you should leave that game for later).
Changing Code
This was how I organized it when I first started out. Ignore the dll files there :) (They were different versions of mods I made for the game)
Okay, now that you have your Managed folder out, open up ILSpy or DnSpy (I will use ILSpy for the demonstration):
Drag the Assembly-CSharp.dll to open it.
Yeah my name is Kevin.
and now if you open it up, you will see a bunch of {} icons. Think of them as like packages of different classes. Open the first one without a name:
Wow! Now you got a list of classes written by the game dev to make the game!
What I usually do here is look through each classes and its methods/variables to kind of understand what each one is doing. It helps a bunch if you played the game for a bit.
Okay, so you are now ready to modify the code. Pick what you want to edit. In this case, I will modify the item cooldown (In this game, you have items that you throw that do damage and they have cooldowns).
My first guess on where to find this function is MyPlayerUnit class.
In each class, the blue icons are variables and the pink variables are the methods (you edit methods).
Right off the bat, I see the Attack() method. Let's click that:
It shows you exactly what the method does.
So reading the code tells me this:
- variable b is the player's position,
- variable direction is the direction the player is looking at,
- check if the player has a target and if it does, calculate direction based on the position of the player -and the target.
- loop through player's active bag spaces, put item into tItem and if it's a weapon and is not on cooldown, use the item.
Boom! We got the part of the code that checks if the item is on cooldown. We will backtrace this and see how the cooldown works. We won't modify this part for the cooldown since there may be checks for cooldowns somewhere else in the code. We always want to backtrace is as far as we can and change that.
We end up in the same class and now we know that the Attack() function checks if the weapon is cooling by calling this. Looking at this method, we see itemExtData.coolUntilAt which is a variable that must be storing the cooldown time.
The TryGetValue function being called is putting in the item data based on the id into the variable called itemExtData and checking if the ending cooldown ending time passed current time.
Okay, so now we click on ItemExtData class:
There we have it! Once we modify the coolTime variable, it will change the item's cooldown duration.
We can see that in the Reset(float coolTime) function, it sets this.coolTime = coolTime. What if we change this.coolTime to equal 0? Click the gear icon to open reflexil and click on the Reset() method on the left panel.
On the bottom you see the IL code you can edit to change the values!
Here is where you need to understand some IL instructions.
So what we want to modify are these 4 lines:
ldarg.0 is basically calling "this" and then loads the parameter variable with ldarg.1 into the stack. Then, with call and stfld, it puts the variable we loaded earlier into the coolTime variable.
These 4 lines are equal to this.coolTime = coolTime; in C#.
So we have to change ldarg.1 to ldc.i4 0!
ldc.i4 is an IL instruction for loading an integer. so right click and press edit on line 2.
Change OpCode to ldc.r4
Change Operand type to Single (=Float) and change Operand to 0.
Click Update.
Now go to the left panel and right click on Reset(float) and click "Update ILSpy Object Model". It will show the changes in the C# code:
However, notice how the variable coolTime is this:
We should match the variable type since float != ObscuredFloat.
We can do this by doing this.coolTime = new ObscuredFloat(0f);
Now go back to the IL code in reflexil and right click -> Create New ->
OpCode = newobj
Operand type -> Method reference
Operand = (Find the method that makes an obscuredfloat)
It is in Assembly-CSharp-firstpass.dll in my case:
Inside CodeStage.AntiCheat.ObscuredTypes:
now choose the .ctor(System.Single)
Press insert before selection or whatever and then drag the line to be after the ldc.r4
Now reload the object model and you get what we wanted!
Now, to save, click on the Assembly-CSharp.dll on the left panel and right click -> Save As
Name it Assembly-CSharp.dll and override the current Assembly-CSharp.dll.
Then open your GSO apk and navagate to the managed file. Then drag your new patched Assembly-CSharp.dll into the apk like so:
Now you have a modded apk of the game! Just need to sign it now.
Take your apk and put it in the same folder as your one_click_signer.cmd
run it and do what it tells you to do!
Then install your new modded game and profit:)
That's it. If you want to mod something else, you follow this same process.
o melhor !!!
ReplyDeleteobrigado pela ajuda.
U r de best!!! Dont get y u kicked me but OK, can I get ur contacts? Or can u let me in so I can friend flexus on discord? Because I dont have any contacts with him, grow stone is gone, discord, I can't message him because I'm not is the same go up as him, so... Idk, haha, tell me why u kicked me, I would love to know!!! ❤😉
ReplyDeletehttps://discord.gg/tVtDG6N
Deletewhat to do if every one of files you want to change has a lock on it.is there a way to unlock and then edit these files inside assembly-Csharp.dll or not?
ReplyDeleteYou said c++ have different method , may i know the method ?
ReplyDeleteOh , apparently , this tutorial doesn't work for unity game using IL2CPP , sad , thanks anyway
ReplyDelete