윈도우는 멀티 태스킹(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 개의 댓글:
댓글 쓰기