Special Command—Use lm* and Get All Details from Modules

Yet another basic and useful command: lm.

Hmmmmm… OK so you already know this command. Great! But do you know all of its variations?

Usually when we get used to a command we don’t try to explore its variations and sometimes one of these variations may give you the information you’re looking for!

Let’s start getting all the basic information from all modules with lm.

This command shows several columns or fields, each with a different title. Some of these titles have specific meanings:

  • module name is typically the file name without the file name extension. In some cases, the module name differs significantly from the file name.
  • The symbol type immediately follows the module name. This column is not labeled. If you have loaded symbols, the symbol file name follows this column.
  • The first address in the module is shown as start. The first address after the end of the module is shown as end. For example, if start is "faab4000" and end is "faab8000", the module extends from 0xFAAB4000 to 0xFAAB7FFF, inclusive.

lm

Displaying all modules:

 

lmo

Displaying only the loaded modules:

 

lmv

Displaying details for all modules:

 

lmv m <moduleName>

Displaying details for a specific module:

 

Tip: Use it whenever you see an offset from the call stack that doesn’t look normal.

The stack below was manually crafted, just to use as an example:

 

053ffd4c 7731b071 ntdll!KiFastSystemCallRet
053ffd74 004153e7 ntdll!RtlPcToFileHeader+0x45

053ffe38 0041528c mtgdi!CGDIThread+0xed900
053ffe90 5796d973 mtgdi!CRectThread+0xed973
053fff58 6aacdfd3 mfc90d+0x3c
053fff94 6aacdf69 MSVCR90D!beginthreadex+0x1F
053fffa0 76e63833 MSVCR90D!beginthreadex+0x1a
053fffac 7731a9bd kernel32!BaseThreadInitThunk+3b
053fffec 00000000 ntdll!LdrInitializeThunk

Whenever you see a long offset, like above, it means you have no symbols or there's a problem and the symbols don't match, so you cannot trust on the names of the method calls! Usually when you don't have symbols is because it's a third-party component, so you lmv m to get information like version, company name and more.

 

lme

Displays only modules that have a symbol problem. These symbols include modules that have no symbols and modules whose symbol status is C, T, # , M, or Export:

lm1m

Do you want to use the lm output in a .foreach loop? I’ve done this in a few of my scripts. To accomplish this, you should use lm1m to get just the module names:

Displaying modules based on a pattern:

lm m <pattern>

This is hot! Have you already wondered if it’s possible to get a module from a memory address or that starts with a specific letter? Yes, it is! Here’s the usage. I'm getting all modules that start with the letter "m":

 

lm a <address>

 

This is even cooler! I'm using an address to get the module:

 

 

 

Finally, this is my bonus for you: An lm variation using DML. You can click on the hyperlinks and get more information, including functions and data. Fantastic!

lmD

Here you can see scripts that use lm*.