Windbg에서 KDBG 찾기
Windbg의 타겟 시스템은 wdbgexts.h에 정의되어 있는 _KDDEBUGGER_DATA64 구조체(이하 KDBG)를 이용하여 그 디버깅 정보를 유지한다. 또한 Windbg는 심볼 정보가 담긴 pdb 파일을 이용하여 구조체들의 필드 구성과 해당 값을 볼 수 있다. 이런 구조체 조사를 아래와 같이 "dt" 명령어를 통해 지원한다.
kd> dt _EPROCESS
nt!_EPROCESS
+0x000 Pcb : _KPROCESS
+0x2c8 ProcessLock : _EX_PUSH_LOCK
+0x2d0 CreateTime : _LARGE_INTEGER
+0x2d8 RundownProtect : _EX_RUNDOWN_REF
+0x2e0 UniqueProcessId : Ptr64 Void
+0x2e8 ActiveProcessLinks : _LIST_ENTRY
+0x2f8 Flags2 : Uint4B
+0x2f8 JobNotReallyActive : Pos 0, 1 Bit
(생략)
하지만 타겟 시스템(Debuggee) 내에서도 유용하게 사용되는 KDBG 구조체 정보는 dt 명령어를 통해 한눈에 볼 수가 없는데, 이유는 KDBG 구조체에 대한 심볼 정보가 없기 때문이다. 뭐 사실 KDBG 구조체를 누가 자주 찾아보겠는가 하지만… 가끔씩 KDBG 구조체를 봐야할 때가 있는데 이 때마다 아래와 같은 방법으로 KDBG 구조체를 찾았다.
Version 정보
Microsoft (R) Windows Debugger Version 6.3.9600.16384 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.
Opened \\.\pipe\com_8_64
Waiting to reconnect...
Connected to Windows 8 9200 x64 target at (Tue Jun 17 19:40:42.866 2014 (UTC + 9:00)), ptr64 TRUE
Kernel Debugger connection established.
Windbg에서 KDBG 찾기
dq KdDebuggerDataBlock
하면 된다. ^_^ 아 괜히 부끄러워지네...
아래는 뭐.. 남겨둔다. 소스 코드도 수정해서 다시 올려야겠다.
- KdVersionBlock의 주소를 얻는다.
kd> dq KdVersionBlock
fffff803`5f2fddf0 00070206`23f0000f 00000031`030c8664
fffff803`5f2fde00 fffff803`5f08a000 fffff803`5f354a60
fffff803`5f2fde10 fffff803`5f30a8d0 ffffffff`ffffffff
fffff803`5f2fde20 00000000`00140014 00000000`00000000
fffff803`5f2fde30 00000000`00000000 00000000`00000000
fffff803`5f2fde40 00000000`00000000 00000000`00000000
fffff803`5f2fde50 00000000`00000000 00000000`00000000
fffff803`5f2fde60 00000000`00000000 00000000`00000000
이 KdVersionBlock은 Windbg의 커널의 전역 변수로 디버깅 시스템에 대한 버전 정보를 지닌 _DBGKD_GET_VERSION64 구조체의 주소를 가지고 있다. 또한 이 구조체의 DebuggerDataList 필드는 KDBG 리스트의 주소를 가지고 있다. 리스트라고 했지만 사실 KDBG는 하나만 존재한다. 리스트는 확장성을 위해서 그런 형태로 남겨둔 것 같다.
kd> dt nt!_DBGKD_GET_VERSION64 fffff803`5f2fddf0
+0x000 MajorVersion : 0xf
+0x002 MinorVersion : 0x23f0
+0x004 ProtocolVersion : 0x6 ''
+0x005 KdSecondaryVersion : 0x2 ''
+0x006 Flags : 7
+0x008 MachineType : 0x8664
+0x00a MaxPacketType : 0xc ''
+0x00b MaxStateChange : 0x3 ''
+0x00c MaxManipulate : 0x31 '1'
+0x00d Simulation : 0 ''
+0x00e Unused : [1] 0
+0x010 KernBase : 0xfffff803`5f08a000
+0x018 PsLoadedModuleList : 0xfffff803`5f354a60
+0x020 DebuggerDataList : 0xfffff803`5f30a8d0 // -> _PKDDEBUGGER_DATA64
- DebuggerDataList를 통해 KDBG의 주소를 얻는다.
kd> dq 0xfffff803`5f30a8d0
fffff803`5f30a8d0 fffff803`5f2fda90 fffff803`5f2fda90
fffff803`5f30a8e0 00001666`754785db 00001666`754785db
fffff803`5f30a8f0 00000000`00000000 00000000`00da7a64
fffff803`5f30a900 526d6574`7379535c 74737973`5c746f6f
fffff803`5f30a910 6f746e5c`32336d65 78652e6c`6e726b73
fffff803`5f30a920 00000000`00000065 00000000`00000000
fffff803`5f30a930 00000000`00000000 00000000`00000000
fffff803`5f30a940 00000000`00000000 00000000`00000000
KDBG의 주소는 fffff803`5f2fda90로 LIST_ENTRY64의 형태로 생각하면 FLINK 부분이라고 보면 된다. 물론 바로 옆 8바이트를 보면 BLINK 부분도 같은 값으로 채워져 있는 것을 확인할 수 있다.
kd> dc fffff803`5f2fda90
fffff803`5f2fda90 5f30a8d0 fffff803 5f30a8d0 fffff803 ..0_......0_....
fffff803`5f2fdaa0 4742444b 00000360 5f08a000 fffff803 KDBG`......_....
fffff803`5f2fdab0 5f0ff930 fffff803 00000000 00000000 0.._............
fffff803`5f2fdac0 00000000 00010000 5f0ff510 fffff803 ..........._....
fffff803`5f2fdad0 00000000 00000000 5f354a60 fffff803 ........`J5_....
fffff803`5f2fdae0 5f320c10 fffff803 5f3e0188 fffff803 ..2_......>_....
fffff803`5f2fdaf0 5f319ac0 fffff803 5f3e21c0 fffff803 ..1_.....!>_....
fffff803`5f2fdb00 5f3e00a8 fffff803 5f3e00bc fffff803 ..>_......>_....
Tag(_KDDEBUGGER_DATA64.Header.Tag)값을 확인하여 KDBG 구조체를 확인할 수 있다. 이렇게 KDBG를 찾으면 또 문제가 생기는데 구조체 심볼 정보가 없기 때문에 원하는 필드의 값을 일일이 오프셋을 계산하여 알아내야 한다. 너무 귀찮다… 그래서 공부도 할 겸 Windbg Extesion 형태로 kdbgext.dll 플러그인을 만들었다.
KDBG EXTENSION Plugin
최대한 dt와 비슷하게 나오게 할려고 했지만 아직 부족한건 사실이다. 백문이 불여일견이라고 아래를 보면 어떻게 동작하는지 대충 알 수 있다.
kd> .load kdbgext.dll
kd> !kdbg
KDBG Windbg Extension v0.1 by ozdang
> PlatformId : 2 / Win32 : 6.2 / KD : 15.9200
> KdVersionBlock : 0xfffff80355af9df0
> DebugDataList : 0xfffff80355b068d0
> KDBG's Address : 0xfffff80355af9a90
dt _KDDEBUGGER_DATA64 0xfffff80355af9a90
+00000 Header.List.Flink : 0xfffff80355b068d0
+0x008 Header.List.Blink : 0xfffff80355b068d0
+0x010 Header.OwnerTag : 0x4742444b 'KDBG'
+0x014 Header.Size : 0x360
+0x018 KernBase : 0xfffff80355886000
+0x020 BreakpointWithStatus : 0xfffff803558fb930
+0x028 SavedContext : 0
+0x030 ThCallbackStack : 0
+0x032 NextCallback : 0
+0x034 FramePointer : 0
+0x036 Header.Size : 0x1
+0x038 KiCallUserMode : 0xfffff803558fb510
+0x040 KeUserCallbackDispatcher : 0
+0x048 PsLoadedModuleList : 0xfffff80355b50a60
+0x050 PsActiveProcessHead : 0xfffff80355b1cc10
(생략)
Windbg x86 버전에서만 동작한다. 세팅 방법은 Windbg Extension 폴더에 넣으면 된다. WDK 8.1 버전의 경우 "C:\Program Files (x86)\Windows Kits\8.1\Debuggers\x86\winext" 이다. 이후 위와 같이 .load kdbgext.dll로 플러그인을 불러오고 !kdbg 명령어를 통해 KDBG 구조체의 정보를 볼 수 있다.
본 플러그인의 소스는 https://code.google.com/p/kdbg-extension/ 에서 볼 수 있으며 다운로드도 가능하다.
Download :
*여담이지만 처음만들 때는 pdb 파일을 만들어서 심볼 정보만 얻을려고 했는데 뭔가 잘 되지 않았다… 이 방법으로 될 것 같기도 하고 아닌 것 같기도 하고… 해서 일단 확실한 플러그인 형태로 제작하였다.
'디버깅' 카테고리의 다른 글
MS 심볼 구성에 관하여 (0) | 2014.12.17 |
---|---|
Windows 10 _KPCR and _KPRCB (0) | 2014.11.14 |
8바이트 변수 초기화 문제 (0) | 2014.11.14 |
Window8 Remote Kernel Debugging on Vmware using WinDbg (0) | 2014.04.11 |
_DRIVER_OBJECT.DriverSection 정보 (0) | 2013.10.05 |