利用windbg探索进程和进程上下文
1.列出所有活动进程
使用!process命令可以打印出活动进程的信息。第一个参数是要打印的EPROCESS的地址,如果指定为0则表示打印所有的进程。第二个参数用于说明打印进程信息的详细级别。指定0则表示打印最简单的信息。
[plain] view plain?
- 0: kd> !process 0 0
- **** NT ACTIVE PROCESS DUMP ****
- PROCESS 821b7490 SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000
- DirBase: 02b80020 ObjectTable: e1003e30 HandleCount: 350.
- Image: System
- PROCESS 82072da0 SessionId: none Cid: 0234 Peb: 7ffd4000 ParentCid: 0004
- DirBase: 02b80040 ObjectTable: e14323d0 HandleCount: 19.
- Image: smss.exe
- PROCESS 8204ab28 SessionId: 0 Cid: 0264 Peb: 7ffd6000 ParentCid: 0234
- DirBase: 02b80060 ObjectTable: e156e898 HandleCount: 434.
- Image: csrss.exe
- PROCESS 81e87580 SessionId: 0 Cid: 027c Peb: 7ffde000 ParentCid: 0234
- DirBase: 02b80080 ObjectTable: e1478c18 HandleCount: 294.
- Image: winlogon.exe
- PROCESS 820b5378 SessionId: 0 Cid: 02a8 Peb: 7ffde000 ParentCid: 027c
- DirBase: 02b800a0 ObjectTable: e16d3480 HandleCount: 273.
- Image: services.exe
- [...]省略部分输出
输出结果中我可以看到几个重要的字段:
·Cid : 进程id
·Peb : 进程环境块的地址
·ParentCid : 父进程id
·DirBase : 目录表 (用于转换虚拟地址和物理地址PDT)
·ObjectTable : 进程的句柄表
如果要针对某个进程查看更详细的信息,可以按照如下方式指定EPROCESS块地址,并提高信息的详细级别
[plain] view plain?
- 0: kd> !process 81f8e4b8 1
- PROCESS 81f8e4b8 SessionId: 0 Cid: 0134 Peb: 7ffdf000 ParentCid: 02a8
- DirBase: 02b802a0 ObjectTable: e1b49790 HandleCount: 101.
- Image: TPAutoConnSvc.exe
- VadRoot 81f85208 Vads 88 Clone 0 Private 276. Modified 1. Locked 0.
- DeviceMap e1003118
- Token e1afe528
- ElapsedTime 00:00:08.218
- UserTime 00:00:00.031
- KernelTime 00:00:00.031
- QuotaPoolUsage[PagedPool] 55852
- QuotaPoolUsage[NonPagedPool] 3520
- Working Set Sizes (now,min,max) (1012, 50, 345) (4048KB, 200KB, 1380KB)
- PeakWorkingSetSize 1012
- VirtualSize 33 Mb
- PeakVirtualSize 34 Mb
- PageFaultCount 1028
- MemoryPriority BACKGROUND
- BasePriority 8
- CommitCharge 393
2.切换进程上下文
因为进程的地址空间都是相互独立的,所以我们使用dd 0x400000之类的指令是没有意义的。因为我们不确定当前用户地址空间就是我们的目标进程地址空间。因此我们首先要切换到我们想查看的进程上下文。之后才能查看它私有的地址空间。如果不按这个规定的话,有可能得出的结果是很多?????
[plain] view plain?
- 0: kd> .process 81f8e4b8
- Implicit process is now 81f8e4b8
- WARNING: .cache forcedecodeuser is not enabled
- 0: kd> dd 0x400000
- 00400000 00905a4d 00000003 00000004 0000ffff
- 00400010 000000b8 00000000 00000040 00000000
- 00400020 00000000 00000000 00000000 00000000
- 00400030 00000000 00000000 00000000 00000100
- 00400040 0eba1f0e cd09b400 4c01b821 685421cd
- 00400050 70207369 72676f72 63206d61 6f6e6e61
- 00400060 65622074 6e757220 206e6920 20534f44
- 00400070 65646f6d 0a0d0d2e 00000024 00000000
- 0: kd> .process
- Implicit process is now 8055d0c0
- 0: kd> dd 0x400000
- 00400000 ???????? ???????? ???????? ????????
- 00400010 ???????? ???????? ???????? ????????
- 00400020 ???????? ???????? ???????? ????????
- 00400030 ???????? ???????? ???????? ????????
- 00400040 ???????? ???????? ???????? ????????
- 00400050 ???????? ???????? ???????? ????????
- 00400060 ???????? ???????? ???????? ????????
- 00400070 ???????? ???????? ???????? ????????
3.列出进程已经加载的dll
切换到目标进程上下文之后,我们可以使用!peb或者!dlls命令列出进程已经加载的dll。进程加载的dll列表保存在peb中,所以这两条命令都能很好的工作。只是显示格式不同罢了。比如我要查看我本机的TPAutoConnSvc.exe
[plain] view plain?
- 0: kd> !peb
- PEB at 7ffdf000
- InheritedAddressSpace: No
- ReadImageFileExecOptions: No
- BeingDebugged: No
- ImageBaseAddress: 00400000
- Ldr 00251e90
- Ldr.Initialized: Yes
- Ldr.InInitializationOrderModuleList: 00251f28 . 002533c8
- Ldr.InLoadOrderModuleList: 00251ec0 . 00253550
- Ldr.InMemoryOrderModuleList: 00251ec8 . 00253558
- Base TimeStamp Module
- 400000 4a76ebe1 Aug 03 21:53:37 2009 C:\Program Files\VMware\VMware Tools\TPAutoConnSvc.exe
- 7c920000 4802bdc5 Apr 14 10:13:25 2008 C:\WINDOWS\system32\ntdll.dll
- 7c800000 4802bdc6 Apr 14 10:13:26 2008 C:\WINDOWS\system32\kernel32.dll
- 41000000 4a76ebcf Aug 03 21:53:19 2009 C:\WINDOWS\system32\TPSvc.dll
- 695d0000 4802bd9d Apr 14 10:12:45 2008 C:\WINDOWS\System32\Wbem\framedyn.dll
- 77be0000 4802be3f Apr 14 10:15:27 2008 C:\WINDOWS\system32\msvcrt.dll
- 77da0000 4802bd89 Apr 14 10:12:25 2008 C:\WINDOWS\system32\ADVAPI32.dll
- 77e50000 4802bdae Apr 14 10:13:02 2008 C:\WINDOWS\system32\RPCRT4.dll
- 77fc0000 4802bdc1 Apr 14 10:13:21 2008 C:\WINDOWS\system32\Secur32.dll
- 77d10000 4802bdbd Apr 14 10:13:17 2008 C:\WINDOWS\system32\USER32.dll
- 77ef0000 4802bd81 Apr 14 10:12:17 2008 C:\WINDOWS\system32\GDI32.dll
- 770f0000 4802bdbd Apr 14 10:13:17 2008 C:\WINDOWS\system32\OLEAUT32.dll
- 76990000 4802bdbc Apr 14 10:13:16 2008 C:\WINDOWS\system32\ole32.dll
- 77bd0000 4802bdbf Apr 14 10:13:19 2008 C:\WINDOWS\system32\VERSION.dll
- 759d0000 4802bdbe Apr 14 10:13:18 2008 C:\WINDOWS\system32\USERENV.dll
- 76320000 4802bda2 Apr 14 10:12:50 2008 C:\WINDOWS\system32\comdlg32.dll
4.查看进程的内存映射情况
虚拟地址描述符(Virtual Adderss Descriptor)包含一个进程中用户空间已分配地址信息。Vad能够帮助我们快速的定位隐藏或者注入的代码。但是首先我们需要找到Vadroot。不过这个在EPROCESS中已经明确指出了。直接把Vadroot的地址作为参数,使用!vad命令即可得出进程用户空间已分配的内存信息。
[plain] view plain?
- 0: kd> !vad 81f85208
- VAD level start end commit
- 82060128 ( 4) 10 10 1 Private READWRITE
- 81ae0760 ( 5) 20 20 1 Private READWRITE
- 81ae95b0 ( 3) 30 12f 4 Private READWRITE
- 81ed7a20 ( 5) 130 132 0 Mapped READONLY Pagefile-backed section
- 81ffebc8 ( 4) 140 141 0 Mapped READONLY Pagefile-backed section
- 81f89578 ( 6) 150 24f 24 Private READWRITE
- 82012798 ( 5) 250 25f 6 Private READWRITE
- 82003408 ( 7) 260 26f 0 Mapped READWRITE Pagefile-backed section
- 82002e98 ( 6) 270 285 0 Mapped READONLY \WINDOWS\system32\unicode.nls
- 81ae9370 ( 8) 290 2d0 0 Mapped READONLY \WINDOWS\system32\locale.nls
- 81c050d8 ( 7) 2e0 320 0 Mapped READONLY \WINDOWS\system32\sortkey.nls
- 81ed79b8 ( 9) 330 335 0 Mapped READONLY \WINDOWS\system32\sorttbls.nls
- 81ed7b58 ( 8) 340 380 0 Mapped READONLY Pagefile-backed section
- 81c03260 ( 9) 390 39f 5 Private READWRITE
- 81c05758 (10) 3a0 3a2 0 Mapped READONLY \WINDOWS\system32\ctype.nls
- 81e7f460 (11) 3b0 3bf 8 Private READWRITE
- 81e1d168 (12) 3c0 3c0 1 Private READWRITE
- 81bd5bd0 (13) 3d0 3d0 1 Private READWRITE
- 81f8e868 (15) 3e0 3e1 0 Mapped READONLY Pagefile-backed section
- 81e1b0e8 (14) 3f0 3f1 0 Mapped READONLY Pagefile-backed section
- 81e43cd0 ( 2) 400 440 13 Mapped Exe EXECUTE_WRITECOPY \Program Files\VMware\VMware Tools\TPAutoConnSvc.exe
- [...]
- 81bdc0c8 ( 5) 9e0 9fb 23 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\TPVMW32.dll
- 81e18b28 ( 4) a00 a0f 4 Private READWRITE
- 81f85208 ( 0) a10 a10 0 Mapped READWRITE Pagefile-backed section
- 81e840b8 ( 5) a20 a23 0 Mapped READWRITE Pagefile-backed section
- 81e17178 ( 4) a30 b2f 10 Private READWRITE
- 81e19128 ( 6) b30 c2f 3 Private READWRITE
- 81bd02b0 ( 5) c30 d2f 5 Private READWRITE
- 82003a28 ( 7) d30 e2f 2 Private READWRITE
- 81e17988 ( 6) e30 e6f 3 Private READWRITE
- 81e1a548 ( 7) e70 e7f 12 Private READWRITE
- 81adfc70 ( 8) e80 e8d 0 Mapped READWRITE Pagefile-backed section
- 81a968e0 ( 9) e90 e90 1 Private READWRITE
- <span style="color:#330033;">81ed5e50 ( 3) 10000 10023 10 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\tprdpw32.dll</span>
- 81e7d200 ( 2) 41000 41078 25 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\TPSvc.dll
- 81f86980 ( 5) 5adc0 5adf6 2 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\uxtheme.dll
- [...]
- <span style="color:#ff6666;">81ed5220 ( 2) 7c920 7c9b2 5 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\ntdll.dll</span>
- [...]
如果要计算出每个vad节点的虚拟地址,只需要将开始地址和结束地址乘以0x1000即可。我们来看看0x81ed5220处的vad,他的位于0x7c920000和0x7c9b2000这个区间段。并且映射了可执行文件tprdpw32.dll。用lm查看一下这个地址。
[plain] view plain?
- 0: kd> lm vt a 0x7c920000
- start end module name
- 7c920000 7c9b3000 ntdll
- Loaded symbol image file: ntdll.dll
- Image path: ntdll.dll
- Image name: ntdll.dll
- Timestamp: Mon Apr 14 10:13:25 2008 (4802BDC5)
- CheckSum: 00097CB7
- ImageSize: 00093000
- Translations: 0000.04b0 0000.04e4 0409.04b0 0409.04e4
5.查看进程句柄表
使用!handle命令可以列出当前进程所有已经打开的句柄信息。!handle命令的第一个参数是句柄值(如果是0则列出所有句柄),第二个参数是所需信息的详细程度(跟!process一样)。如下命令列出了当前进程上下文中所有的句柄信息
[plain] view plain?
- 0: kd> !handle 0 0
- PROCESS 81f8e4b8 SessionId: 0 Cid: 0134 Peb: 7ffdf000 ParentCid: 02a8
- DirBase: 02b802a0 ObjectTable: e1b49790 HandleCount: 101.
- Image: TPAutoConnSvc.exe
- Handle table at e1b0c000 with 101 entries in use
- 0004: Object: e1009540 GrantedAccess: 000f0003 Entry: e1b0c008
- Object: e1009540 Type: (821b3730) KeyedEvent
- ObjectHeader: e1009528 (old version)
- HandleCount: 28 PointerCount: 29
- Directory Object: e1009f58 Name: CritSecOutOfMemoryEvent
- 0008: Object: e14d00d8 GrantedAccess: 00000003 Entry: e1b0c010
- Object: e14d00d8 Type: (821b7040) Directory
- ObjectHeader: e14d00c0 (old version)
- HandleCount: 28 PointerCount: 64
- Directory Object: e1003350 Name: KnownDlls
- 000c: Object: 81f88b38 GrantedAccess: 00100020 (Inherit) Entry: e1b0c018
- Object: 81f88b38 Type: (821e9900) File
- ObjectHeader: 81f88b20 (old version)
- HandleCount: 1 PointerCount: 1
- Directory Object: 00000000 Name: \WINDOWS\system32 {HarddiskVolume1}
- [...]
其中type指出了句柄关联的对象的类型,object字段表明了对象的地址。handlecount和pointercount分别记录了句柄引用次数和指针引用次数(ObrefrenceObjectByHandle、ByName)。
RING3下断
首先切换到用户环境,.process命令的功能是在内核态调试时,切换进程CONTEXT。执行如下命令:
1:使用!process 0 0 获取用户空间的所有的进程的信息
kd> !process 0 0 explorer.exe
PROCESS 81fff020 SessionId: 0 Cid: 0600 Peb: 7ffde000 ParentCid: 05f0
DirBase: 048401c0 ObjectTable: e19d5188 HandleCount: 371.
Image: explorer.exe
2:使用.process /p + 你需要断的应用程序的EProcess地址切换到应用程序的地址空间
kd> .process /p 81fff020
3:重新加载user PDB文件
kd> .reload /f /user
4:使用非侵入式的切换进程空间
kd> .process /i /p 81fff020
5:下应用层断点。
jpg 改成 doc