테스트 환경 : 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
'Windows > WDK' 카테고리의 다른 글
OBJECT_HEADER or DRIVER_OBJECT에서 OBJECT_HEADER_NAME_INFO 얻는 방법 (0) | 2020.10.22 |
---|---|
드라이버 숨기기 (LDR_DATA_TABLE_ENTRY) (0) | 2020.10.13 |
코드서명 없이 WDK 드라이버 실행하기 (Windows 10 64비트) (3) | 2020.03.19 |
[64비트] Visual Studio 2010 + WDK + MASM 개발 환경 구축하기 (2) | 2014.08.28 |
WDK 왕초보를 위한 개발 가이드 #3 - 문자열 사용 (0) | 2014.04.08 |