_DRIVER_OBJECT.DriverSection 정보
윈도우 커널에서 드라이버에 대한 정보를 관리하는 오브젝트가 있는데 이를 드라이버 오브젝트(_DRIVER_OBJECT)라고 한다. 이 오브젝트란 것이 프로그래밍상의 오브젝트가 아니라 말 그대로 '드라이버 객체'를 의미한다. 프로그래밍상으로 보면 구조체라고 보면 된다. 아래는 _DRIVER_OBJECT 구조체 정의이다.
kd> dt _DRIVER_OBJECT
nt!_DRIVER_OBJECT
+0x000 Type : Int2B
+0x002 Size : Int2B
+0x004 DeviceObject : Ptr32 _DEVICE_OBJECT
+0x008 Flags : Uint4B
+0x00c DriverStart : Ptr32 Void
+0x010 DriverSize : Uint4B
+0x014 DriverSection : Ptr32 Void
+0x018 DriverExtension : Ptr32 _DRIVER_EXTENSION
+0x01c DriverName : _UNICODE_STRING
+0x024 HardwareDatabase : Ptr32 _UNICODE_STRING
+0x028 FastIoDispatch : Ptr32 _FAST_IO_DISPATCH
+0x02c DriverInit : Ptr32 long
+0x030 DriverStartIo : Ptr32 void
+0x034 DriverUnload : Ptr32 void
+0x038 MajorFunction : [28] Ptr32 long
(Windows 7 SP0 x86 from Windbg)
이 중에 DriverSection이 Void형 포인터란 것을 알 수 있다. 즉 이 부분을 커널 디버깅하는 유저들에게 알려주지 않겠다는 뜻인데, 리버서들은 아래와 같이 이 영역이 사용된다는 것을 알아내었다. ㅡㅡa
typedef struct _KLDR_DATA_TABLE_ENTRY {
/*+0x000*/ LIST_ENTRY InLoadOrderLinks;
/*+0x008*/ PVOID ExceptionTable;
/*+0x00c*/ ULONG ExceptionTableSize;
// ULONG padding on IA64
/*+0x010*/ PVOID GpValue;
/*+0x014*/ PNON_PAGED_DEBUG_INFO NonPagedDebugInfo;
/*+0x018*/ PVOID DllBase;
/*+0x01c*/ PVOID EntryPoint;
/*+0x020*/ ULONG SizeOfImage;
/*+0x024*/ UNICODE_STRING FullDllName;
/*+0x02c*/ UNICODE_STRING BaseDllName;
/*+0x034*/ ULONG Flags;
/*+0x038*/ USHORT LoadCount;
/*+0x03c*/ USHORT __Unused5;
/*+0x03e*/ PVOID SectionPointer;
/*+0x040*/ ULONG CheckSum;
// ULONG padding on IA64
/*+0x044*/ PVOID LoadedImports;
/*+0x048*/ PVOID PatchInformation;
} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;
출처: <http://www.kernelmode.info/forum/viewtopic.php?f=10&t=1206>
뭐 사실 위 구조체에서 명확히 얻을 수 있는 정보는 드라이버 오브젝트(_DRVIER_OBJECT)와 커널 모듈 엔트리(_LDR_DATA_TABLE_ENTRY)의 base(MZ~) 주소를 비교하여 서로 얻을 수 있지만 위처럼 문서화되지 않은 구조체를 사용하여 편하게 구할 수도 있다.
한번 실제로 이런지 살펴봐야겠다.
kd> !drvobj \Driver\rspndr
Driver object (867f2628) is for:
\Driver\rspndr
Driver Extension List: (id , addr)
Device Object list:
867f3be8
kd> dt _DRIVER_OBJECT 867f2628
nt!_DRIVER_OBJECT
+0x000 Type : 0n4
+0x002 Size : 0n168
+0x004 DeviceObject : 0x867f3be8 _DEVICE_OBJECT
+0x008 Flags : 0x12
+0x00c DriverStart : 0x8923b000 Void
+0x010 DriverSize : 0x13000
+0x014 DriverSection : 0x867f2848 Void // -> _KLDR_DATA_TABLE_ENTRY
+0x018 DriverExtension : 0x867f26d0 _DRIVER_EXTENSION
+0x01c DriverName : _UNICODE_STRING "\Driver\rspndr"
+0x024 HardwareDatabase : 0x82fa9250 _UNICODE_STRING "\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM"
+0x028 FastIoDispatch : (null)
+0x02c DriverInit : 0x8924a450 long +ffffffff8924a450
+0x030 DriverStartIo : (null)
+0x034 DriverUnload : 0x89248422 void +ffffffff89248422
+0x038 MajorFunction : [28] 0x82cf2da3 long nt!IopInvalidDeviceRequest+0
kd> dc 0x867f2848
867f2848 86416198 867ecd28 ffffffff ffffffff .aA.(.~.........
867f2858 00000000 00000000 8923b000 8924a450 ..........#.P.$.
867f2868 00013000 004e004e 8a46fc00 00140014 .0..N.N...F.....
867f2878 867f28a4 49104000 00000001 00000000 .(...@.I........
867f2888 00017a94 00000000 00000000 8a47aa38 .z..........8.G.
867f2898 00000000 00013000 4a5bc8f0 00730072 .....0....[Jr.s.
867f28a8 006e0070 00720064 0073002e 00730079 p.n.d.r...s.y.s.
867f28b8 ffff0000 7fffffff 04030010 69536d4d ............MmSi
아 근데 이거 비교해보니까.. 그냥 _LDR_DATA_TABLE_ENTRY를 가리키는거 같다. --a
kd> dt _LDR_DATA_TABLE_ENTRY 0x867f2848
nt!_LDR_DATA_TABLE_ENTRY
+0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x86416198 - 0x867ecd28 ]
+0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0xffffffff - 0xffffffff ]
+0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x018 DllBase : 0x8923b000 Void
+0x01c EntryPoint : 0x8924a450 Void
+0x020 SizeOfImage : 0x13000
+0x024 FullDllName : _UNICODE_STRING "\SystemRoot\system32\DRIVERS\rspndr.sys"
+0x02c BaseDllName : _UNICODE_STRING "rspndr.sys"
+0x034 Flags : 0x49104000
+0x038 LoadCount : 1
+0x03a TlsIndex : 0
+0x03c HashLinks : _LIST_ENTRY [ 0x0 - 0x17a94 ]
+0x03c SectionPointer : (null)
+0x040 CheckSum : 0x17a94
+0x044 TimeDateStamp : 0
+0x044 LoadedImports : (null)
+0x048 EntryPointActivationContext : (null)
+0x04c PatchInformation : 0x8a47aa38 Void
+0x050 ForwarderLinks : _LIST_ENTRY [ 0x0 - 0x13000 ] // 여기 아래부터 필드 사용 안함
+0x058 ServiceTagLinks : _LIST_ENTRY [ 0x4a5bc8f0 - 0x730072 ]
+0x060 StaticLinks : _LIST_ENTRY [ 0x6e0070 - 0x720064 ]
+0x068 ContextInformation : 0x0073002e Void
+0x06c OriginalBase : 0x730079
+0x070 LoadTime : _LARGE_INTEGER 0x7fffffff`ffff0000
LoadedImports 구조체와 완전 유사하다. PatchInformation 쯤 부터 오프셋 차이가 나는데 위 리버싱이 잘못된 걸까 싶기도 하다.
ForwarderLinks 부터는 필드 값이 정상적이지 않아서 사용하지 않는 걸로 판단하였었는데, 뭐 다른걸로 사용될 수도?
실제로 모듈의 풀 헤더(_POOL_HEADER)를 살펴보면
아래와 같이 _POOL_HEADER의 크기(0x08) + _LDR_DATA_TABLE_ENTRY(0x78)의 크기로 구성된 것을 알 수 있다.
kd> dt _POOL_HEADER 0x867f2848-8
nt!_POOL_HEADER
+0x000 PreviousSize : 0y000000110 (0x6)
+0x000 PoolIndex : 0y0000000 (0)
+0x002 BlockSize : 0y000010000 (0x10) // 0x10 * 0x08(x86 pool alignment) = 0x80
+0x002 PoolType : 0y0000010 (0x2)
+0x000 Ulong1 : 0x4100006
+0x004 PoolTag : 0x644c6d4d
+0x004 AllocatorBackTraceIndex : 0x6d4d
+0x006 PoolTagHash : 0x644c
바이너리도 살펴보면
kd> dc 0x867f2848 L24
867f2848 86416198 867ecd28 ffffffff ffffffff .aA.(.~.........
867f2858 00000000 00000000 8923b000 8924a450 ..........#.P.$.
867f2868 00013000 004e004e 8a46fc00 00140014 .0..N.N...F.....
867f2878 867f28a4 49104000 00000001 00000000 .(...@.I........
867f2888 00017a94 00000000 00000000 8a47aa38 .z..........8.G.
867f2898 00000000 00013000 4a5bc8f0 00730072 .....0....[Jr.s.
867f28a8 006e0070 00720064 0073002e 00730079 p.n.d.r...s.y.s.
867f28b8 ffff0000 7fffffff 04030010 69536d4d ............MmSi // 아래부터 blocksize를 벗어남
867f28c8 00000000 829028f0 00000001 867f28d4 .....(.......(..
실제로 MmSi 시그너처가 있는 것으로 보아 다른 영역으로 사용되는 것을 추측할 수 있다.
결론을 내리자면 _DRIVER_OBJECT.DriverSection은 _LDR_DATA_TABLE_ENTRY(또는 _KLDR_DATA_TABLE_ENTRY)를 가리킨다. 정도?
항상 커널 분석은 미궁이다. --a
'디버깅' 카테고리의 다른 글
MS 심볼 구성에 관하여 (0) | 2014.12.17 |
---|---|
Windows 10 _KPCR and _KPRCB (0) | 2014.11.14 |
8바이트 변수 초기화 문제 (0) | 2014.11.14 |
Windbg에서 KDBG 찾기 (0) | 2014.06.19 |
Window8 Remote Kernel Debugging on Vmware using WinDbg (0) | 2014.04.11 |