Archive for January, 2012

Why is lmv sometimes more verbose?

Saturday, January 28th, 2012

While working in WinDBG, lm is the standard command for viewing the loaded module list of the target. Amongst other things, this command takes a v flag to increase the verbosity as well as an m flag to match a particular module. Thus, if you want to see verbose information for a module named foo you can execute the following command:

lmv mfoo

That’s all fine and good, but you might notice that some modules provide more information than others. For example, check out the detailed information provided for the NTFS module:

1: kd> lmv mntfs
start             end                 module name
fffff880`01250000 fffff880`013f3000   Ntfs       (deferred)
    Image path: \SystemRoot\System32\Drivers\Ntfs.sys
    Image name: Ntfs.sys
    Timestamp:        Mon Jul 13 19:20:47 2009 (4A5BC14F)
    CheckSum:         00195F88
    ImageSize:        001A3000
    File version:     6.1.7600.16385
    Product version:  6.1.7600.16385
    File flags:       0 (Mask 3F)
    File OS:          40004 NT Win32
    File type:        3.7 Driver
    File date:        00000000.00000000
    Translations:     0409.04b0
    CompanyName:      Microsoft Corporation
    ProductName:      Microsoft® Windows® Operating System
    InternalName:     ntfs.sys
    OriginalFilename: ntfs.sys
    ProductVersion:   6.1.7600.16385
    FileVersion:      6.1.7600.16385 (win7_rtm.090713-1255)
    FileDescription:  NT File System Driver
    LegalCopyright:   © Microsoft Corporation. All rights reserved.

Versus the limited information we get for the FltMgr module:

1: kd> lmv mfltmgr
start             end                 module name
fffff880`010fa000 fffff880`01146000   fltmgr     (deferred)
    Image path: \SystemRoot\system32\drivers\fltmgr.sys
    Image name: fltmgr.sys
    Timestamp:        Mon Jul 13 19:19:59 2009 (4A5BC11F)
    CheckSum:         00056413
    ImageSize:        0004C000
    Translations:     0000.04b0 0000.04e4 0409.04b0 0409.04e4

What’s up with that?

The answer is the availability of resource information. The PE file format allows for a .rsrc section, which contains developer provided information about the binary (company, version, description, etc.). The information placed here comes from a .rc file supplied when the image is compiled and is usually accessed via the Details tab of the file properties:

If an image contains a resident and valid .rsrc section, lmv will provide the details from it as part of its output. If we dump the PE header for the NTFS module, we can see that it does indeed have a .rsrc section:

1: kd> !dh ntfs
File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
    8664 machine (X64)
       8 number of sections
4A5BC14F time date stamp Mon Jul 13 19:20:47 2009
...
SECTION HEADER #7
   .rsrc name
   1CFF0 virtual size
  185000 virtual address
   1D000 size of raw data
  176600 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
40000040 flags
         Initialized Data
         (no align specified)
         Read Only

Which explains why we saw all of that detailed info for NTFS. But why didn’t we see it for FltMgr? In fact, if we check out the file properties for FltMgr.sys we see that it does indeed have a valid resource section:

But lmv was unable to parse it for some reason. Let’s check out the PE header to find out why:

1: kd> !dh fltmgr
File Type: DLL
FILE HEADER VALUES
    8664 machine (X64)
       B number of sections
4A5BC11F time date stamp Mon Jul 13 19:19:59 2009
...
SECTION HEADER #A
   .rsrc name
    1E50 virtual size
   49000 virtual address
    2000 size of raw data
   42E00 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
42000040 flags
         Initialized Data
         Discardable
         (no align specified)
         Read Only

Aha! The .rsrc section is marked as discardable, meaning the the image loader is free to remove this section from memory when the module is loaded. Thus, while this module has a valid .rsrc section on disk, it is not guaranteed to have one in memory.

Discardable is the default used by the compiler/linker for resource sections because the information is typically only used in file property dialogs, where it can easily be retrieved from the image on disk. However, certain Microsoft supplied modules (such as NTFS) go out of their way to mark their resource sections as non-discardable to make it possibly to query version information from the debugger at the cost of some extra RAM.

Scanning for Control Areas (!ca and !memusage)

Tuesday, January 3rd, 2012

Control areas are an important data structure in Windows in that they track the state of memory mapped files. From this state you can find out things like the name of the file that is memory mapped, the location of the data in memory, etc.

Control areas are created not only for files that are memory mapped for data and executable access, but even for files being accessed via cached I/O (internally the Cache Manager memory maps these files), “special” files such as the MFT (the file systems effectively perform cached I/O on these files), and memory mapped sections that are backed by the paging file. As you can imagine, these data structures can be useful when analyzing a memory dump for lots of different reasons. So, how do you go about finding control areas to play with?

Turns out, there are two different methods provided by WinDBG for quickly scanning a target for control areas. Note that control areas can also be found indirectly through file objects, but that’s a separate technique that we’re not covering here. 

The first is the !ca command, which is normally used to display a control area that you already have the address of:

0: kd> !ca fffffa8003c2c770
ControlArea  @ fffffa8003c2c770
  Segment      fffff8a00f39d190  Flink      fffffa8003c2c3f8
  Section Ref                 0  Pfn Ref                   1
  User Ref                    0  WaitForDel                0
  File Object  fffffa800593dc40  ModWriteCount             0
  WritableRefs                0
  Flags (4080) File Accessed     
File: \Program Files\Debugging Tools for Windows (x64)\windbg.exe
Segment @ fffff8a00f39d190
  ControlArea     fffffa8003c2c770  ExtendInfo    0000000000000000
  Total Ptes                    9d
  Segment Size               9cd10  Committed                    0
  Flags (c0000) ProtectionMask
Subsection 1 @ fffffa8003c2c7f0
  ControlArea  fffffa8003c2c770  Starting Sector        0
  Base Pte     fffff8a00a3e2820  Ptes In Subsect       9d
  Flags                d100000d  Sector Offset        d10
  Accessed
  Flink        fffffa8003c2c4c0  Blink   fffffa8006a1cae0

For information about how to use the above output to retrieve the contents of the file, refer to my previous article found here.

However, !ca also has another interesting usage. If instead of a valid control area address you specify 0, you’ll be greeted to a list of all the control areas the command can find. It doesn’t do this via any sort of elegant method, instead what it does is search the various executive pools for allocations with the appropriate pool tags:

0: kd> !ca 0
Scanning large pool allocation table for Tag: MmCa (fffffa80072df000 : fffffa80075df000)
fffffa8005115bd0 0       File: \$Directory
fffffa80057a7450 1       Pagefile-backed section
...
Searching NonPaged pool (fffffa8003901000 : ffffffe000000000) for Tag: MmCa
fffffa80039cbd40 0       File: \WinDDK\7600.16385.1\inc\api\SpecStrings_strict.h
fffffa800396c250 0       File: \Windows\Fonts\couri.ttf
fffffa8007738640 0       File: \Windows\SysWOW64\davhlpr.dll
...
Scanning large pool allocation table for Tag: MmCi (fffffa80072df000 : fffffa80075df000)
fffffa80051596c0 0       Image: \Windows\SysWOW64\WMASF.DLL
fffffa8003e51260 0       Image: \Windows\SysWOW64\thumbcache.dll
fffffa8003e575f0 0       Image: \Windows\SysWOW64\netshell.dll
fffffa80061f5b50 0       Image: \Windows\System32\samlib.dll
fffffa80067125d0 0       Image: \Windows\System32\atiu9p64.dll
fffffa8006e34610 0       Image: \Windows\System32\WUDFx.dll
fffffa80056d1df0 0       Image: \Windows\System32\iertutil.dll
fffffa80056f49c0 0       Image: \Windows\System32\urlmon.dll
...
Searching NonPaged pool (fffffa8003901000 : ffffffe000000000) for Tag: MmCi
fffffa8003aace30 0       Image: \Windows\System32\dmocx.dll
fffffa8003ae5750 0       Image: \WinDDK\7600.16385.1\bin\x86\rc.exe
fffffa8006dff160 0       Image: \Windows\System32\mapi32.dll
fffffa8006dff460 0       Image: \Windows\SysWOW64\mfplat.dll
fffffa8006e169a0 0       Image: \Windows\SysWOW64\d3d8thk.dll
fffffa8006e2b5a0 0       Image: \Windows\SysWOW64\atiumdva.dll
...

From here, you can start running !ca on whatever control areas you might find interesting (the control area address is the address in the first column of the output). Note that files may in fact have two control areas, one for data access as well as one for image access.

The other way of finding control areas is by using the !memusage command (this is, in fact, the method documented in the Windows Internals book). This method is different in that instead of searching for pool tags, the !memusage command actually scans the PFN database and uses the data from the entries to find control areas. This is a much more complex procedure that we’ll have to save for another time :)