Volatility Plugins — Plugin windows.ldrmodules Let’s Talk About it
- 2 hours ago
- 4 min read

This plugin is honestly one of the best examples of why Volatility still matters in memory forensics.
Why?
Because instead of trusting a single data source, ldrmodules does something very smart —it cross-checks multiple memory structures and looks for inconsistencies.
And malware absolutely hates consistency.
What ldrmodules Is Actually Doing
When we’re looking for suspiciously loaded code inside a process, there isn’t just one place to look.
Windows tracks loaded DLLs in multiple ways, and ldrmodules compares all of them.
Every process has a Process Environment Block (PEB).Inside the PEB, Windows maintains three linked lists that track loaded DLLs:
InLoadOrderModule
InInitializationOrderModule
InMemoryOrderModule

In a normal process, all three lists usually contain the same DLLs, just ordered differently.
Now here’s where it gets interesting.
ldrmodules doesn’t stop there. It also looks at the VAD tree, which tracks image-mapped memory pages — basically what is actually mapped into memory.
So now we can ask a very powerful question:
Does what Windows thinks is loaded match what is actually mapped in memory?
When the answer is “no” — that’s where malware shows up.
What Information ldrmodules Gives Us
For each process, the plugin shows:
PID – Process ID
Process – Process name
Base – Base address from the VAD tree
InLoad – Present in PEB InLoad list
InInit – Present in PEB InInitialization list
InMem – Present in PEB InMemory list
MappedPath – File path from disk (from the VAD)
A legitimate DLL should:
be marked True in all PEB lists
have a valid MappedPath on disk
Example Look:

Anything that breaks this pattern deserves attention.
Important: False Positives Are Normal
Before you panic over every “False”, keep these in mind:
Process executable
The process binary itself (like lsass.exe) will always show False in InInit. This is expected and normal.
Special files
Files like:
.mui
.fon
.winmd
.msstyles
are mapped into memory but are not real DLLs, so they won’t appear in PEB lists.
Legit DLLs not yet loaded
Sometimes DLLs are mapped but not actually used yet — they’ll show in VAD but not in PEB.
SysWOW64 weirdness
Volatility 3 sometimes marks SysWOW64 DLLs as FALSE.
This is likely due to 32-bit tracking differences.
That’s why I always run ldrmodules in both Volatility 2 and 3 when possible.
The Biggest Red Flag: Empty MappedPath
This is huge — so don’t miss it.
If a DLL has no MappedPath:
it was not loaded from disk
it was not loaded via LoadLibrary
Windows has no idea where it came from

That almost always means DLL injection.
Even if the DLL still appears in one or more PEB lists.
How Malware Hides DLLs: PEB Unlinking
Because the PEB lives in userland, malware doesn’t need kernel access to mess with it. Administrator rights are enough.
A common trick is unlinking a DLL from one or more PEB lists:
Process keeps running normally
DLL stays in memory
Tools like Task Manager and dlllist don’t see it
From the outside, it looks clean.
But…
The VAD tree still knows the truth.
So when ldrmodules finds:
memory-mapped executable code
that is missing from PEB lists
…it becomes very obvious something is wrong.
How ldrmodules Thinks
Instead of trusting the PEB, ldrmodules does this:
Walk the VAD tree
Find image-mapped executable memory
Compare each entry with:
InLoad
InInit
InMem
Show mismatches as True / False
This gives you a visual way to spot:
unlinked DLLs
injected memory
reflective loaders
process hollowing
Normal Example (What “Good” Looks Like)
A clean entry from wininit.exe might show:
DLL: \Windows\System32\iertutil.dll
InLoad = True
InInit = True
InMem = True
MappedPath = present
This is exactly what we expect.

Zeus Banking Trojan Example
Now let’s look at malware.
Zeus injects itself into almost every running process.
In ldrmodules, we see an entry with:
InLoad = False
InInit = False
InMem = False
MappedPath = empty

This tells us:
code exists in memory
Windows loader never loaded it
VAD has executable memory
no backing file on disk
Classic injected code.
Process Executable Entry — Don’t Get Confused
You’ll often see the first entry representing the process itself:
\WINDOWS\system32\svchost.exeIt will:
be present in InLoad and InMem
show False in InInit

This is normal and expected.
Stuxnet & Process Hollowing
Stuxnet takes things further using process hollowing.
In an lsass.exe , ldrmodules shows:
entries with no MappedPath
missing from multiple PEB lists
One section:
not in any list → injected DLL
Another section:
missing only from InInit → looks normal
BUT still has no MappedPath
This is the key clue.
The original lsass.exe image was unmapped and replaced entirely in memory.
Since this all happened in RAM:
no file on disk
no mapped path
nothing for AV to scan
Exactly how hollowing is supposed to work.
Cross-Checking With malfind
If you compare:
Base address from ldrmodules
Base address reported by malfind
You’ll see both tools pointing to the same suspicious memory regions.
Two tools.
Two data sources.
Same conclusion.
That’s confidence.
Advanced Trick: ldrmodules vs dlllist
One last powerful trick:
dlllist → reads PEB (easy to manipulate)
ldrmodules → reads VAD (kernel-side, harder to fake)
If base addresses don’t match between the two? That’s a strong indicator of process hollowing.
Final Thought
Attackers can:
unlink DLLs
avoid LoadLibrary
never touch disk
hollow processes
But they can’t escape memory structures entirely.
As long as:
code must execute
memory must be executable
Plugins like ldrmodules will always give you something to pull on.
--------------------------------------------------------Dean-----------------------------------
