Search code examples
windbgwindows-kernelwindows-driver

driver handling \Device\


In windows there are device like \Device\ that could be found using Winobj from Sysinternals. How can we find out which kernel side driver is handling operations for that device?

Im sorry for not being able to ask my question in more clear way.

I googled but wasn't able to get far.


Solution

  • First you can get a list of devices by interrogating the \device directory of the object manager:

    0: kd> !object \Device
    Object: ffffe48ed7a9ab90  Type: (ffff9b89548e1380) Directory
        ObjectHeader: ffffe48ed7a9ab60 (new version)
        HandleCount: 2 PointerCount: 66188
        Directory Object: ffffe48ed7a56e00  Name: Device
    
        Hash Address          Type                      Name
        ---- -------          ----                      ----
         00  ffff9b896bf89e00 Device                    000000ed
             ffff9b8965a4ae00 Device                    000000c7
             ffff9b8967b7cd40 Device                    000000b3
             ffff9b8965c9ca70 Device                    UMDFCtrlDev-624c4811-0bbc-11ee-a47f-107b441961bb
             ffff9b895e77c630 Device                    0000007e
             ...
             ffff9b8954edadf0 Device                    CNG
    

    I'm going to go with CNG, since you should have this one too (it's the Windows "Crypto Next Generation" driver).

    0: kd> !devobj ffff9b8954edadf0
    Device object (ffff9b8954edadf0) is for:
     CNG \Driver\CNG DriverObject ffff9b8954ee0e30
     ...
    

    The driver is \Driver\CNG and its object (_DRIVER_OBJECT) is at ffff9b8954ee0e30:

    0: kd> dt _driver_object ffff9b8954ee0e30
    nt!_DRIVER_OBJECT
       +0x000 Type             : 0n4
       +0x002 Size             : 0n336
       +0x008 DeviceObject     : 0xffff9b89`54edadf0 _DEVICE_OBJECT
       +0x010 Flags            : 0x12
       +0x018 DriverStart      : 0xfffff804`2e710000 Void
       +0x020 DriverSize       : 0xbb000
       +0x028 DriverSection    : 0xffff9b89`54843c50 Void
       +0x030 DriverExtension  : 0xffff9b89`54ee0f80 _DRIVER_EXTENSION
       +0x038 DriverName       : _UNICODE_STRING "\Driver\CNG"
       +0x048 HardwareDatabase : 0xfffff804`2bb2e990 _UNICODE_STRING "\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM"
       +0x050 FastIoDispatch   : (null)
       +0x058 DriverInit       : 0xfffff804`2e7c3010     long  cng!GsDriverEntry+0
       +0x060 DriverStartIo    : (null)
       +0x068 DriverUnload     : (null)
       +0x070 MajorFunction    : [28] 0xfffff804`2e717900     long  cng!CngDispatch+0
    

    Since you have the base address of the module (it's the DriverStart field) you can just lm it to get the module path:

    0: kd> lmDkif a 0xfffff804`2e710000
    Browse full module list
    start             end                 module name
    fffff804`2e710000 fffff804`2e7cb000   cng      \SystemRoot\System32\drivers\cng.sys
    

    The interesting option here is f:

    Displays the full image path. (This path always matches the path that is displayed in the initial load notification, unless you issued a .reload -s command.) When you use f, symbol type information is not displayed.

    So, \Device\CNG is handled by %SYSTEMROOT%\System32\drivers\cng.sys.

    Another (undocumented) trick is to cast the DriverSection field (which is just a void* in the symbols) to a _LDR_DATA_TABLE_ENTRY. This field is actually not really a loader data table entry (which works for user modules, but not exactly for kernel ones; the real structure is not in the symbols). The first few fields in the output are correct though:

    0: kd> dt _ldr_data_table_entry 0xffff9b89`54843c50
    nt!_LDR_DATA_TABLE_ENTRY
       +0x000 InLoadOrderLinks : _LIST_ENTRY [ 0xffff9b89`54843e10 - 0xffff9b89`54881dc0 ]
       +0x010 InMemoryOrderLinks : _LIST_ENTRY [ 0xfffff804`2e7bb000 - 0x00000000`00004b0c ]
       +0x020 InInitializationOrderLinks : _LIST_ENTRY [ 0x00000000`00000000 - 0x00000000`00000000 ]
       +0x030 DllBase          : 0xfffff804`2e710000 Void
       +0x038 EntryPoint       : 0xfffff804`2e7c3010 Void
       +0x040 SizeOfImage      : 0xbb000
       +0x048 FullDllName      : _UNICODE_STRING "\SystemRoot\System32\drivers\cng.sys"
       +0x058 BaseDllName      : _UNICODE_STRING "cng.sys"
       ...
       ... !!! remainder of the fields are wrong !!!
       ...
    

    Edit

    Same with \device\tcp:

    2: kd> !object \device\tcp
    Object: ffffa88cb3c98c00  Type: (ffffa88cb32b4d20) Device
        ObjectHeader: ffffa88cb3c98bd0 (new version)
        HandleCount: 0  PointerCount: 4
        Directory Object: ffff9581e383ad80  Name: Tcp
    
    2: kd> !devobj ffffa88cb3c98c00
    Device object (ffffa88cb3c98c00) is for:
     Tcp \Driver\tdx DriverObject ffffa88cb3f61e00
    Current Irp 00000000 RefCount 85 Type 00000012 Flags 00000050
    SecurityDescriptor ffff9581e3c17e60 DevExt ffffa88cb3c98d50 DevObjExt ffffa88cb3c98d58 
    ExtensionFlags (0x00000800)  DOE_DEFAULT_SD_PRESENT
    Characteristics (0x00000100)  FILE_DEVICE_SECURE_OPEN
    Device queue is not busy.
    

    Asking for more information by using the 7 (1 | 2 | 4) flag concerning the driver object:

    2: kd> !drvobj \Driver\tdx 7
    Driver object (ffffa88cb3f61e00) is for:
     \Driver\tdx
    
    Driver Extension List: (id , addr)
    
    Device Object list:
    ffffa88cb3c5cc00  ffffa88cb3c64c00  ffffa88cb3c69c00  ffffa88cb3c73c00
    ffffa88cb3c76c00  ffffa88cb3c98c00  ffffa88cb3c9bc00  
    
    DriverEntry:   fffff8052c5ce010 
    DriverStartIo: 00000000 
    DriverUnload:  fffff8052c5c3870 
    AddDevice:     00000000 
    
    Dispatch routines:
    [00] IRP_MJ_CREATE                      fffff8052c5c2f30    +0xfffff8052c5c2f30
    [01] IRP_MJ_CREATE_NAMED_PIPE           fffff80526744b60    nt!IopInvalidDeviceRequest
    [02] IRP_MJ_CLOSE                       fffff8052c5c2e90    +0xfffff8052c5c2e90
    [03] IRP_MJ_READ                        fffff80526744b60    nt!IopInvalidDeviceRequest
    [04] IRP_MJ_WRITE                       fffff80526744b60    nt!IopInvalidDeviceRequest
    [05] IRP_MJ_QUERY_INFORMATION           fffff80526744b60    nt!IopInvalidDeviceRequest
    [06] IRP_MJ_SET_INFORMATION             fffff80526744b60    nt!IopInvalidDeviceRequest
    [07] IRP_MJ_QUERY_EA                    fffff80526744b60    nt!IopInvalidDeviceRequest
    [08] IRP_MJ_SET_EA                      fffff80526744b60    nt!IopInvalidDeviceRequest
    [09] IRP_MJ_FLUSH_BUFFERS               fffff80526744b60    nt!IopInvalidDeviceRequest
    [0a] IRP_MJ_QUERY_VOLUME_INFORMATION    fffff80526744b60    nt!IopInvalidDeviceRequest
    [0b] IRP_MJ_SET_VOLUME_INFORMATION      fffff80526744b60    nt!IopInvalidDeviceRequest
    [0c] IRP_MJ_DIRECTORY_CONTROL           fffff80526744b60    nt!IopInvalidDeviceRequest
    [0d] IRP_MJ_FILE_SYSTEM_CONTROL         fffff80526744b60    nt!IopInvalidDeviceRequest
    [0e] IRP_MJ_DEVICE_CONTROL              fffff8052c5c3220    +0xfffff8052c5c3220
    [0f] IRP_MJ_INTERNAL_DEVICE_CONTROL     fffff8052c5b1010    +0xfffff8052c5b1010
    [10] IRP_MJ_SHUTDOWN                    fffff80526744b60    nt!IopInvalidDeviceRequest
    [11] IRP_MJ_LOCK_CONTROL                fffff80526744b60    nt!IopInvalidDeviceRequest
    [12] IRP_MJ_CLEANUP                     fffff8052c5c2e00    +0xfffff8052c5c2e00
    [13] IRP_MJ_CREATE_MAILSLOT             fffff80526744b60    nt!IopInvalidDeviceRequest
    [14] IRP_MJ_QUERY_SECURITY              fffff80526744b60    nt!IopInvalidDeviceRequest
    [15] IRP_MJ_SET_SECURITY                fffff80526744b60    nt!IopInvalidDeviceRequest
    [16] IRP_MJ_POWER                       fffff80526744b60    nt!IopInvalidDeviceRequest
    [17] IRP_MJ_SYSTEM_CONTROL              fffff8052c5c3640    +0xfffff8052c5c3640
    [18] IRP_MJ_DEVICE_CHANGE               fffff80526744b60    nt!IopInvalidDeviceRequest
    [19] IRP_MJ_QUERY_QUOTA                 fffff80526744b60    nt!IopInvalidDeviceRequest
    [1a] IRP_MJ_SET_QUOTA                   fffff80526744b60    nt!IopInvalidDeviceRequest
    [1b] IRP_MJ_PNP                         fffff80526744b60    nt!IopInvalidDeviceRequest
    

    Technically, you can just ask any address in the module using lm, so rather than the DriverStart I'll be using one of the adresses in the module (its DriverEntry; but one of the IRP handler would do it too, at least if it's in the module, not in nt or elsewhere).

    2: kd> lm a fffff8052c5ce010    
    Browse full module list
    start             end                 module name
    fffff805`2c5b0000 fffff805`2c5d2000   tdx        (pdb symbols)          g:\symbols\tdx.pdb\89E0FDAAC67460365A3A443A924463EE1\tdx.pdb
    

    You'll need symbolic information for that though, see .reload /f /n (doc).