windbg学习21(!handle和!cs)

1.查看句柄信息!handle

!handle 扩展显示目标系统中一个或所有进程拥有的句柄的信息

0:001> !handle
Handle 4
  Type         	Directory
Handle 8
  Type         	File
Handle c
  Type         	File
Handle 10
  Type         	Key
Handle 14
  Type         	ALPC Port
Handle 18
  Type         	Mutant
Handle 1c
  Type         	Key
Handle 20
  Type         	Event
Handle 24
  Type         	Key
Handle 2c
  Type         	Event
Handle 30
  Type         	WindowStation
Handle 34
  Type         	Desktop
Handle 38
  Type         	WindowStation
Handle 3c
  Type         	File
Handle 84
  Type         	Event
Handle 88
  Type         	Event
Handle 8c
  Type         	Event
Handle 90
  Type         	Event
Handle 94
  Type         	Event
Handle 98
  Type         	Event
Handle 9c
  Type         	Directory
Handle a0
  Type         	Event
Handle a4
  Type         	Event
Handle a8
  Type         	File
Handle ac
  Type         	File
Handle b0
  Type         	Event
Handle b4
  Type         	Mutant
Handle b8
  Type         	Event
Handle bc
  Type         	Mutant
Handle c0
  Type         	Section
Handle c4
  Type         	Section
Handle c8
  Type         	Mutant
Handle cc
  Type         	Section
Handle d0
  Type         	Key
Handle d4
  Type         	Key
Handle d8
  Type         	Key
Handle dc
  Type         	Key
Handle e0
  Type         	Key
Handle e4
  Type         	File
Handle e8
  Type         	Section
Handle f4
  Type         	File
Handle f8
  Type         	ALPC Port
Handle fc
  Type         	Mutant
Handle 100
  Type         	Section
Handle 104
  Type         	File
Handle 10c
  Type         	File
Handle 110
  Type         	Key
Handle 114
  Type         	Key
Handle 11c
  Type         	Key
49 Handles
Type           	Count
None           	2
Event          	12
Section        	5
File           	9
Directory      	2
Mutant         	5
WindowStation  	2
Key            	11
Desktop        	1

我们注意到最下面这一部分统计了各种类型句柄的各自数目

要得到某个句柄更详细的信息,可以用这个句柄做为参数,再用'f'表示显示最详细的信息:

0:001> !handle 4 f
Handle 4
  Type         	Directory
  Attributes   	0x10
  GrantedAccess	0x3:
         None
         Query,Traverse
  HandleCount  	60
  PointerCount 	99
  Name         	\KnownDlls
  No Object Specific Information available
0:001> !handle 84 f
Handle 84
  Type         	Event
  Attributes   	0
  GrantedAccess	0x1f0003:
         Delete,ReadControl,WriteDac,WriteOwner,Synch
         QueryState,ModifyState
  HandleCount  	2
  PointerCount 	3
  Name         	<none>
  Object Specific Information
    Event Type Manual Reset
    Event is Waiting

重新写一个代码测试Mutex:

0:001> !handle xx f
Handle 78
  Type         	Mutant
  Attributes   	0
  GrantedAccess	0x1f0001:
         Delete,ReadControl,WriteDac,WriteOwner,Synch
         QueryState
  HandleCount  	2
  PointerCount 	3
  Name         	<none>
  Object Specific Information
    Mutex is Free
0:001> !handle xx f
Handle e0
  Type         	Mutant
  Attributes   	0
  GrantedAccess	0x1f0001:
         Delete,ReadControl,WriteDac,WriteOwner,Synch
         QueryState
  HandleCount  	2
  PointerCount 	3
  Name         	<none>
  Object Specific Information
    Mutex is Owned

再写个代码验证信号量:

0:001> !handle dc f
Handle dc
  Type         	Semaphore
  Attributes   	0
  GrantedAccess	0x1f0003:
         Delete,ReadControl,WriteDac,WriteOwner,Synch
         QueryState,ModifyState
  HandleCount  	2
  PointerCount 	3
  Name         	<none>
  Object Specific Information
    Semaphore Count 4
    Semaphore Limit 5

可以看到,上面给出了这个句丙的类型,属性,访问权限以及句柄计数,我们甚至看到这个事件是Manual Reset(人工重置事件)如果是Event Type Auto Reset(自动重置事件),状态是Waiting(未触发),如果是Event is set表示已触发状态,如果Mutex is free 表示互斥量已有信号,如果Mutex is owned表示互斥量已被占用,对于信号量,Semaphore Count 表示可用的信号量,Limit表示总数

我们不知道!handle具体用法,可以使用-?来查询

0:001> !handle -?
!handle [<handle>] [<flags>] [<type>]
  <handle> - Handle to get information about
             0 or -1 means all handles
  <flags> - Output control flags
            1   - Get type information (default)
            2   - Get basic information
            4   - Get name information
            8   - Get object specific info (where available)
  <type> - Limit query to handles of the given type
Display information about open handles

当handle很多时,我们也许只想知道所有互斥量的信息:

0:001> !handle 0 1 Mutant
Handle 78
  Type         	Mutant
Handle e0
  Type         	Mutant
Handle ec
  Type         	Mutant
3 handles of type Mutant

1对应flags,至于名字Mutant可以参看windbg帮助说明:

Specifies the type of handle that you want to examine. Only handles that match this type are displayed.TypeName is case sensitive. Valid types include Event, Section, File, Port, Directory, SymbolicLink, Mutant, WindowStation, Semaphore, Key, Token, Process, Thread, Desktop, IoCompletion, Timer, Job, and WaitablePort.

上面红色标明为区分大小写,怀疑:下面明显是成功的!

0:001> !handle 0 3 mutanT
Handle 78
  Type         	Mutant
  Attributes   	0
  GrantedAccess	0x1f0001:
         Delete,ReadControl,WriteDac,WriteOwner,Synch
         QueryState
  HandleCount  	2
  PointerCount 	3
Handle e0
  Type         	Mutant
  Attributes   	0
  GrantedAccess	0x1f0001:
         Delete,ReadControl,WriteDac,WriteOwner,Synch
         QueryState
  HandleCount  	2
  PointerCount 	3
Handle ec
  Type         	Mutant
  Attributes   	0
  GrantedAccess	0x100000:
         Synch
         None
  HandleCount  	13
  PointerCount 	15
3 handles of type Mutant


 

2.临界区 (!cs)

底层的临界区数据结构为_RTL_CRITICAL_SECTION

反正我经常记不住,所以可以使用通配符先查找一下:

0:001> dt ntdll!_RTL_CR*
          ntdll!_RTL_CRITICAL_SECTION
          ntdll!_RTL_CRITICAL_SECTION_DEBUG
0:001> dt ntdll!_RTL_CRITICAL_SECTION
   +0x000 DebugInfo        : Ptr32 _RTL_CRITICAL_SECTION_DEBUG
   +0x004 LockCount        : Int4B
   +0x008 RecursionCount   : Int4B
   +0x00c OwningThread     : Ptr32 Void
   +0x010 LockSemaphore    : Ptr32 Void
   +0x014 SpinCount        : Uint4B


LockCount默认为-1,如果>=0,则表示有线程进入到临界区,要找出有多少线程正在等待进入临界区,可以:

正在等待的线程数量=LockCount - RecursionCount + 1

RecursionCount:表示同一个线程进入到临界区多少次,默认为0

OwningThread:如果有线程进入到临界区,这是进入临界区的线程ID

LockSemaphore:这是一个自动重置事件,当线程试图进入一个其他线程占用的临界区时,将会创建这个事件

SpinCount:自旋锁的次数

进一步看DebugInfo结构:

0:001> dt _RTL_CRITICAL_SECTION_DEBUG
ntdll!_RTL_CRITICAL_SECTION_DEBUG
   +0x000 Type             : Uint2B
   +0x002 CreatorBackTraceIndex : Uint2B
   +0x004 CriticalSection  : Ptr32 _RTL_CRITICAL_SECTION
   +0x008 ProcessLocksList : _LIST_ENTRY
   +0x010 EntryCount       : Uint4B
   +0x014 ContentionCount  : Uint4B
   +0x018 Flags            : Uint4B
   +0x01c CreatorBackTraceIndexHigh : Uint2B
   +0x01e SpareUSHORT      : Uint2B

CriticalSection:在这个域上包含敢一个指针指向与这个结构相关的临界区

ProcessLocksList:任何进程在操作系统中都将维护一张链表,其中包含了在这个进程中所有处于活跃状态的临界区,你可以通过这个节点中FLINK和BLINK来遍历进程中的临界区链表

EntryCount:每当线程尝试进入一个已经被其他线程拥有的临界区并由此进入到等待状态,这个域的值都会被加1

!cs 扩展显示一个或多个临界区(critical section)或者整个临界区树
!cs startAddr endAddr

0:001> !cs 0x001af1f0 00400000
-----------------------------------------
DebugInfo          = 0x00197a48
Critical section   = 0x003a0138 (+0x3A0138)
NOT LOCKED
LockSemaphore      = 0x0
SpinCount          = 0x00000fa0
-----------------------------------------
DebugInfo          = 0x001aed68
Critical section   = 0x001af5c0 (+0x1AF5C0)
NOT LOCKED
LockSemaphore      = 0x0
SpinCount          = 0x00000000
-----------------------------------------
DebugInfo          = 0x001aedb8
Critical section   = 0x001afd34 (+0x1AFD34)
NOT LOCKED
LockSemaphore      = 0x0
SpinCount          = 0x00000000

!cs -l仅显示锁定的临界区



 



 

原文地址:https://www.cnblogs.com/hgy413/p/3693446.html