테스트 환경 : windows 10 x64 build 19041

이 방식은 DRIVER_OBJECT -> OBJECT_HEADER_NAME_INFO ->  OBJECT_DIRECTORY -> OBJECT_DIRECTORY_ENTRY 순서대로 구조체를 얻어온 뒤 ENTRY 체인을 끊어 목록에서 제거하는 방식입니다.

이를 위해 먼저 최상위 OBJECT_DIRECTORY 부터 살펴봅니다.

lkd> !object ffffcb83e84023c0
Object: ffffcb83e84023c0  Type: (ffffdc8a4aa9c4e0) Directory
    ObjectHeader: ffffcb83e8402390 (new version)
    HandleCount: 0  PointerCount: 58
    Directory Object: 00000000  Name: \

    Hash Address          Type                      Name
    ---- -------          ----                      ----
     01  ffffdc8a4ccfe450 Mutant                    PendingRenameMutex
         ffffcb83e8451ad0 Directory                 ObjectTypes
     02  ffffdc8a4f6ec6e0 FilterConnectionPort      storqosfltport
     04  ffffdc8a55ba1c20 FilterConnectionPort      TsFltScanPort_V3LITE40
     05  ffffdc8a55ba1670 FilterConnectionPort      TsFltCheckPort_V3LITE40
         ffffcb83e84b6520 SymbolicLink              SystemRoot
     06  ffffcb83e8cfba20 Directory                 Sessions
     08  ffffcb83e848fb80 Directory                 ArcName
     09  ffffdc8a4f6ec9a0 FilterConnectionPort      WcifsPort
         ffffcb83e84ec060 Directory                 NLS
     10  ffffdc8a4fa27760 Event                     LanmanServerAnnounceEvent
         ffffdc8a4f86baa0 ALPC Port                 ThemeApiPort
         ffffdc8a4ce59d40 Device                    UdfsCdRom
         ffffcb83e8ba5380 Directory                 Windows
         ffffcb83e8467c50 Directory                 GLOBAL??
     11  ffffcb83e8cfb2a0 Directory                 RPC Control
         ffffdc8a4c3596a0 ALPC Port                 PdcPort
     13  ffffdc8a55b87400 FilterConnectionPort      MEDSRVPOSTPORT_V3LITE40_2.13.1.63
         ffffdc8a4cd7a4e0 Event                     EFSInitEvent
     14  ffffcb83e8c68930 SymbolicLink              Dfs
         ffffdc8a4c53c870 Device                    clfs
     15  ffffdc8a4c22dc90 Event                     CsrSbSyncEvent
         ffffdc8a4c62a790 ALPC Port                 SeRmCommandPort
     16  ffffcb83e8445830 SymbolicLink              DosDevices
     17  ffffdc8a55b92450 FilterConnectionPort      MEDSRVPENDINGPORT_V3LITE40_2.13.1.63
         ffffcb83e8cfbc00 Directory                 KnownDlls32
     18  ffffdc8a55b88fa0 FilterConnectionPort      MEDSRVSENDPORT_V3LITE40_2.13.1.63
         ffffcb83e849ad20 Key                       \REGISTRY
     19  ffffcb83e8836c00 Directory                 BaseNamedObjects
     20  ffffcb83e8ec49d0 Section                   Win32kCrossSessionGlobals
         ffffdc8a4ab13df0 ALPC Port                 PowerPort
     21  ffffdc8a4f412a10 ALPC Port                 SmSsWinStationApiPort
         ffffdc8a4c22b7b0 Event                     UniqueInteractiveSessionIdEvent
         ffffcb83e84ec920 Directory                 UMDFCommunicationPorts
     22  ffffcb83e8cfb840 Directory                 KnownDlls
         ffffdc8a4cc52d40 Device                    FatCdrom
         ffffdc8a4cc53d40 Device                    Fat
         ffffdc8a4ab46df0 ALPC Port                 PowerMonitorPort
     23  ffffdc8a4c626b50 Device                    Ntfs
         ffffcb83e84ec3e0 Directory                 FileSystem
         ffffcb83e8441cc0 Directory                 KernelObjects
     26  ffffdc8a4ebebd40 ALPC Port                 SeLsaCommandPort
         ffffcb83e8451ca0 Directory                 Callback
     28  ffffdc8a4f6ec580 FilterConnectionPort      BindFltPort
         ffffdc8a4c23dc30 Event                     DSYSDBG.Debug.Trace.Memory.2bc
         ffffcb83e84588d0 Directory                 Security
     29  ffffdc8a4ce31e00 Device                    UdfsDisk
     30  ffffcb83e8490060 Directory                 Device
     32  ffffcb83e84f8190 SymbolicLink              DriverData
     34  ffffcb83ebcfe610 Section                   LsaPerformance
         ffffdc8a4c8aec70 ALPC Port                 SmApiPort
     35  ffffdc8a4f6ec4d0 FilterConnectionPort      CLDMSGPORT
         ffffcb83e84b66d0 SymbolicLink              OSDataRoot
     36  ffffdc8a4c23e9f0 Event                     SAM_SERVICE_STARTED
         ffffcb83e84ec220 Directory                 Driver
         ffffcb83e8489820 Directory                 DriverStores

저의 windows의 windbg 화면으로, OBJECT_DIRECTORY 구조체는 타입과 이름을 가지고 있습니다. 최상위 구조체라서 타입은 HANDLE을 가지고 있습니다.

우리에게 필요한 것은 드라이버 목록인데, 이는 각각 23번, 36번 인덱스 2번째에 속해 있습니다. (FileSystem, Driver) 

일반적으로 드라이버를 로딩하면 Driver의 OBJECT_DIRECTORY에 연결되므로, 36번 인덱스의 Driver만 보도록 하겠습니다. 

위 주소를 다시 구조체로 표현해봅니다.

lkd> dt !_OBJECT_DIRECTORY  ffffcb83e84023c0
nt!_OBJECT_DIRECTORY
   +0x000 HashBuckets      : [37] (null) 
   +0x128 Lock             : _EX_PUSH_LOCK
   +0x130 DeviceMap        : (null) 
   +0x138 ShadowDirectory  : (null) 
   +0x140 NamespaceEntry   : (null) 
   +0x148 SessionObject    : (null) 
   +0x150 Flags            : 0
   +0x154 SessionId        : 0xffffffff

HashBucket은 37개의 배열로 구성되어 있으며, 각각 OBJECT_DIRECTORY_ENTRY로 표현됩니다. 각 OBJECT_DIRECTORY_ENTRY체인으로 연결되어 있습니다. 

운영체제는 각각의 Name에서 Hash Index 를 계산해 각 배열에 삽입하는 방식입니다. 따라서 연결된 Entry의 갯수는 일정하지 않습니다. 

보시면 00, 03번 인덱스는 존재하지 않고, 10번의 경우 5개의 오브젝트가 존재하는데 Name에서 동일한 Hash Index가 계산된 결과입니다. (Hash인덱스를 어떻게 구하는지는 모르겠습니다. 만약 알게되면 기술하도록 하겠습니다.)

HashBucket을 눌러보면 아래와 같이 나옵니다.

lkd> dx -id 0,0,ffffdc8a4aa96040 -r1 (*((ntkrnlmp!_OBJECT_DIRECTORY_ENTRY * (*)[37])0xffffcb83e84023c0))
(*((ntkrnlmp!_OBJECT_DIRECTORY_ENTRY * (*)[37])0xffffcb83e84023c0))                 [Type: _OBJECT_DIRECTORY_ENTRY * [37]]
    [0]              : 0x0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [1]              : 0xffffcb83e8ca8b10 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [2]              : 0xffffcb83ec36c2e0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [3]              : 0x0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [4]              : 0xffffcb83f4a17c00 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [5]              : 0xffffcb83f4a17b70 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [6]              : 0xffffcb83e8caca10 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [7]              : 0x0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [8]              : 0xffffcb83e84b5060 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [9]              : 0xffffcb83ebf53e70 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [10]             : 0xffffcb83ec371200 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [11]             : 0xffffcb83e8ca8d20 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [12]             : 0x0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [13]             : 0xffffcb83ece2c4c0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [14]             : 0xffffcb83e8b80690 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [15]             : 0xffffcb83e8caec90 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [16]             : 0xffffcb83e84af0c0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [17]             : 0xffffcb83ece2c430 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [18]             : 0xffffcb83ece2c400 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [19]             : 0xffffcb83e854c2e0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [20]             : 0xffffcb83e85439d0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [21]             : 0xffffcb83e8845930 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [22]             : 0xffffcb83e8ca8d80 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [23]             : 0xffffcb83e855f600 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [24]             : 0x0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [25]             : 0x0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [26]             : 0xffffcb83e8841160 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [27]             : 0x0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [28]             : 0xffffcb83ec36cca0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [29]             : 0xffffcb83e8cad460 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [30]             : 0xffffcb83e84b5630 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [31]             : 0x0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [32]             : 0xffffcb83e8545a00 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [33]             : 0x0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [34]             : 0xffffcb83e8841250 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [35]             : 0xffffcb83ec36c430 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [36]             : 0xffffcb83e8842420 [Type: _OBJECT_DIRECTORY_ENTRY *]

36번 인덱스의 주소를 구조체로 확인해봅니다.

lkd> dt _OBJECT_DIRECTORY_ENTRY 0xffffcb83e8842420
nt!_OBJECT_DIRECTORY_ENTRY
   +0x000 ChainLink        : 0xffffcb83`e8568920 _OBJECT_DIRECTORY_ENTRY
   +0x008 Object           : 0xffffdc8a`4c23e9f0 Void
   +0x010 HashValue        : 0x9b5074d

2번째에 위치해있으니 ChainLink를 따라가봅니다.

lkd> dt _OBJECT_DIRECTORY_ENTRY 0xffffcb83e8568920
nt!_OBJECT_DIRECTORY_ENTRY
   +0x000 ChainLink        : 0xffffcb83`e84b5b10 _OBJECT_DIRECTORY_ENTRY
   +0x008 Object           : 0xffffcb83`e84ec220 Void
   +0x010 HashValue        : 0x80a0801

해당 OBJECT_DIRECTORY_ENTRY에 0xffffcb83e84ec220 오브젝트가 있음을 확인할 수 있습니다. (!object 한 것과 값을 비교해보세요) 이 주소는 OBJECT_DIRECTORY 구조체로 표현됩니다.(그래서 Type명이 Directory입니다.) 이를 다시 !object로 확인해봅니다.

lkd> !object 0xffffcb83e84ec220
Object: ffffcb83e84ec220  Type: (ffffdc8a4aa9c4e0) Directory
    ObjectHeader: ffffcb83e84ec1f0 (new version)
    HandleCount: 0  PointerCount: 124
    Directory Object: ffffcb83e84023c0  Name: Driver

    Hash Address          Type                      Name
    ---- -------          ----                      ----
     00  ffffdc8a50e1eb20 Driver                    kldbgdrv
         ffffdc8a4c9a2e20 Driver                    fvevol
         ffffdc8a4c356d70 Driver                    vdrvroot
     01  ffffdc8a4cd2ee00 Driver                    usbuhci
         ffffdc8a4cc9dd40 Driver                    GpuEnergyDrv
         ffffdc8a4ca4b9e0 Driver                    NetBT
         ffffdc8a4aa3fd00 Driver                    acpiex
         ffffdc8a4aa8bde0 Driver                    Wdf01000
     02  ffffdc8a4faabb70 Driver                    mpsdrv
         ffffdc8a4c53a060 Driver                    storahci
     03  ffffdc8a51c56540 Driver                    BthEnum
         ffffdc8a4fd73e20 Driver                    MMCSS
         ffffdc8a4f924e30 Driver                    lltdio
         ffffdc8a4cbdeb40 Driver                    bam
         ffffdc8a4cc63d80 Driver                    Psched
         ffffdc8a4cb8ae40 Driver                    BasicRender
         ffffdc8a4c9c28f0 Driver                    disk
     04  ffffdc8a4facadf0 Driver                    HTTP
         ffffdc8a4c382d80 Driver                    stornvme
     05  ffffdc8a4cdbe5b0 Driver                    e1i65x64
         ffffdc8a4cb9acb0 Driver                    WscVReg
     06  ffffdc8a4f641a70 Driver                    monitor
         ffffdc8a4cdb7b50 Driver                    usbehci
         ffffdc8a4cb9a6c0 Driver                    ahcache
         ffffdc8a4cafae40 Driver                    vmrawdsk
         ffffdc8a4c9c1dc0 Driver                    iorate
         ffffdc8a4c53b640 Driver                    pcw
     07  ffffdc8a4fcd4df0 Driver                    AMonCDW8
         ffffdc8a4cde8060 Driver                    Ucx01000
         ffffdc8a4cde7060 Driver                    USBXHCI
         ffffdc8a4c359dc0 Driver                    partmgr
     08  ffffdc8a52b98e50 Driver                    AntiStealth_V3LITE40
         ffffdc8a4fd83a10 Driver                    PEAUTH
         ffffdc8a4ab88e40 Driver                    MsLldp
         ffffdc8a4cc6fa30 Driver                    Vid
         ffffdc8a4ab0cd80 Driver                    ACPI_HAL
     09  ffffdc8a4c372850 Driver                    spaceport
     10  ffffdc8a4cf1ae00 Driver                    HidUsb
         ffffdc8a4cc62dd0 Driver                    vwififlt
     11  ffffdc8a50ea0e10 Driver                    condrv
         ffffdc8a4cb9be40 Driver                    DXGKrnl
         ffffdc8a4ab35e20 Driver                    PnpManager
     12  ffffdc8a4c9c9740 Driver                    Null
         ffffdc8a4c35ca80 Driver                    vsock
         ffffdc8a4ab3be20 Driver                    intelpep
     13  ffffdc8a506c4e30 Driver                    MeDCoreD_V3LITE40
         ffffdc8a4aa81e20 Driver                    Telemetry
         ffffdc8a4aae6de0 Driver                    SoftwareDevice
     14  ffffdc8a52e98a70 Driver                    RFCOMM
         ffffdc8a4ca57e10 Driver                    Serenum
         ffffdc8a4c8ae0a0 Driver                    CLFS
         ffffdc8a4ab28e20 Driver                    WindowsTrustedRTProxy
     15  ffffdc8a4ccdae20 Driver                    Serial
         ffffdc8a4cc59d40 Driver                    NdisCap
         ffffdc8a4c8b3d30 Driver                    KSecDD
         ffffdc8a4c35bda0 Driver                    volmgr
         ffffdc8a4aaced80 Driver                    DeviceApi
     16  ffffdc8a4fcd3c90 Driver                    VMMemCtl
         ffffdc8a4ccd6e20 Driver                    umbus
         ffffdc8a4aad9c10 Driver                    MsSecFlt
         ffffdc8a4abd8cc0 Driver                    CNG
     17  ffffdc8a4ce72e20 Driver                    Win32k
         ffffdc8a4cce0dc0 Driver                    i8042prt
         ffffdc8a4cc96d70 Driver                    npsvctrig
         ffffdc8a4c9bed90 Driver                    volume
         ffffdc8a4c8b6e00 Driver                    KSecPkg
     18  ffffdc8a4cca25b0 Driver                    mouclass
     19  ffffdc8a4ea59e00 Driver                    X58a84jzGG36Q
         ffffdc8a4c53d350 Driver                    msisadrv
     20  ffffdc8a4fd79e10 Driver                    Ndu
         ffffdc8a4ccdddb0 Driver                    kbdclass
     21  ffffdc8a4c8b8e00 Driver                    mouhid
         ffffdc8a4c9bf8f0 Driver                    volsnap
     22  ffffdc8a567efe30 Driver                    MeDVpDrv_V3LITE40
         ffffdc8a4cc71dd0 Driver                    nsiproxy
         ffffdc8a4c944bd0 Driver                    AhnRghNt
         ffffdc8a4aaddd80 Driver                    WMIxWDM
     23  ffffdc8a528188f0 Driver                    BthPan
         ffffdc8a4fac3e30 Driver                    MsQuic
         ffffdc8a4cb6f9a0 Driver                    tdx
         ffffdc8a4c360a90 Driver                    vmci
     24  ffffdc8a5102ae30 Driver                    AntiStealth_V3LITE40F
         ffffdc8a52f8b570 Driver                    BTHUSB
         ffffdc8a4ab32e20 Driver                    WindowsTrustedRT
     25  ffffdc8a4cd2fde0 Driver                    HDAudBus
         ffffdc8a4cbbde40 Driver                    BasicDisplay
     26  ffffdc8a4cd62e00 Driver                    rdpbus
     27  ffffdc8a50eaca70 Driver                    Cdm2DrNt
         ffffdc8a4fcd3a70 Driver                    DBGV
         ffffdc8a4c358dc0 Driver                    pdc
     28  ffffdc8a4f92de20 Driver                    rspndr
         ffffdc8a4e14fe00 Driver                    vmusbmouse
     29  ffffdc8a4ce59670 Driver                    HdAudAddService
         ffffdc8a4cc98d60 Driver                    mssmbios
         ffffdc8a4cc97de0 Driver                    CSC
         ffffdc8a4c372d90 Driver                    volmgrx
         ffffdc8a4c536060 Driver                    pci
     30  ffffdc8a545d5e50 Driver                    ArtDrv
         ffffdc8a4cd67ce0 Driver                    NdisVirtualBus
         ffffdc8a4cdeb300 Driver                    CmBatt
         ffffdc8a4cce1e00 Driver                    vm3dmp_loader
         ffffdc8a4ccd8e20 Driver                    kdnic
         ffffdc8a4c9c1ba0 Driver                    cdrom
         ffffdc8a4c8b54e0 Driver                    NDIS
     31  ffffdc8a4cd65dc0 Driver                    swenum
     32  ffffdc8a4ce6ee30 Driver                    usbhub
         ffffdc8a4c9bfb00 Driver                    rdyboost
         ffffdc8a4c997e30 Driver                    WFPLWFS
         ffffdc8a4c8b7e00 Driver                    Tcpip
         ffffdc8a4aad9e20 Driver                    SgrmAgent
     33  ffffdc8a543a7750 Driver                    TSFltDrv_V3LITE40
         ffffdc8a4ce66cb0 Driver                    USBHUB3
         ffffdc8a4cdec940 Driver                    intelppm
         ffffdc8a4cd2fb20 Driver                    gencounter
         ffffdc8a4c162e40 Driver                    Beep
         ffffdc8a4c374410 Driver                    atapi
     34  ffffdc8a4cf18e00 Driver                    usbccgp
         ffffdc8a4cb6b9a0 Driver                    AFD
         ffffdc8a4c373c40 Driver                    mountmgr
         ffffdc8a4c365e30 Driver                    intelide
     35  ffffdc8a4e156410 Driver                    ATamptNt_V3LITE40
         ffffdc8a52bb1b70 Driver                    BTHPORT
         ffffdc8a4fd83e30 Driver                    tcpipreg
         ffffdc8a4ce32060 Driver                    ksthunk
         ffffdc8a4ccd9e30 Driver                    vmmouse
         ffffdc8a4cb6c9a0 Driver                    afunix
     36  ffffdc8a55296750 Driver                    asc_kbc_V3LITE40
         ffffdc8a4ca547b0 Driver                    vm3dmp
         ffffdc8a4cca4db0 Driver                    CompositeBus
         ffffdc8a4caf99a0 Driver                    ws2ifsl
         ffffdc8a4c64edd0 Driver                    EhStorClass
         ffffdc8a4aa954c0 Driver                    ACPI

로딩된 드라이버 목록이 나오는 것을 확인할 수 있습니다. 

위에서 언급했듯이, 각각의 Entry(1줄당 하나의 Entry, 여기서는 드라이버를 의미)는 체인으로 연결되어 있습니다. 아래 그림처럼 특정 Entry를 제거한 후 체인을 이을 수 있습니다.

33번 인덱스의 2번째인 USBHUB3를 목록에서 숨겨본다고 가정하겠습니다. 

우선 위 주소를 구조체로 표현해봅니다.

lkd> dt _OBJECT_DIRECTORY 0xffffcb83e84ec220
nt!_OBJECT_DIRECTORY
   +0x000 HashBuckets      : [37] 0xffffcb83`f16ee960 _OBJECT_DIRECTORY_ENTRY
   +0x128 Lock             : _EX_PUSH_LOCK
   +0x130 DeviceMap        : (null) 
   +0x138 ShadowDirectory  : (null) 
   +0x140 NamespaceEntry   : (null) 
   +0x148 SessionObject    : (null) 
   +0x150 Flags            : 0
   +0x154 SessionId        : 0xffffffff

HashBucket을 눌러보면 아래와 같이 나옵니다.

lkd> dx -id 0,0,ffffdc8a4aa96040 -r1 (*((ntkrnlmp!_OBJECT_DIRECTORY_ENTRY * (*)[37])0xffffcb83e84ec220))
(*((ntkrnlmp!_OBJECT_DIRECTORY_ENTRY * (*)[37])0xffffcb83e84ec220))                 [Type: _OBJECT_DIRECTORY_ENTRY * [37]]
    [0]              : 0xffffcb83f16ee960 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [1]              : 0xffffcb83e8ca9a10 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [2]              : 0xffffcb83ec3710b0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [3]              : 0xffffcb83f2246b20 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [4]              : 0xffffcb83ec370900 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [5]              : 0xffffcb83e8ca9e30 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [6]              : 0xffffcb83f66bb380 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [7]              : 0xffffcb83edd0bf70 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [8]              : 0xffffcb83edd081f0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [9]              : 0xffffcb83e8545490 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [10]             : 0xffffcb83e8568860 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [11]             : 0xffffcb83efa5efd0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [12]             : 0xffffcb83e854c820 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [13]             : 0xffffcb83edd05790 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [14]             : 0xffffcb83f2246ac0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [15]             : 0xffffcb83e8ca8c30 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [16]             : 0xffffcb83ec373fc0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [17]             : 0xffffcb83e8b809c0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [18]             : 0xffffcb83e8ca8a50 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [19]             : 0xffffcb83f2245590 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [20]             : 0xffffcb83ece2d4b0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [21]             : 0xffffcb83e8cae4e0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [22]             : 0xffffcb83edd05c10 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [23]             : 0xffffcb83f2246eb0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [24]             : 0xffffcb83edd08c70 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [25]             : 0xffffcb83e8ca9a40 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [26]             : 0xffffcb83e8cab330 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [27]             : 0xffffcb83edd08be0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [28]             : 0xffffcb83ec36f310 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [29]             : 0xffffcb83e8cad760 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [30]             : 0xffffcb83edd0cb10 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [31]             : 0xffffcb83e8cab180 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [32]             : 0xffffcb83e8cacda0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [33]             : 0xffffcb83edd0ced0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [34]             : 0xffffcb83e85686b0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [35]             : 0xffffcb83edd087c0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [36]             : 0xffffcb83edd0cf30 [Type: _OBJECT_DIRECTORY_ENTRY *]

33번 인덱스의 주소를 구조체로 확인해봅니다.

lkd>  dt _OBJECT_DIRECTORY_ENTRY 0xffffcb83edd0ced0
nt!_OBJECT_DIRECTORY_ENTRY
   +0x000 ChainLink        : 0xffffcb83`e8cadac0 _OBJECT_DIRECTORY_ENTRY
   +0x008 Object           : 0xffffdc8a`543a7750 Void // TSFltDrv_V3LITE40 오브젝트
   +0x010 HashValue        : 0x602bada7

2번째에 위치해있으니 ChainLink주소를 따라가봅니다.

lkd> dt _OBJECT_DIRECTORY_ENTRY 0xffffcb83`e8cadac0
nt!_OBJECT_DIRECTORY_ENTRY
   +0x000 ChainLink        : 0xffffcb83`e8caa730 _OBJECT_DIRECTORY_ENTRY
   +0x008 Object           : 0xffffdc8a`4ce66cb0 Void // USBHUB3 오브젝트
   +0x010 HashValue        : 0x19f5be6d

해당 OBJECT_DIRECTORY_ENTRY에 USBHUB3인 0xffffdc8a4ce66cb0 오브젝트에 도달한 것을 확인할 수 있습니다. 여기서 이전 Entry의 ChainLink를 USBHUB3 Entry가 가리키는 ChainLink로 변경하면 됩니다. 

이제 중요한 것은 해당 OBJECT_DIRECTORY_ENTRY에 어떻게 도달하느냐인데, DriverEntry함수의 PDRIVER_OBJECT는 Directory 타입의 "Driver"에 속해있는 유형입니다. "Driver"에 속해있는 드라이버라면 OBJECT_DIRECTORY(일종의 부모)가 동일합니다. 따라서 타 드라이버의 DRIVER_OBJECT 등을 구할 필요없이 자신의 드라이버 모듈을 Head로 사용하면 됩니다.

"Driver" 의 OBJECT_DIRECTORY에 접근하기 위해서 우선 ObQueryNameInfo함수로 OBJECT_HEADER_NAME_INFO 구조체 주소를 구해야 합니다. 해당 구조체에 OBJECT_DIRECTORY를 가리키는 필드가 있습니다.

POBJECT_HEADER_NAME_INFO pObjectHeaderNameInfo = ObQueryNameInfo(pDriverObject);
POBJECT_DIRECTORY pObjectDirectory = pObjectHeaderNameInfo->Directory;

OBJECT_DIRECTORY를 구했으면 각각의 ENTRY를 순회한 뒤 이름이 일치하면 ChainLink를 변경하는 코드를 작성합니다.

UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"USBHUB3");
for (int i = 0; i < 37; i++)
{
	POBJECT_DIRECTORY_ENTRY pBlinkObjectDirectoryEntry = NULL; // 이전 노드 저장
	POBJECT_DIRECTORY_ENTRY pObjectDirectoryEntry = pObjectDirectory->HashBuckets[i];

	while (pObjectDirectoryEntry)
	{        
		// 일치하면
		if (RtlEqualUnicodeString(DriverName, &pObjectHeaderNameInfo->Name, TRUE))
		{
			// 체인의 0번째(=헤드)가 자신의 Entry일때
			if (pObjectDirectory->HashBuckets[p] == pObjectDirectoryEntry)
			{			
				pObjectDirectory->HashBuckets[p] = pObjectDirectoryEntry->ChainLink; // 내 Entry의 다음 Entry를 헤드로 만든다.
				pObjectDirectoryEntry->ChainLink = NULL;
			}
			else // 1번째부터
			{			
				pBlinkObjectDirectoryEntry->ChainLink = pObjectDirectoryEntry->ChainLink; // 이전 Entry의 다음 Entry를 내 다음 Entry로 가리킨다.
				pObjectDirectoryEntry->ChainLink = NULL;
			}
		}
	        pBlinkObjectDirectoryEntry = pObjectDirectoryEntry;
		pObjectDirectoryEntry = pObjectDirectoryEntry->ChainLink;
	}
}

코드를 실행하여 체인 연결을 끊은 후 windbg로 확인해보면 TSFltDrv_V3LITE40의 ChainLink가 USBHUB3가 아닌 intelppm을 가리키는 것을 확인할 수 있습니다.

    33  ffffdc8a543a7750 Driver                    TSFltDrv_V3LITE40
        ffffdc8a4cdec940 Driver                    intelppm
        ffffdc8a4cd2fb20 Driver                    gencounter
        ffffdc8a4c162e40 Driver                    Beep
        ffffdc8a4c374410 Driver                    atapi
lkd> dt _OBJECT_DIRECTORY_ENTRY 0xffffcb83edd0ced0 // TSFltDrv_V3LITE40 엔트리
nt!_OBJECT_DIRECTORY_ENTRY
   +0x000 ChainLink        : 0xffffcb83`e8caa730 _OBJECT_DIRECTORY_ENTRY // intelpm 엔트리
   +0x008 Object           : 0xffffdc8a`543a7750 Void // TSFltDrv_V3LITE40 오브젝트
   +0x010 HashValue        : 0x602bada7
lkd> dt _OBJECT_DIRECTORY_ENTRY 0xffffcb83`e8cadac0
nt!_OBJECT_DIRECTORY_ENTRY
   +0x000 ChainLink        : (null) // 체인이 끊어짐
   +0x008 Object           : 0xffffdc8a`4ce66cb0 Void // USBHUB3 오브젝트
   +0x010 HashValue        : 0x19f5be6d
lkd> dt _OBJECT_DIRECTORY_ENTRY 0xffffcb83e8caa730 // intelppm 엔트리
nt!_OBJECT_DIRECTORY_ENTRY
   +0x000 ChainLink        : 0xffffcb83`e8caaa30 _OBJECT_DIRECTORY_ENTRY
   +0x008 Object           : 0xffffdc8a`4cdec940 Void // intelppm 오브젝트
   +0x010 HashValue        : 0x29f82c1

 

+ Recent posts