0

I've been looking into reverse engineering a game developped with Unity 2017.4.10, to find a way to get a freely controlled camera. I found the values that interest me in Managed/Assembly-CSharp.dll and figured out how to modify them with dnSpy, however any changes to this dll don't have any effect in-game. Using VMMap told me the game doesn't load the Assembly-CSharp.dll at all, and I assume the code for the game is in UnityPlayer.dll. That dll seems to be obfuscated, since dnSpy is unable to read it beyond hex.

My question is two-fold:

  1. Is there a way to decompile UnityPlayer.dll in a more readable way?
  2. Is it perhaps possible to inject the successfully modified Assembly-CSharp.dll into the game to replace functions loaded from UnityPlayer.dll?
1
  • VMMap doesn't see Assembly-CSharp.dll because it is not loaded the usual way. Try to replace with Assembly-CSharp.dll generated from an empty project. You'll see it is indeed the DLL with game scripts.
    – MazeGen
    Feb 2 at 17:54
1

UnityPlayer.dll is the engine itself - it doesn't contain any user-made scripts. Assembly-CSharp.dll is the main user script dll, and if, as you say, it isn't being affected, you're either modifying an unused class, or they moved to il2cpp (in which case there will be a GameAssembly.dll next to the exe) and just forgot to remove the old files.

1
  • Thank you. I'll mark this as an answer, I fixed the issue a while ago after noticing that I was simply modifying an area of code that wasn't running.
    – JMuller
    Feb 3 at 16:17
0
  1. You can disassemble GameAssembly.dll with GHIDRA, IDA or any other disassembler that supports x86. Decompilation is also available but nowhere near as with dnSpy because code is not C# anymore. It is C++ and you will need GHIDRA or IDA Pro if you have it to get best code decompilation.

  2. You cannot inject managed assemblies into the compiled GameAssembly.dll. But...

If game has moved on to IL2CPP you cannot simply edit the files anymore. You have 2 options to achieve your goal since you still have managed assemblies:

C# - Use BepInEx IL2CPP loader or similar and simply write a "plugin" (DLL written in C# code) which will execute in the game AppDomain and get you what you want. BepInEx comes with everything needed for a fast deployment and development since there are examples that will get you up and running in minutes. Use Reflection for maximum profit.

C++ - Reverse Engineer GameAssembly.dll. Some tools to consider: IL2CppDumper for dumping the methods prototypes from GameAssembly.dll, IL2CppInspector to also dump but with some options on how you want it dumped. You can also make IDA\GHIDRA scripts to apply to GameAssembly database. And you could also look at Il2CppAssemblyUnhollower. Very important to learn how to cast some data types and such.

First option is much easier especially since you have access to old managed code (Assembly-CSharp.dll) and you can look up the source in dnspy.

Second option is a bit advanced and you will not get source code and you will have to use C++ and Read\Write into the process memory manually but as said but it is a good way to get familiar with IL2CPP because not every game\project will have managed assemblies for you to see the source code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.