Skip to content

DotNet

Programs written for .NET (C#, F#, VB.NET) compile to CIL/MSIL bytecode plus rich metadata inside a .exe or .dll (a PE assembly). Because the metadata keeps type, method and field names, a decompiler can reconstruct almost the original source, which makes .NET one of the easiest targets to reverse.

file reports a PE32 / PE32+ “.NET assembly”, and the binary contains the string BSJB (the metadata header) near a reference to mscorlib or System.Private.CoreLib.

Decompilers

ToolSourceNotes
ILSpy GitHubCross-platform, open source. ilspycmd gives a CLI to dump a whole assembly to .cs.
dnSpyExGitHubWindows. Decompiler plus debugger and editor: set breakpoints, edit IL/C# and save the patched assembly. The go-to when strings are decrypted at runtime.
dotPeekWebsiteFree JetBrains decompiler.
ildasm / monodisDocsDump raw IL when the high-level decompilation is wrong or obfuscated.

Common situations

  • Obfuscated assemblies

    Many challenges run the binary through an obfuscator (ConfuserEx, .NET Reactor, …) that renames symbols, encrypts strings and adds control-flow junk. de4dot recognizes and automatically unpacks most of them, producing a clean assembly to decompile.

    de4dot obfuscated.exe -o clean.exe
  • Strings decrypted at runtime

    When constants (the flag, a key, a check) are not visible because they are decrypted on the fly, do not reimplement the decryptor: open the assembly in dnSpyEx, set a breakpoint right after the decryption call and read the plaintext from the debugger. Editing the method to return true and saving is often enough to bypass a check.

  • Native, AOT or Unity builds

    If the program was compiled to native code (NativeAOT, ReadyToRun) there is no IL to decompile, so treat it as a normal native binary. For Unity games the logic lives in Assembly-CSharp.dll (Mono, decompiles directly) or, when built with IL2CPP, in a native GameAssembly that you recover with Il2CppDumper before loading the symbols into Ghidra/IDA.