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*.


Comments (3)

  1. Marc Sherman says:

    Hi,

    Could you elaborate on the following:

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

    I’m not sure what you mean since call stack addresses don’t reside within a module.

    thanks,

    Marc

  2. Marc, thanks for this observation. I changed the text based on your feedback.