Universal Esp for Il2cpp Unity Games
In this writeup i will be showing you how to make an esp on any unity games that is il2cpp compiled. This writeup is inspired by https://github.com/ethanedits/Universal-Unity-ESP . Unity can be compiled with either il2cpp or mono. In mono, we can do mono injection for making our hacks, however, you cant do the same on il2cpp games. Instead, we will be treating il2cpp games as native applications. Lets get start
Before we start, we need to setup some things first. For this example, i will be using a slightly modified FPS Microgame by unity. By slightly modified, i added a static variable in the EnemyTurret class that points to the instance of an EnemyTurret making it easier for us to get its address. You can download my modified game here https://noobexploiter.itch.io/slightly-modified
Next, for making our esp lines, we will be using, imgui, there is already a template for hooking directx11 with imgui implementation, which we will use in this tutorial. https://github.com/rdbo/ImGui-DirectX-11-Kiero-Hook. We can now start
Inside the main.cpp, we will be making a new function called MainHack. We will put all our code in there. Then, we will call MainHack between
ImGui::Begin(“ImGui Window”); and
Like i said, i added a static variable in EnemyTurret class that points to the EnemyTurret Object. You can follow this tutorial to get the static variable. https://guidedhacking.com/threads/how-to-get-the-address-of-a-static-variable-in-unity-games.16246/
Just a note, instead of using 0x5C, use 0xB8 since my game is 64 bit(i forgot to compile it as 32 bit) so it is twice as big.
Getting the position
The EnemyTurret class Inherits from MonoBehaviour and MonoBehaviour inherits Behaviour and Behaviour inherits Component and the Component class has a function called transform which will return the Transform object of our EnemyTurret Object
The tranform class holds the position of a gameobject. We will first make our transform function and call transform to our EnemyTurret object. If you dont know how to call functions, follow this guide https://www.unknowncheats.me/wiki/Calling_Functions_From_Injected_Library_Using_Function_Pointers_in_C%2B%2B.
For the address of the function, we will be using the RVA, the RVA is the offset of the function from the GameAssembly.dll
Now we have the transform object of our turret. The Transform class in unity has a property called position which is a vector 3 that holds the position of a game object. Properties on C# can be called just like a normal function call.
But first, we need to make our own Vector3 struct. Vector 3 is just 3 float, called x,y and z.
Now we can write our own position function and call it with the transform of our turret.
Camera And WorldToScreen
In making esp, WorldToScreen is a function that transform the position of an object in a 3d world to screen coordinates. Hopefully for us, Unity has a built in worldtoscreen function in the Camera class called WorldToScreenPoint.
We need to get the current camera first. In unity, the camera class has a static property called current that returns the current camera in use.
We can call this, like a normal function call.
Now that we have camera object. We can now call the WorldToScreenPoint
WorldToScreenPoint accept a Vector3 as an argument which is the position of our target EnemyTurret Object.
This is what our code looks like now.
Esp with ImGui
Now that we know where to draw, we will now begin to draw. We will be using the function AddLine of ImGui to draw a line from the bottom of the screen, to the position of the Enemy turret
In ImGui, it only accepts ImVec2 for its coordinate so we will make our ImVec2 variables first. Then we will call the AddLine Function
So lets build it, compile it, and………
Its not working. The x position of the esp line is correct. However, the y position is wrong. After some googling, i found this https://forum.unity.com/threads/worldtoscreenpoint-doesnt-work-on-y-screen-axis.34161/. Here, he said to subtract the Screen height to the y position. So lets do the same.
Build it again, inject it, and now its working fine.
This is the end of the writeup, thanks for reading.