Read-only DLL Inspection — amsi.dll (Part 1)

Read-only DLL Inspection — amsi.dll (Part 1)

Summary

Learn a repeatable read-only workflow for Windows DLLs. This part uses amsi.dll as the worked example; the same steps apply to other targets — see Choosing a DLL for read-only inspection.

Series read-only-dll-inspection · Part 1
Example target %windir%\System32\amsi.dll
Lab verified 192.168.50.252 — 101.5 KB, v10.0.19041.4355, signature Valid (inventory)
Prerequisites Lab VM; tools in Step 0; optional target pick from 00-dll-target-selection
Refs PE structure · Microsoft Sysinternals
Read-only boundary

Do not rename, patch, replace, or take ownership of system DLLs. Part 2 will go deeper in Ghidra; this part stops at basic x64 vocabulary.

Table of Contents


What is this guide?

0. Purpose

Build a repeatable, read-only inspection workflow for Windows DLLs. You will collect facts — path, version, signature, who loads it, PE structure, exports, and decompiler hints — before drawing any security conclusions.

amsi.dll (Antimalware Scan Interface) is the worked example in this part because:

Pick a different DLL?

The workflow is DLL-agnostic. Use Choosing a DLL for read-only inspection for tiered candidates (version.dll, wldp.dll, crypt32.dll, …) and a prioritization rubric. Substitute your DLL name in each step below.

This guide is not about bypassing AMSI.

1. High level (explain like I'm five)

Imagine Windows keeps a toolbox of shared parts. A DLL is one part many programs can borrow.

amsi.dll is like a spell-checker for suspicious computer instructions — programs ask it to look at text or scripts before running them.

You are going to:

  1. Find the toolbox drawer where amsi.dll lives.
  2. Check the label (version, size, date).
  3. Check the Microsoft sticker (digital signature).
  4. See which programs currently borrowed that tool.
  5. Open the box and read the instruction sheet without turning anything on.
  6. Use a magnifying glass (Ghidra) to read what the functions probably do.
  7. Learn a few words of the machine's language (x64 assembly).

You never break the seal. You never swap the part. You only look.

2. Deep breakdown

Each numbered step below follows the same three-part shape:

Layer Question it answers
0. Purpose Why this step exists
1. High level The idea in plain language
2. Deep breakdown Exact clicks, commands, and what to write down

Step 0 — Set up safely

0. Purpose

Create a learning environment where mistakes do not damage your daily machine or teach bad habits (disabling defenses, patching system files).

1. High level (explain like I'm five)

Use a practice computer — like a toy kitchen instead of the real stove. Keep the smoke alarm on. Only bring trusted tools from the real store. Do not take apart Windows' built-in parts.

2. Deep breakdown

Prerequisites checklist

Rules (non-negotiable)

Rule Why
Do not rename, patch, replace, or take ownership of amsi.dll You are learning inspection, not evasion
Do not disable Defender "to make analysis easier" Real defenders keep protections on; your lab should too
Work on copies when a GUI tool imports a file Import/copy ≠ execute, but copies reduce accidental execution risk
Install tools only from official sources Supply-chain risk is real

Install these tools (official sources only)

Tool Role Official source
Process Explorer See which processes loaded a DLL Microsoft Sysinternals
Process Monitor Optional; filter file/registry activity during learning Microsoft Sysinternals
Dependencies Visual import/export dependency graph Dependencies project releases
PE-bear or CFF Explorer PE headers, sections, imports, exports PE-bear: hasherezade releases · CFF: ntcore
Ghidra Disassembly and decompilation NSA Ghidra releases
WinDbg Preview Optional; kernel/user debugging literacy Microsoft Store — WinDbg Preview

Optional (helpful for exports listing)

Suggested VM snapshot

Before you start Step 1, take a VM snapshot named something like pre-amsi-inspection. If you accidentally install a shady "cracker" tool, revert instead of troubleshooting for hours.


Step 1 — Locate amsi.dll and collect its details

0. Purpose

Establish a baseline fingerprint for the file: where it lives, how big it is, which version Windows installed, and when it last changed.

1. High level (explain like I'm five)

Ask Windows: "Where is amsi.dll, how heavy is it, what version is on the sticker, and when was the sticker last updated?"

Write the answers in your notebook. Later, if something looks weird, you compare against this baseline.

2. Deep breakdown

Open PowerShell (normal user is fine)

Press Win, type PowerShell, open Windows PowerShell — not necessarily "Run as administrator" for this step.

64-bit amsi.dll (native on 64-bit Windows)

$path = "$env:windir\System32\amsi.dll"
Get-Item $path | Select-Object FullName, Length, LastWriteTime, VersionInfo

Example shape of output (your numbers will differ; lab .252 on 2026-08-31 shown):

FullName      : C:\Windows\System32\amsi.dll
Length        : 103936
LastWriteTime : 6/16/2025 1:05:07 PM
VersionInfo   : File:             C:\Windows\System32\amsi.dll
                ...
                FileVersion:      10.0.19041.4355
                ProductVersion:   10.0.19041.4355

32-bit copy on 64-bit Windows (SysWOW64)

64-bit Windows keeps a separate 32-bit compatibility tree. Inspect it separately:

Get-Item "$env:windir\SysWOW64\amsi.dll" |
  Select-Object FullName, Length, LastWriteTime, VersionInfo

On pure 32-bit Windows (rare today), only the System32 path applies.

Record this table

Field System32 value SysWOW64 value (if applicable)
Full path
File size (bytes)
File version
Product version
Last write time

What "normal" looks like

Troubleshooting

Symptom Likely cause What to do
Cannot find path AMSI component not present on edition/sku Confirm Windows edition; check %windir%\System32 in Explorer
Access denied on Get-Item Rare policy restriction Try read-only Explorer Properties; confirm you are not redirecting with hard links
Very old LastWriteTime File not updated recently Cross-check Windows Update history before assuming tampering

Step 2 — Verify its signature

0. Purpose

Confirm whether Windows sees the file as authentically signed by Microsoft at inspection time. Signature validation is a core trust signal for system DLLs.

1. High level (explain like I'm five)

Official Microsoft parts come with a tamper-evident sticker. You check the sticker with Windows' own checker. Valid means the sticker passed right now.

A bad sticker is a clue, not automatic proof that hackers were here — investigate calmly.

2. Deep breakdown

PowerShell method

$path = "$env:windir\System32\amsi.dll"
Get-AuthenticodeSignature $path |
  Format-List Status, StatusMessage, SignerCertificate

Healthy result (conceptual):

Status            : Valid
StatusMessage     : Signature verified.
SignerCertificate : [Subject]
                      CN=Microsoft Windows
                      ...

Repeat for SysWOW64 if you are cataloging both copies.

File Explorer method

  1. Open C:\Windows\System32 in File Explorer.
  2. Right-click amsi.dll → Properties.
  3. Open the Digital Signatures tab.
  4. Select the signature → Details.
  5. Note signer name, timestamp, and thumbprint if shown.

Record

Check System32 SysWOW64
Status
Signer (CN=...)
Signature timestamp

Interpretation guide

Status Meaning Next step
Valid Signature verified at inspection time Continue — expected for stock amsi.dll (confirmed on lab .252: CN=Microsoft Windows)
NotSigned No embedded Authenticode signature Unusual for inbox amsi.dll; verify image source and update history
HashMismatch File changed after signing Treat as high-priority; compare hash to known-good on same build; involve IR if production
UnknownError Validation could not complete Retry; check system time, corp trust stores, and disk health
Valid signature ≠ "safe to run blindly"

Signature proves publisher identity and integrity at signing time, not that every export is harmless. You are still doing read-only structural analysis.


Step 3 — Check which processes load it

0. Purpose

See who is using amsi.dll right now. This connects the file on disk to runtime behavior.

1. High level (explain like I'm five)

Some programs borrow the spell-checker tool while they work. You walk around the computer asking, "Who has amsi.dll in their hands?"

Seeing it in a process is often normal, not scary by itself.

2. Deep breakdown

Process Explorer workflow

  1. Download and run Process Explorer from Sysinternals.
  2. Run as administrator only if your policy allows it (helps see more processes; not always required).
  3. Press Ctrl+F (Find Handle or DLL).
  4. Search: amsi.dll
  5. Double-click a match to jump to that process.
  6. Open the lower pane: View → Lower Pane View → DLLs (if not already showing).
  7. Select amsi.dll in the module list and read: path, company/publisher, version.

What to record (per match)

Process name PID DLL path loaded Publisher Notes
powershell.exe 1234 C:\Windows\System32\amsi.dll Microsoft Corporation example
...

Expected loaders (examples — your list will vary)

What is not a conclusion

Observation Do not conclude
amsi.dll loaded in PowerShell "Malware is present"
Multiple processes load it "DLL is hijacked"
No matches at idle "AMSI is disabled" (maybe nothing scriptable is running)

Optional: make it load for practice

In a lab VM only, start a new PowerShell window and run a benign command:

'hello' | Out-Null

Search again in Process Explorer. You are proving the observation method, not attacking anything.

Process Monitor (optional extension)

If you want to see load events over time:

  1. Start Procmon as admin.
  2. Filter: Path contains amsi.dll AND Operation is Load Image.
  3. Start a new PowerShell instance.
  4. Confirm a Load Image event appears.

Stop capture when done — Procmon fills disks quickly if left running.


Step 4 — Inspect the DLL structure without running it

0. Purpose

Read the DLL's blueprint on disk: CPU architecture, sections, imported APIs, exported functions, resources, and certificate directory — without executing the file.

1. High level (explain like I'm five)

A DLL is a labeled filing cabinet. You open the cabinet, read the folder tabs, see which other cabinets it borrows tools from, and list which tools it shares — but you never press the "start machine" button.

2. Deep breakdown

Golden rule

Open a copy in PE tools when the tool imports files. In Explorer:

Copy-Item "$env:windir\System32\amsi.dll" -Destination "$env:USERPROFILE\Desktop\amsi-copy.dll"

Analyze amsi-copy.dll on the Desktop. Do not rename the system original.

Tool choice

Tool Best for
PE-bear Fast PE tree navigation, sections, imports/exports
CFF Explorer Deep PE header editing view (use read-only here)
Dependencies "What DLLs does this need?" dependency graph

Review order (same in any PE viewer)

1. Headers
Field What it tells you
Machine / architecture AMD64 vs I386 — must match the path you copied
Timestamp Build/link time (hint only; not cryptographically trustworthy)
Image base Preferred load address in memory
Subsystem WINDOWS_GUI / WINDOWS_CUI — how loader treats it
2. Sections
Section Typical role
.text Executable code
.rdata Read-only constants (strings, vtables)
.data Writable globals
.pdata / .reloc Exception handling / relocation fixups

Note virtual size vs raw size — large discrepancies can be normal; huge empty gaps elsewhere might be worth a second look in malware exercises (less common for inbox Microsoft DLLs).

3. Imports

List which Windows APIs amsi.dll calls and from which DLLs (e.g., kernel32.dll, ntdll.dll, ole32.dll).

Ask: "What facilities does this component need?" — memory, COM, registry, RPC, etc.

4. Exports

List functions this DLL offers to other programs. For AMSI, Microsoft documents eight exports in Amsi.h:

Export Role (from Microsoft Learn)
AmsiInitialize Initialize the AMSI API
AmsiUninitialize Tear down the AMSI instance
AmsiOpenSession Open a correlated scan session
AmsiCloseSession Close a session
AmsiScanBuffer Scan a memory buffer
AmsiScanString Scan a string
AmsiNotifyOperation Notify the antimalware provider of an operation
AmsiResultIsMalware Interpret scan result (documented as a macro in the TOC)
Fact-check

Many blog posts list only six exports and omit AmsiNotifyOperation and AmsiResultIsMalware. Your export table should match Microsoft's function list, not a shortened cheat sheet.

Record the export names and ordinal list. You will revisit these in Ghidra.

5. Resources

Check version info (VS_VERSION_INFO) — should correlate with Step 1 VersionInfo.

Manifest resources may describe activation context or compatibility flags.

6. Security directory

Shows Authenticode-related metadata locations. Correlate with Step 2 — the PE security directory is how signing hooks into the file format.

dumpbin export listing (optional)

If Visual Studio Build Tools are installed, open x64 Native Tools Command Prompt and run:

dumpbin /exports C:\Windows\System32\amsi.dll

This reads metadata only; it does not modify the DLL.

Capture: screenshot or paste the export table into your notebook.

For PE background, see Portable Executable Structure.


Step 5 — Explore it in Ghidra

0. Purpose

Turn static exports into understandable functions: signatures, cross-references, strings, imported APIs, and decompiler approximations — still without patching the binary.

1. High level (explain like I'm five)

Ghidra is a super-powered decoder ring for machine language. You tell it which file to study, it draws maps of the functions, and you label things in your notebook project — not on the real DLL.

The decoder ring guesses. You verify guesses with clues (strings, API names, docs).

2. Deep breakdown

Prepare the file

Use the same desktop copy: amsi-copy.dll. Do not import directly from System32 if your workflow can avoid it.

Create a Ghidra project

  1. Launch Ghidra.
  2. File → New Project → Non-Shared Project.
  3. Name it amsi-inspection-lab (or similar) and pick a folder under your user profile.
  4. File → Import File → select amsi-copy.dll.
  5. Accept default format detection (Portable Executable (PE)).
  6. When asked to analyze, click Yes and accept default analyzers (PE, function ID, decompiler propagation, etc.).
  7. Wait until analysis finishes (progress bottom-right).

Open the program

Double-click amsi-copy.dll in the project window. Ghidra opens the CodeBrowser.

Find exports

  1. Open Window → Symbol Tree (if not visible).
  2. Expand Exports.
  3. You should see symbols such as AmsiScanBuffer, AmsiInitialize, etc.

If names are missing (rare for Microsoft DLLs), check Exports view under Window → Defined Strings / Symbol Table and compare to Step 4 export list.

Pick a first function

Start with AmsiInitialize or AmsiScanBuffer — well-documented entry points.

Click the function name → Ghidra jumps to disassembly. Open the decompiler: Window → Decompile (or the dragon icon).

What to examine (checklist per function)

Artifact Why it matters
Function signature Return type and parameters (often inferred)
Callers (References → Show References to) Who uses this export inside the DLL
Callees Which internal helpers and Win APIs it uses
Strings window Error messages, registry paths, logging clues
Imports External dependencies (AmsiScanBuffer will touch scanning pipelines)
Control flow Branches for error handling vs success paths

Document in Ghidra, not in the binary

Decompiler hygiene

Remember Because
Decompiler output is an approximation Optimizations and metadata loss confuse types
Names like FUN_180001234 are placeholders Rename only in the project
Microsoft docs beat guesses Cross-check exports against AMSI API documentation
AMSI is vendor-agnostic Microsoft: any registered antimalware provider can integrate — not Defender-only

Minimal first-session exercise

  1. Export list: write all Amsi* exports.
  2. For AmsiScanBuffer: note parameter count guess and whether it calls the same internal helper repeatedly.
  3. Find at least one error string near failure branches.
  4. Find one imported API you recognize (e.g., memory allocation or synchronization).

Stop after 30–45 minutes. Part 2 will extend this into cross-reference tracing and comparison workflows.


Step 6 — Learn the minimum x64 assembly vocabulary

0. Purpose

Give you enough reading glasses to follow Ghidra's disassembly pane without becoming a full-time assembly developer.

1. High level (explain like I'm five)

The CPU reads a recipe one line at a time. Some lines call helpers, some compare numbers, some jump to a different step. Registers are scratch pads holding numbers that are often addresses (where something lives in memory), not always the final answer themselves.

2. Deep breakdown

Core instructions

Instruction Plain meaning Tiny example mental model
call "Go run that function, then come back" Calling AmsiInitialize
cmp / test "Compare these values; set flags for a branch" test rax, rax → "is RAX zero?"
je, jne, ja, ... "Jump if the last comparison said ..." jne error_path → branch on not-equal
mov Copy bits between register/memory mov rcx, rdx
ret Return from current function End of export stub

Registers (Windows x64 calling convention — first pass)

Register Role in many calls
RCX 1st integer/pointer argument
RDX 2nd argument
R8 3rd argument
R9 4th argument
RAX Return value (many functions)
RSP Stack pointer — where the stack lives
RBP Optional frame pointer in some functions

Additional arguments may spill to the stack. Ghidra often annotates them in the decompiler view.

Pattern recognition drill (in Ghidra)

Open AmsiScanBuffer disassembly and try to spot:

  1. mov rcx, ... / mov rdx, ... near the top — likely setting up arguments.
  2. A call to an internal function or imported API.
  3. test eax, eax or cmp followed by je/jne — success vs failure split.
  4. ret at the end of the function.

Registers hold addresses more often than "numbers"

If you see mov rax, qword ptr [rcx], read it as: "Load the 8-byte value at the memory address stored in RCX into RAX" — not "RCX equals that value."

Study method (10 minutes/day)

Day Focus
1 Identify call and ret in one export
2 Circle rcx/rdx/r8/r9 setup before a call
3 Match one je/jne pair to decompiler if
4 Open Microsoft docs for the same export name side-by-side

Further reading (vault)


What to record in your lab notebook

By the end of Part 1, you should have:


← Windows Playbook · DLL target selection · Part 1 · Part 2 (coming) →

Related: PE structure · Attack AMSI