Someone hands you a .dll and asks, "is this safe?" Maybe it arrived in an email attachment, maybe it turned up in a download that felt off, maybe it is a plugin from a source you do not fully trust. The instinct to just run it and see what happens is exactly the instinct to resist. The whole point of analysis is to understand what a binary would do without giving it the chance to do it.
The good news for .NET specifically: managed assemblies are unusually transparent to static analysis. Because a DLL ships IL plus rich metadata, a decompiler can show you what it would do — the APIs it calls, the data it carries, the shape of its logic — while the file stays inert on disk. This is a defensive, educational guide to doing that safely. It is about understanding a suspicious assembly, not evading anyone's defenses.
TL;DR: Work on a copy, on an isolated machine, and never execute the sample. Decompile it with a static tool like Glass.NET, read what it does, and inspect its referenced APIs, strings and embedded resources. Watch for obfuscation as a signal. Static analysis reads the file; it does not run it — that is what makes it safe.
First, the safety rules
Before you open anything, set up so that a mistake cannot hurt you:
- Work on a copy. Never analyze your only copy of a sample, and keep the original untouched for reference or hand-off.
- Isolate the environment. Do the work on a dedicated analysis machine or an isolated VM with no access to anything you care about, ideally with networking disabled.
- Never execute it. This is the rule everything else supports. Do not run it, do not double-click it, do not load it into a process. Static analysis means the binary never runs.
- Follow policy. If this is a real incident at work, follow your organization's malware-handling procedures. This guide is for understanding a file defensively; it is not a replacement for professional incident response.
With that in place, static analysis is genuinely low-risk, because reading a file is not the same as running it.
Why static analysis is the safe path for .NET
A .NET assembly is not opaque machine code. The compiler emits IL — a stack-based instruction set — plus metadata naming every type, method, field and referenced API. A decompiler reads that and reconstructs C#. Crucially, tools like Glass are static analysis only: they read metadata and IL and reconstruct code, and never execute the assembly they inspect. So you get to see the program's structure and intent while it sits harmlessly on disk. There is background on how this reconstruction works in how to decompile a .NET DLL to C#, and a broader look at the practice in how to reverse-engineer a .NET app.
Step by step: reading an unknown assembly
1. Open it in a static tool
Load the .dll or .exe into a decompiler (in Glass: File ▸ Open Assembly, or drag it onto the window). The tool reads the metadata and lists the assembly's namespaces ▸ types ▸ members. If it is a native (unmanaged) binary rather than a managed one, Glass will tell you — that is a different analysis problem and a different toolset.
2. Check the assembly's identity first
Before reading any code, look at the assembly-level facts: its name, version and strong-name status, target framework, referenced assemblies, and embedded resources. This "what does this assembly reveal" summary is often the fastest tell. An assembly that claims to be a harmless utility but references networking, process-spawning or cryptography APIs it has no business using is worth a closer look. Glass surfaces this kind of assembly information and an exposure report that summarizes what an assembly exposes.
3. Read what the code actually does
Now read the reconstructed C#. Use Go To All (Ctrl+T) to jump to entry points and suspicious type names, Go to Definition (F12) to follow calls, and Find All References (Shift+F12) to see where a suspicious method is used. You are building a picture of behavior: what runs on load, what it reads or writes, what it reaches out to.
Pay attention to which framework APIs are called. Static analysis lets you see, without running anything, whether the code touches capabilities that matter — file and registry access, process creation, network calls, reflection used to load more code, or cryptographic routines. None of these is proof of anything on its own; plenty of legitimate code uses all of them. But the combination and the context tell a story.
4. Inspect strings and embedded resources
Suspicious assemblies often carry their intent in their data. Look at string literals and embedded resources for hardcoded URLs, file paths, command strings, or a second payload tucked into a resource. A decompiler shows embedded resources and lets you read string constants directly from the metadata — again, without executing a thing.
5. Drop to IL when the C# will not reconstruct
If the C# view is patchy — which happens with obfuscated or deliberately malformed assemblies — flip to the IL view. IL is readable even when clean C# reconstruction fails, so you can still follow what the code does at the instruction level. There is more on when this helps in how to view the IL of a .NET assembly.
Spotting obfuscation — and why it matters
Obfuscation is not proof of malice; plenty of legitimate commercial software is obfuscated to protect intellectual property. But on an unexpected assembly, heavy obfuscation is a signal that someone wanted to make analysis hard, and that is worth noting. Tells to look for:
-
Meaningless or non-printable names. Types and members renamed to
a,b, gibberish, or reused/unprintable characters. - Encrypted string literals. Where you expect readable text, you see calls into a decryption routine instead of plain strings.
-
Flattened control flow. Logic that jumps around a giant
switch/state machine instead of reading top to bottom. - Reflection-heavy loading. Code that resolves types and methods by name at runtime to hide what it calls.
When an assembly is obfuscated, named-symbol navigation loses value, but you can still trace structure and behavior, and an exposure summary still tells you what capabilities the assembly references. Note the obfuscation as part of your assessment and weigh it with everything else.
A worked example: reading intent, not running it
Suppose an unexpected "invoice viewer" DLL decompiles to something like this:
private static void OnLoad()
{
var data = DecodeResource("logo.png"); // "image" resource
var path = Path.Combine(Path.GetTempPath(), "svc.exe");
File.WriteAllBytes(path, data); // writes an executable
Process.Start(new ProcessStartInfo(path) { CreateNoWindow = true });
}
You never ran the file, yet the static read is damning: a resource named like an image is decoded into bytes, written to the temp folder as an .exe, and launched with no window. That is a dropper pattern, and you learned it by reading. The right next step is to preserve the sample and follow your incident-handling process — not to execute it to "confirm."
Honest limits
Static analysis is powerful, but be clear about what it is not:
- It does not observe runtime behavior. You see what the code can do, not what it does against a live environment. Dynamic analysis is a separate discipline with separate, carefully sandboxed tooling.
- Obfuscation slows you down. Determined obfuscation, packing or runtime code-loading can hide intent from a purely static read.
- It is not a verdict. Reading a file tells you a lot, but classifying real malware and responding to a real incident is professional security work. Use this to understand and triage, then escalate.
- Only analyze what you have the right to. Even for defensive work, respect the law and your organization's policy.
Analyze safely, for free
Understanding a suspicious .NET assembly starts with reading it, not running it — and a static decompiler is exactly the right tool for that. Glass.NET is free, static-analysis-only (it never executes the assembly it inspects), and built for reading unfamiliar code fast — no license, no seats, no sign-up. Download it, open the file on an isolated machine, and read what it would do before it ever gets the chance. For a related trust-check workflow, see how to inspect a NuGet package before you trust it.








