뭉근 : 느긋하게 타는 불

  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 

하면 된다. ^_^ 아 괜히 부끄러워지네... 

아래는 뭐.. 남겨둔다. 소스 코드도 수정해서 다시 올려야겠다.

  1. 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

   

  1. 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 : 

kdbgext.dll


*여담이지만 처음만들 때는 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