뭉근 : 느긋하게 타는 불

윈도우 커널에서 드라이버에 대한 정보를 관리하는 오브젝트가 있는데 이를 드라이버 오브젝트(_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