| Type | Name | Developer | Price | License | Download | Website |
|---|---|---|---|---|---|---|
| Decompiler/IL Editor | dnSpy | 0xd4d | Open source | GPL v3 | https://ci.appveyor.com/project/0xd4d/dnspy/branch/master/artifacts | GitHub |
| Decompiler | dotPeek | JetBrains | Free | Commercial | https://www.jetbrains.com/decompiler/download/ | Official Website |
| Deobfuscator | de4dot | 0xd4d | Open source | GPL v3 | https://ci.appveyor.com/project/0xd4d/de4dot/branch/master/artifacts | GitHub |
You will also need to install the correct Unity Editor from the official Unity download archive.
Using dnSpy, load the assembly and modify the assembly attributes from:
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
To:
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.EnableEditAndContinue | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
For more information, see 0xd4d's guide to Making an Image Easier to Debug.
Save the module with the following MD Writer Options:
- Check: Preserve All MD Tokens
- Check: Preserve Heap Offsets (all)
- Check: Create Heap Even If Empty (all)
- Check: Misc Options (all except Keep Old MaxStack Value)
For Unity 2017.2 and above. For older versions, see 0xd4d's guide to debugging Unity games.
Before you do anything, backup the game's player .exe, UnityPlayer.dll, and the Managed folder.
- Download and install the correct version of Unity from the official Unity download archive.
- In the Unity installation directory, go to the
Editor\Data\PlaybackEngines\windowsstandalonesupport\Variationsfolder. - Determine whether the game is 32-bit or 64-bit, and go to either
win32_development_monoorwin64_development_mono. - In the game's root directory, delete the game's
.exeandUnityPlayer.dll. - Copy the debug
WindowsPlayer.exeandUnityPlayer.dllto the game's root directory. - Rename the game's new
WindowsPlayer.exeappropriately. - From the folder selected in #3, copy the contents of
Data\Managedto the game's respective folder, overwriting all files when prompted. - Create a new plain text file in the game's Data folder named
boot.config. - Edit
boot.config, add the lineplayer-connection-debug=1, and save.
Compile these changes into de4dot:
https://github.com/0xd4d/de4dot/pull/126/commits/28f33354c86cdbfc1d96134fab1132c87a99a5e3
We need to set up the assembly so that dotPeek can generate a new PDB file. (Currently, dnSpy does not offer PDB generation.)
Note: The line numbers in stack traces will be accurate to dotPeek's decompilation output because we're using dotPeek to generate the PDB.
- Run de4dot from the command prompt/shell to see the command line parser arguments.
- Execute the following command:
de4dot --dont-rename --keep-types --preserve-tokens --preserve-strings -fpdb <input_assembly_dll> -o <output_assembly_dll>
Important: The output assembly should have the same name as the input assembly.
A dummy PDB will be produced in the output folder.
- Load the new assembly into dotPeek.
- Generate the PDB file.
You may have to wait a while for dotPeek to generate the DecompilerCache and write the PDB file.
Note: For reference, JetBrains stores the DecompilerCache at the following location:
%LOCALAPPDATA%\JetBrains\Shared\vAny\DecompilerCache\decompiler
Unity loads MDB files, not PDB files, so we need to convert our new PDB to MDB. Fortunately, we have all the tools already.
Execute the following command:
"<unity_install_path_base>\Editor\Data\MonoBleedingEdge\bin\mono.exe" "<unity_install_path_base>\Editor\Data\MonoBleedingEdge\lib\mono\4.5\pdb2mdb.exe" "<target_assembly_dll>"
The MDB file will be generated in the same folder as the target assembly DLL.
Finally, replace mono-2.0-bdwgc.dll in the game's MonoBleedingEdge folder with the debug version from the Unity Editor's MonoBleedingEdge folder.