Analyzing Dotnet Assemblies logo

Analyzing Dotnet Assemblies

Community
trilwu
analyzing-dotnet-assemblies

Reverse engineer .NET assemblies and executables with dnSpyEx, ILSpy, and de4dot — identifying and unwrapping obfuscators and packers, deobfuscating control flow and string encryption, handling single-file and NativeAOT publishes, and patching IL. Use when a binary is a managed PE, when ILSpy shows mangled names or empty method bodies, or when analyzing .NET malware, a loader, or a Windows application.

Overview

Publishertrilwu
Repositorysecskills
Skill nameanalyzing-dotnet-assemblies
Stars
144
Forks
15
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by trilwu on GitHub. Read the source before you install it.

Installation

Install the Analyzing Dotnet Assemblies AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/trilwu/secskills.git /tmp/secskills
mkdir -p .claude/skills
cp -r /tmp/secskills/secskills-core/skills/analyzing-dotnet-assemblies .claude/skills/analyzing-dotnet-assemblies
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Analyzing Dotnet Assemblies in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Analyzing Dotnet Assemblies on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Analyzing Dotnet Assemblies is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Analyzing .NET Assemblies

.NET compiles to IL with full metadata, so an unobfuscated assembly decompiles to near-original C#. That makes the interesting question not "how do I read this" but "what is in the way" — a packer, an obfuscator, a runtime loader, or a publish mode that hides the managed code inside a native host.

When to Use

  • file reports a PE and the binary contains a CLR header or mscoree.dll
  • ILSpy or dnSpy opens the assembly but names are mangled or bodies are empty
  • Analyzing .NET malware, loaders, or red-team tooling
  • Reviewing a Windows desktop or service application without source
  • Recovering logic from a PowerShell or C# in-memory loader

When NOT to Use

  • Unity IL2CPP — use reversing-unity-il2cpp; the C# is compiled to native
  • Xamarin/MAUI mobile — use reversing-xamarin-maui for the container extraction, then come back here for the DLLs
  • Suspected malware, before containment — use analyzing-malware first
  • Go or Rust binaries — use the matching skill

Confirm It Is Managed

bash
# Linux
file target.exe                                 # "Mono/.Net assembly"
rg -a -o 'BSJB|mscoree\.dll|System\.Private\.CoreLib' target.exe | head

# Windows
dotnet-tool: ildasm /text target.exe | head
# CLR header presence in the optional header data directory 14 is the real test
What you findPublish modeApproach
Managed PE, references mscorlib/System.Private.CoreLibFramework-dependentDecompile directly
Native PE containing an embedded managed bundleSingle-file publishExtract the bundle first
Native PE, no IL metadata at allNativeAOTNot .NET RE — use analyzing-binaries
.dll with no entry pointLibraryDecompile; find callers elsewhere
bash
# Single-file publish: the managed assemblies are appended as a bundle
# Extract with a bundle extractor, or carve on the manifest header
ilspycmd --list-bundle target.exe 2>/dev/null || binwalk -Me target.exe

Decompile

bash
ilspycmd target.dll -o ./decompiled -p       # -p writes a project structure
# GUI: dnSpyEx (maintained fork), ILSpy, dotPeek
# dnSpyEx also debugs and edits assemblies, which is why it is the default choice

rg -n 'https?://|ConnectionString|ApiKey|password|Convert\.FromBase64String' ./decompiled | head -40

Read in this order: the entry point, then any type named for the product, then anything referencing networking, crypto, or process APIs. Skip generated types (<>c__DisplayClass, <Module>) unless following a specific closure.

Identify the Obfuscator Before Fighting It

Deobfuscation is cheap when you name the tool and expensive when you do not.

bash
detect-it-easy target.exe          # or DIE's CLI: diec
# Look for: ConfuserEx, .NET Reactor, SmartAssembly, Eazfuscator, Babel,
#           Dotfuscator, Agile.NET, Obfuscar
rg -a -o 'ConfuserEx|Reactor|SmartAssembly|Eazfuscator|Babel|DotNetPatcher' target.exe
bash
# de4dot handles the classic obfuscators automatically
de4dot target.exe -o cleaned.exe
de4dot -p cr target.exe            # force a specific profile when detection fails
# ConfuserEx specifically: use a maintained unpacker fork, since de4dot's
# built-in support predates later ConfuserEx versions

What each obfuscation layer looks like, and how to handle it:

LayerAppearanceHandling
Name manglingClass1.method_3, unicode/invisible namesCosmetic — rename as you read; de4dot restores some
String encryption<Module>.Decrypt(12345) everywhereRun the decryptor: de4dot, or invoke the method dynamically
Control flow flatteningGiant switch on a state variablede4dot's CFG cleanup, or read dynamically
Proxy/delegate callsEvery call goes through a helperde4dot devirtualization
Anti-tamper / anti-debugFails under dnSpy debuggerPatch the check, or dump after decryption
Virtualization (Agile.NET, KoiVM)No recognizable IL at allDevirtualizer (OldRod for KoiVM) or dynamic analysis
Native stub wrapping ILManaged code decrypted at runtimeDump from memory — the reliable answer

Dumping from memory is the general escape hatch. Whatever the packer, the CLR must eventually hold real IL to execute it. Let it load, then dump:

bash
# MegaDumper / ExtremeDumper / pe-sieve — dump loaded managed modules from a
# running process, then decompile the dump
pe-sieve /pid <pid> /dmode 3

This is the same "let it unpack itself" pattern as packed native malware; see analyzing-malware for containment before running anything hostile.

Debugging and Patching

bash
# dnSpyEx: set breakpoints in decompiled C#, inspect locals, edit method bodies,
# and save the modified assembly. This is unusually powerful — you can change a
# license check or a validation result and immediately re-run.

Patching workflow: edit the IL or the decompiled C# in dnSpyEx, save the assembly, and re-run. Strong-name signatures break on save — either remove the strong name requirement, or if the app verifies its own hash, hook the check. For a signed assembly the app itself verifies, patching is usually the wrong tool; hook at runtime instead.

.NET Malware Notes

.NET is heavily used for loaders and commodity RATs, and the artifacts are distinctive:

  • Assembly.Load(byte[]) — a second stage decrypted in memory. Find the decryption routine, run it offline, and analyze the resulting assembly. This is the single most common .NET malware pattern.
  • Activator.CreateInstance plus reflection to hide the real call graph.
  • AmsiScanBuffer / EtwEventWrite patching — search for the byte patterns or the GetProcAddress calls that precede them.
  • P/Invoke declarations ([DllImport]) reveal native capability: VirtualAlloc, CreateRemoteThread, SetWindowsHookEx.
  • Resources and satellite assemblies holding encrypted payloads — always enumerate the resource section.
bash
rg -n 'DllImport|Assembly\.Load|CreateInstance|FromBase64String|RijndaelManaged|AmsiScanBuffer' ./decompiled | head -30
ilspycmd --list-resources target.dll

Extracted second stages go back through this skill; capability and IOC output goes to analyzing-malware, detection content to engineering-detections.

Rationalizations to Reject

  • "The names are meaningless, it's too obfuscated." Name mangling is the weakest layer. The structure, strings, and P/Invokes are intact.
  • "de4dot failed, so it can't be deobfuscated." Identify the obfuscator and use its specific unpacker, or dump from memory.
  • "It's a native EXE, so it isn't .NET." Check for single-file publish and for native stubs wrapping managed code.
  • "The strings are encrypted." The decryptor is in the assembly. Call it.
  • "I decompiled the loader, that's the malware." The loader is stage one. Find the Assembly.Load and recover what it loads.
  • "I'll read the flattened control flow manually." Run the cleanup, or debug it in dnSpyEx and watch the real path.

References

  • analyzing-malware — containment, capability model, and IOCs
  • analyzing-binaries — NativeAOT and native stub analysis
  • reversing-unity-il2cpp, reversing-xamarin-maui — the other .NET containers
  • engineering-detections — turning recovered behaviour into rules
  • dnSpyEx, ILSpy/ilspycmd, de4dot, Detect It Easy, pe-sieve, OldRod

Frequently asked questions

What does the Analyzing Dotnet Assemblies AI skill do?

Reverse engineer .NET assemblies and executables with dnSpyEx, ILSpy, and de4dot — identifying and unwrapping obfuscators and packers, deobfuscating control flow and string encryption, handling single-file and NativeAOT publishes, and patching IL. Use when a binary is a managed PE, when ILSpy shows mangled names or empty method bodies, or when analyzing .NET malware, a loader, or a Windows application.

Why use Analyzing Dotnet Assemblies on TypingMind?

Because you install it once and use it with any model. Analyzing Dotnet Assemblies is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Analyzing Dotnet Assemblies in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/trilwu/secskills/tree/main/secskills-core/skills/analyzing-dotnet-assemblies. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Analyzing Dotnet Assemblies?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Analyzing Dotnet Assemblies?

As many as you like. As long as a model supports skills, you can use Analyzing Dotnet Assemblies with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Analyzing Dotnet Assemblies AI skill free?

Yes. It is published on GitHub by trilwu under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇