2009년 12월 9일 수요일

WinDbg 커널모드에서 유저모드 엿보기

윈도우는 멀티 태스킹(Multi-Tasking)을 지원하는 운영체제로 Context Switching (문맥교환) 을 통해서 구현되고 있습니다. 아무리 운영체제가 동시에 여러 개의 작업을 한다고 하더라도 CPU 는 한번에 하나씩 동작할 수 밖에 없기 때문에 프로세스, 레지스터, 또는 세션 등의 작업들이 사용하는 레지스트리나 메모리에 관련된 자신들만의 정보들을 가지고 가지게 됩니다. 이 것이 Context 라고 불려지는 것이고 운영체제는 Context 를 매번 바꿔가면서 작업을 하게 됩니다. 컨텍스트는 Session, Process, Register, Local Context 로 구분될 수 있습니다.

이 글에서 알아보고자 하는 것은 WinDbg 를 이용해 커널모드 디버깅을 할 때 사용자 모드에서 동작하는 응용프로그램들의 정보를 확인하고 싶을 때 어떻게 할 수 있는지 알아보려고 합니다. 서두에서 컨텍스 에 대해서 말씀 드린 이유는 WinDbg 에서 원하는 프로세스 혹은 스레드의 컨텍스로 변경해주면 되기 때문입니다.

테스트를 하기위해 가상머신(VMWare)에 윈도우 XP 를 구동시키고 가상 시리얼포트로 WinDbg 와 연결하였습니다. 윈도우 XP 에서 노트패드(notepad.exe) 를 실행하고 WinDbg 에서 브레이크 걸어 (Ctrl+Break) 테스트 하였습니다.

1) 일단 보고 싶은 프로세스 명으로 _EPROCESS 의 주소를 찾습니다.

kd> !process 0 0 notepad.exe
PROCESS 816021d0  SessionId: 0  Cid: 0450    Peb: 7ffdf000  ParentCid: 057c
    DirBase: 0e773000  ObjectTable: e1737ee0  HandleCount:  36.
    Image: notepad.exe


2) 프로세스의 내용을 조금 더 자세하게 보여달라카고~ 스래드 주소를 찾습니다.

kd> !process 816021d0  7
PROCESS 816021d0  SessionId: 0  Cid: 0450    Peb: 7ffdf000  ParentCid: 057c
    DirBase: 0e773000  ObjectTable: e1737ee0  HandleCount:  36.
    Image: notepad.exe
    VadRoot 816dd7c8 Vads 58 Clone 0 Private 160. Modified 17. Locked 0.
    DeviceMap e1afacd8
    Token                             e1db4960
    ElapsedTime                       00:00:26.500
    UserTime                          00:00:00.015
    KernelTime                        00:00:00.093
    QuotaPoolUsage[PagedPool]         30332
    QuotaPoolUsage[NonPagedPool]      2320
    Working Set Sizes (now,min,max)  (774, 50, 345) (3096KB, 200KB, 1380KB)
    PeakWorkingSetSize                774
    VirtualSize                       27 Mb
    PeakVirtualSize                   30 Mb
    PageFaultCount                    837
    MemoryPriority                    BACKGROUND
    BasePriority                      8
    CommitCharge                      375

        THREAD 81603250  Cid 0450.0484  Teb: 7ffde000 Win32Thread: e1632628 WAIT: (WrUserRequest) UserMode Non-Alertable
            815b9490  SynchronizationEvent
        Not impersonating
        DeviceMap                 e1afacd8
        Owning Process            816021d0       Image:         notepad.exe
        Wait Start TickCount      10621          Ticks: 29 (0:00:00:00.453)
        Context Switch Count      355                 LargeStack
        UserTime                  00:00:00.000
        KernelTime                00:00:00.093
        Win32 Start Address notepad!WinMainCRTStartup (0x01006ae0)
... (이하 생략)

3) 그 스래드 주소를 이용해서 Context Swiching 하면 됩니다.

kd> .thread /p /r 81603250
Implicit thread is now 81603250
Implicit process is now 816021d0
.cache forcedecodeuser done
Loading User Symbols
.....................


4) 그러고 나서 스택을 보면 notepad 문자가 보이죠~

kd> kn
  *** Stack trace for last set context - .thread/.cxr resets it
 # ChildEBP RetAddr  
00 f7a48c38 804ec71c nt!KiSwapContext+0x2e
01 f7a48c44 804ec5a3 nt!KiSwapThread+0x44
02 f7a48c6c bf8762d6 nt!KeWaitForSingleObject+0x1c0
03 f7a48ca8 bf876646 win32k!xxxSleepThread+0x189
04 f7a48cec bf87667a win32k!xxxRealInternalGetMessage+0x40f
05 f7a48d4c 804d6e91 win32k!NtUserGetMessage+0x27
06 f7a48d4c 7ffe0304 nt!KiSystemService+0xc4
07 0006feb8 77cf3c8b SharedUserData!SystemCallStub+0x4
08 0006fed8 010028e4 USER32!NtUserGetMessage+0xc
09 0006ff1c 01006c54 notepad!WinMain+0xe3
0a 0006ffc0 77e3eb69 notepad!WinMainCRTStartup+0x174
0b 0006fff0 00000000 kernel32!BaseProcessStart+0x23


5) notepad 코드 위치한 곳으로 이동 시키고~

kd> .frame 9
09 0006ff1c 01006c54 notepad!WinMain+0xe3


6) 소스를 까보면 짜잔~~~

kd> u notepad!WinMain
notepad!WinMain:
01002801 55              push    ebp
01002802 8bec            mov     ebp,esp
01002804 83ec20          sub     esp,20h
01002807 56              push    esi
01002808 57              push    edi
01002809 ff1528110001    call    dword ptr [notepad!_imp__GetCommandLineW (01001128)]
0100280f 68c8130001      push    offset notepad!`string' (010013c8)
01002814 6a29            push    29h

도움이 되셨으면 좋겠네요~

0 개의 댓글:

댓글 쓰기