테스트환경 : windows 10 x64 build 19041
OBJECT_HEADER에서 OBJECT_HEADER_NAME_INFO를 어떻게 얻을까 다양한 방법으로 구글링해보다가 ObQueryNameInfo(PVOID pObject) 함수가 있다는 것을 발견했습니다. 이 함수를 쓰면 POBJECT_HEADER_NAME_INFO 주소를 리턴하더군요. 어떻게 얻나 궁금해서 windbg로 까봤습니다.
0: kd> u ObQueryNameInfo
nt!ObQueryNameInfo:
fffff803`6987b920 0fb641ea movzx eax,byte ptr [rcx-16h]
fffff803`6987b924 4883c1d0 add rcx,0FFFFFFFFFFFFFFD0h
fffff803`6987b928 a802 test al,2
fffff803`6987b92a 7416 je nt!ObQueryNameInfo+0x22 (fffff803`6987b942)
fffff803`6987b92c 83e003 and eax,3
fffff803`6987b92f 488d154aa55a00 lea rdx,[nt!ObpInfoMaskToOffset (fffff803`69e25e80)]
fffff803`6987b936 0fb60410 movzx eax,byte ptr [rax+rdx]
fffff803`6987b93a 482bc8 sub rcx,rax
fffff803`6987b93d 488bc1 mov rax,rcx
fffff803`6987b940 c3 ret
먼저 인자에서 0x16을 뺀것을 포인터 참조해서 저장하고, 그 다음은 0x30만큼 빼고 주소를 저장하네요. (인자로는 DRIVER_OBJECT 0xffffc28f1318ce30 를 줘봤습니다. )
일단 0x30만큼 뺀 것은 OBJECT_HADER 구조체였습니다. (대충 감으로 때려맞춤...)
kd> dt _OBJECT_HEADER 0xffffc28f1318ce30-0x30
nt!_OBJECT_HEADER
+0x000 PointerCount : 0n3
+0x008 HandleCount : 0n0
+0x008 NextToFree : (null)
+0x010 Lock : _EX_PUSH_LOCK
+0x018 TypeIndex : 0x13 ''
+0x019 TraceFlags : 0 ''
+0x019 DbgRefTrace : 0y0
+0x019 DbgTracePermanent : 0y0
+0x01a InfoMask : 0x2 ''
+0x01b Flags : 0x12 ''
+0x01b NewObject : 0y0
+0x01b KernelObject : 0y1
+0x01b KernelOnlyAccess : 0y0
+0x01b ExclusiveObject : 0y0
+0x01b PermanentObject : 0y1
+0x01b DefaultSecurityQuota : 0y0
+0x01b SingleHandleEntry : 0y0
+0x01b DeletedInline : 0y0
+0x01c Reserved : 0xffffc28f
+0x020 ObjectCreateInfo : 0x00000000`00000001 _OBJECT_CREATE_INFORMATION
+0x020 QuotaBlockCharged : 0x00000000`00000001 Void
+0x028 SecurityDescriptor : 0xffffb20d`a6735cee Void
+0x030 Body : _QUAD
0x16만큼 뺀것은 +0x1A에 위치해 있는 InfoMask 필드네요. InfoMask & 2 가 참이면 InfoMask & 3을 하여 index로 사용합니다. (예제에서는 2 & 3 = 2(index))
그 다음으로 ObpInfoMaskToOffset 에서 index를 사용하여 오프셋을 꺼내옵니다.
(BYTE*)ObpInfoMaskToOffset(0xfffff803`69e25e80) + index(2) (예제는 fffff803`69e25e82가 되겠군요.)
2: kd> db fffff803`69e25e80
fffff803`69e25e80 00 20 20 40 10 30 30 50-20 40 40 60 30 50 50 70 . @.00P @@`0PPp
fffff803`69e25e90 10 30 30 50 20 40 40 60-30 50 50 70 40 60 60 80 .00P @@`0PPp@``.
fffff803`69e25ea0 10 30 30 50 20 40 40 60-30 50 50 70 40 60 60 80 .00P @@`0PPp@``.
fffff803`69e25eb0 20 40 40 60 30 50 50 70-40 60 60 80 50 70 70 90 @@`0PPp@``.Ppp.
fffff803`69e25ec0 10 30 30 50 20 40 40 60-30 50 50 70 40 60 60 80 .00P @@`0PPp@``.
fffff803`69e25ed0 20 40 40 60 30 50 50 70-40 60 60 80 50 70 70 90 @@`0PPp@``.Ppp.
fffff803`69e25ee0 20 40 40 60 30 50 50 70-40 60 60 80 50 70 70 90 @@`0PPp@``.Ppp.
fffff803`69e25ef0 30 50 50 70 40 60 60 80-50 70 70 90 60 80 80 a0 0PPp@``.Ppp.`...
OBJECT_HEADER 주소에서 꺼내온 0x20(OBJECT_HEADER_NAME_INFO 구조체 사이즈)만큼 빼고 해당 주소를 리턴합니다.
예제는 0xffffc28f1318ce00 - 0x20 = 0xffffc28f1318cde0
kd> dt _OBJECT_HEADER_NAME_INFO 0xffffc28f1318cde0
nt!_OBJECT_HEADER_NAME_INFO
+0x000 Directory : 0xffffb20d`a66ec5a0 _OBJECT_DIRECTORY
+0x008 Name : _UNICODE_STRING "KernelV"
+0x018 ReferenceCount : 0n0
+0x01c Reserved : 0
잘 얻어졌습니다.
ObpInfoMaskToOffset는 0x100개의 배열이며, 직접 생성할 수도 있습니다. (아래의 소스에 자세히 나와있습니다.)
github.com/hfiref0x/WinObjEx64/blob/master/Source/WinObjEx64/kldbg.c
'Windows > WDK' 카테고리의 다른 글
드라이버 숨기기 (OBJECT_DIRECTORY) (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 |