analyzing-dotnet-malware-internals
Reverses .NET/managed malware: decompiling MSIL back to C#, defeating common .NET protectors and string encryptors, and tracing reflection-based loaders to recover the real payload. Activates for requ
SKILL.mdskills/analyzing-dotnet-malware-internals/SKILL.md
GitHubAnalyzing .NET Malware Internals
When to Use
- A sample is a managed (.NET) assembly — confirmed by a CLR header /
mscoreeimport orBSJBmetadata signature. - You need readable C# from MSIL and want to defeat .NET-specific obfuscation.
- A loader uses reflection (
Assembly.Load) to run an in-memory payload you must recover.
Do not use native disassembly workflows (Ghidra for x86) as the primary tool — managed code decompiles far more cleanly with a .NET decompiler.
Prerequisites
- ILSpy / dnSpyEx for decompilation and (with dnSpyEx) managed debugging.
- de4dot or equivalent for known protectors; familiarity with common .NET obfuscators.
Workflow
Step 1: Confirm it is managed
Check for the CLR runtime header and the BSJB metadata magic:
python scripts/analyst.py identify sample.exe
Step 2: Decompile
Open in ILSpy/dnSpyEx and review the entry point, Main, and module initializer
(<Module>.cctor), which protectors often abuse.
Step 3: Handle obfuscation
Recognize and undo common schemes:
- String encryption — a decryptor method called everywhere; run/trace it to recover plaintext (de4dot can often static-decrypt).
- Control-flow flattening — follow the dispatcher state machine.
- Proxy methods / renaming — rely on decompiler analysis rather than names.
Step 4: Trace reflection loaders
Find Assembly.Load(byte[]) / Activator.CreateInstance; dump the byte array argument at
runtime (managed debugger breakpoint) to recover the real second-stage assembly, then recurse.
Step 5: Analyze the payload
Decompile the recovered stage; extract C2, configuration, and capabilities for the report.
Validation
- Decompiled C# is coherent (named or recovered) and the entry path is traced.
- Encrypted strings are recovered to plaintext.
- The reflection-loaded stage is dumped and itself decompiles.
Pitfalls
- Treating the loader as the payload — managed malware is frequently multi-stage.
- Ignoring the module initializer where protectors install hooks.
- Static-decrypting strings when the scheme is runtime-keyed; debug and dump instead.
References
- See
references/api-reference.mdfor the CLR identifier. - ECMA-335 and ILSpy (linked in frontmatter).