windbg学习21(!handle和!cs)

1.查看句柄信息!handle

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

[cpp] view plaincopy

  1. 0:001> !handle  
  2. Handle 4  
  3.   Type          Directory  
  4. Handle 8  
  5.   Type          File  
  6. Handle c  
  7.   Type          File  
  8. Handle 10  
  9.   Type          Key  
  10. Handle 14  
  11.   Type          ALPC Port  
  12. Handle 18  
  13.   Type          Mutant  
  14. Handle 1c  
  15.   Type          Key  
  16. Handle 20  
  17.   Type          Event  
  18. Handle 24  
  19.   Type          Key  
  20. Handle 2c  
  21.   Type          Event  
  22. Handle 30  
  23.   Type          WindowStation  
  24. Handle 34  
  25.   Type          Desktop  
  26. Handle 38  
  27.   Type          WindowStation  
  28. Handle 3c  
  29.   Type          File  
  30. Handle 84  
  31.   Type          Event  
  32. Handle 88  
  33.   Type          Event  
  34. Handle 8c  
  35.   Type          Event  
  36. Handle 90  
  37.   Type          Event  
  38. Handle 94  
  39.   Type          Event  
  40. Handle 98  
  41.   Type          Event  
  42. Handle 9c  
  43.   Type          Directory  
  44. Handle a0  
  45.   Type          Event  
  46. Handle a4  
  47.   Type          Event  
  48. Handle a8  
  49.   Type          File  
  50. Handle ac  
  51.   Type          File  
  52. Handle b0  
  53.   Type          Event  
  54. Handle b4  
  55.   Type          Mutant  
  56. Handle b8  
  57.   Type          Event  
  58. Handle bc  
  59.   Type          Mutant  
  60. Handle c0  
  61.   Type          Section  
  62. Handle c4  
  63.   Type          Section  
  64. Handle c8  
  65.   Type          Mutant  
  66. Handle cc  
  67.   Type          Section  
  68. Handle d0  
  69.   Type          Key  
  70. Handle d4  
  71.   Type          Key  
  72. Handle d8  
  73.   Type          Key  
  74. Handle dc  
  75.   Type          Key  
  76. Handle e0  
  77.   Type          Key  
  78. Handle e4  
  79.   Type          File  
  80. Handle e8  
  81.   Type          Section  
  82. Handle f4  
  83.   Type          File  
  84. Handle f8  
  85.   Type          ALPC Port  
  86. Handle fc  
  87.   Type          Mutant  
  88. Handle 100  
  89.   Type          Section  
  90. Handle 104  
  91.   Type          File  
  92. Handle 10c  
  93.   Type          File  
  94. Handle 110  
  95.   Type          Key  
  96. Handle 114  
  97.   Type          Key  
  98. Handle 11c  
  99.   Type          Key  
  100. 49 Handles  
  101. Type            Count  
  102. None            2  
  103. Event           12  
  104. Section         5  
  105. File            9  
  106. Directory       2  
  107. Mutant          5  
  108. WindowStation   2  
  109. Key             11  
  110. Desktop         1  

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

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

[cpp] view plaincopy

  1. 0:001> !handle 4 f  
  2. Handle 4  
  3.   Type          Directory  
  4.   Attributes    0x10  
  5.   GrantedAccess 0x3:  
  6.          None  
  7.          Query,Traverse  
  8.   HandleCount   60  
  9.   PointerCount  99  
  10.   Name          \KnownDlls  
  11.   No Object Specific Information available  

[cpp] view plaincopy

  1. 0:001> !handle 84 f  
  2. Handle 84  
  3.   Type          Event  
  4.   Attributes    0  
  5.   GrantedAccess 0x1f0003:  
  6.          Delete,ReadControl,WriteDac,WriteOwner,Synch  
  7.          QueryState,ModifyState  
  8.   HandleCount   2  
  9.   PointerCount  3  
  10.   Name          <none>  
  11.   Object Specific Information  
  12.     Event Type Manual Reset  
  13.     Event is Waiting  

重新写一个代码测试Mutex:

[cpp] view plaincopy

  1. 0:001> !handle xx f  
  2. Handle 78  
  3.   Type          Mutant  
  4.   Attributes    0  
  5.   GrantedAccess 0x1f0001:  
  6.          Delete,ReadControl,WriteDac,WriteOwner,Synch  
  7.          QueryState  
  8.   HandleCount   2  
  9.   PointerCount  3  
  10.   Name          <none>  
  11.   Object Specific Information  
  12.     Mutex is Free  
  13. 0:001> !handle xx f  
  14. Handle e0  
  15.   Type          Mutant  
  16.   Attributes    0  
  17.   GrantedAccess 0x1f0001:  
  18.          Delete,ReadControl,WriteDac,WriteOwner,Synch  
  19.          QueryState  
  20.   HandleCount   2  
  21.   PointerCount  3  
  22.   Name          <none>  
  23.   Object Specific Information  
  24.     Mutex is Owned  

再写个代码验证信号量:

[cpp] view plaincopy

  1. 0:001> !handle dc f  
  2. Handle dc  
  3.   Type          Semaphore  
  4.   Attributes    0  
  5.   GrantedAccess 0x1f0003:  
  6.          Delete,ReadControl,WriteDac,WriteOwner,Synch  
  7.          QueryState,ModifyState  
  8.   HandleCount   2  
  9.   PointerCount  3  
  10.   Name          <none>  
  11.   Object Specific Information  
  12.     Semaphore Count 4  
  13.     Semaphore Limit 5  

 

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

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

[cpp] view plaincopy

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

 

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

[cpp] view plaincopy

  1. 0:001> !handle 0 1 Mutant  
  2. Handle 78  
  3.   Type          Mutant  
  4. Handle e0  
  5.   Type          Mutant  
  6. Handle ec  
  7.   Type          Mutant  
  8. 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.

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

[cpp] view plaincopy

  1. 0:001> !handle 0 3 mutanT  
  2. Handle 78  
  3.   Type          Mutant  
  4.   Attributes    0  
  5.   GrantedAccess 0x1f0001:  
  6.          Delete,ReadControl,WriteDac,WriteOwner,Synch  
  7.          QueryState  
  8.   HandleCount   2  
  9.   PointerCount  3  
  10. Handle e0  
  11.   Type          Mutant  
  12.   Attributes    0  
  13.   GrantedAccess 0x1f0001:  
  14.          Delete,ReadControl,WriteDac,WriteOwner,Synch  
  15.          QueryState  
  16.   HandleCount   2  
  17.   PointerCount  3  
  18. Handle ec  
  19.   Type          Mutant  
  20.   Attributes    0  
  21.   GrantedAccess 0x100000:  
  22.          Synch  
  23.          None  
  24.   HandleCount   13  
  25.   PointerCount  15  
  26. 3 handles of type Mutant  


 

2.临界区 (!cs)

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

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

[cpp] view plaincopy

  1. 0:001> dt ntdll!_RTL_CR*  
  2.           ntdll!_RTL_CRITICAL_SECTION  
  3.           ntdll!_RTL_CRITICAL_SECTION_DEBUG  
  4. 0:001> dt ntdll!_RTL_CRITICAL_SECTION  
  5.    +0x000 DebugInfo        : Ptr32 _RTL_CRITICAL_SECTION_DEBUG  
  6.    +0x004 LockCount        : Int4B  
  7.    +0x008 RecursionCount   : Int4B  
  8.    +0x00c OwningThread     : Ptr32 Void  
  9.    +0x010 LockSemaphore    : Ptr32 Void  
  10.    +0x014 SpinCount        : Uint4B  


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

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

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

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

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

SpinCount:自旋锁的次数。

进一步看DebugInfo结构:

[cpp] view plaincopy

  1. 0:001> dt _RTL_CRITICAL_SECTION_DEBUG  
  2. ntdll!_RTL_CRITICAL_SECTION_DEBUG  
  3.    +0x000 Type             : Uint2B  
  4.    +0x002 CreatorBackTraceIndex : Uint2B  
  5.    +0x004 CriticalSection  : Ptr32 _RTL_CRITICAL_SECTION  
  6.    +0x008 ProcessLocksList : _LIST_ENTRY  
  7.    +0x010 EntryCount       : Uint4B  
  8.    +0x014 ContentionCount  : Uint4B  
  9.    +0x018 Flags            : Uint4B  
  10.    +0x01c CreatorBackTraceIndexHigh : Uint2B  
  11.    +0x01e SpareUSHORT      : Uint2B  

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

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

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

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

[cpp] view plaincopy

  1. 0:001> !cs 0x001af1f0 00400000  
  2. -----------------------------------------  
  3. DebugInfo          = 0x00197a48  
  4. Critical section   = 0x003a0138 (+0x3A0138)  
  5. NOT LOCKED  
  6. LockSemaphore      = 0x0  
  7. SpinCount          = 0x00000fa0  
  8. -----------------------------------------  
  9. DebugInfo          = 0x001aed68  
  10. Critical section   = 0x001af5c0 (+0x1AF5C0)  
  11. NOT LOCKED  
  12. LockSemaphore      = 0x0  
  13. SpinCount          = 0x00000000  
  14. -----------------------------------------  
  15. DebugInfo          = 0x001aedb8  
  16. Critical section   = 0x001afd34 (+0x1AFD34)  
  17. NOT LOCKED  
  18. LockSemaphore      = 0x0  
  19. SpinCount          = 0x00000000  

 

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值