05 等待链表和调度链表

进程断链 : 程序可以正常运行,原因是CPU执行与调度是基于线程的,进程断链只是影响一些遍历系统进程的API,并不会影响程序执行
线程断链 :断链后在Windbg或者OD中无法看到被断掉的线程,但并不影响其执行,原因是CPU调度线程的时候压根不用这个链表

** 线程有3种状态:就绪(ready)、等待(wait)、运行(running)**

运行的线程 : 存储在KPCR中
就绪和等待的线程 : 33个链表中(一个等待链表,32个就绪链表)这些链表都使用了_KTHREAD + 0x060这个位置。这个一个位置,两个名字,如下所示。也就是说,线程在某一时刻,只能属于其中一个圈

   +0x060 WaitListEntry    : _LIST_ENTRY
   +0x060 SwapListEntry    : _SINGLE_LIST_ENTRY

等待链表

线程调用了Sleep或者WaitForSingleObject等函数时,就挂到一个链表之中,它是等待链表
等待链表的有一个全局变量地址 :


kd> dd KiWaitListHead
8055b008  89ab8080 89a77520 00000010 00000000
8055b018  b6de6b92 a787ea13 01000013 ffdff980
8055b028  ffdff980 804dd2cd 00000000 000018a3
8055b038  00000000 ffdff9c0 8055b040 8055b040
8055b048  00000000 00000000 8055b050 8055b050
8055b058  00000000 00000000 00000000 89be8b30

通过这个地址可以访问到线程


kd> dt _ETHREAD 0x89ab8080-0x60
ntdll!_ETHREAD
   +0x000 Tcb              : _KTHREAD
   +0x1c0 CreateTime       : _LARGE_INTEGER 0x0ecc10bb`90f64850
   +0x1c0 NestedFaultCount : 0y00
   +0x1c0 ApcNeeded        : 0y0
   +0x1c8 ExitTime         : _LARGE_INTEGER 0x89ab81e8`89ab81e8
   +0x1c8 LpcReplyChain    : _LIST_ENTRY [ 0x89ab81e8 - 0x89ab81e8 ]
   +0x1c8 KeyedWaitChain   : _LIST_ENTRY [ 0x89ab81e8 - 0x89ab81e8 ]
   +0x1d0 ExitStatus       : 0n0
   +0x1d0 OfsChain         : (null) 
   +0x1d4 PostBlockList    : _LIST_ENTRY [ 0x89ab81f4 - 0x89ab81f4 ]
   +0x1dc TerminationPort  : (null) 
   +0x1dc ReaperLink       : (null) 
   +0x1dc KeyedWaitValue   : (null) 
   +0x1e0 ActiveTimerListLock : 0
   +0x1e4 ActiveTimerListHead : _LIST_ENTRY [ 0x89ab8204 - 0x89ab8204 ]
   +0x1ec Cid              : _CLIENT_ID
   +0x1f4 LpcReplySemaphore : _KSEMAPHORE
   +0x1f4 KeyedWaitSemaphore : _KSEMAPHORE
   +0x208 LpcReplyMessage  : (null) 
   +0x208 LpcWaitingOnPort : (null) 
   +0x20c ImpersonationInfo : (null) 
   +0x210 IrpList          : _LIST_ENTRY [ 0x89ab8230 - 0x89ab8230 ]
   +0x218 TopLevelIrp      : 0
   +0x21c DeviceToVerify   : (null) 
   +0x220 ThreadsProcess   : 0x89bf19c8 _EPROCESS
   +0x224 StartAddress     : 0xb7db6ce4 Void
   +0x228 Win32StartAddress : (null) 
   +0x228 LpcReceivedMessageId : 0
   +0x22c ThreadListEntry  : _LIST_ENTRY [ 0x896fa24c - 0x896d524c ]
   +0x234 RundownProtect   : _EX_RUNDOWN_REF
   +0x238 ThreadLock       : _EX_PUSH_LOCK
   +0x23c LpcReplyMessageId : 0
   +0x240 ReadClusterSize  : 7
   +0x244 GrantedAccess    : 0x1f03ff
   +0x248 CrossThreadFlags : 0x30
   +0x248 Terminated       : 0y0
   +0x248 DeadThread       : 0y0
   +0x248 HideFromDebugger : 0y0
   +0x248 ActiveImpersonationInfo : 0y0
   +0x248 SystemThread     : 0y1
   +0x248 HardErrorsAreDisabled : 0y1
   +0x248 BreakOnTermination : 0y0
   +0x248 SkipCreationMsg  : 0y0
   +0x248 SkipTerminationMsg : 0y0
   +0x24c SameThreadPassiveFlags : 0
   +0x24c ActiveExWorker   : 0y0
   +0x24c ExWorkerCanWaitUser : 0y0
   +0x24c MemoryMaker      : 0y0
   +0x250 SameThreadApcFlags : 0
   +0x250 LpcReceivedMsgIdValid : 0y0
   +0x250 LpcExitThreadCalled : 0y0
   +0x250 AddressSpaceOwner : 0y0
   +0x254 ForwardClusterOnly : 0 ''
   +0x255 DisablePageFaultClustering : 0 ''


进一步可以访问到进程

kd> dt _EPROCESS 0x89bf19c8 
ntdll!_EPROCESS
   +0x000 Pcb              : _KPROCESS
   +0x06c ProcessLock      : _EX_PUSH_LOCK
   +0x070 CreateTime       : _LARGE_INTEGER 0x0
   +0x078 ExitTime         : _LARGE_INTEGER 0x0
   +0x080 RundownProtect   : _EX_RUNDOWN_REF
   +0x084 UniqueProcessId  : 0x00000004 Void
   +0x088 ActiveProcessLinks : _LIST_ENTRY [ 0x899180a8 - 0x80562358 ]
   +0x090 QuotaUsage       : [3] 0
   +0x09c QuotaPeak        : [3] 0
   +0x0a8 CommitCharge     : 7
   +0x0ac PeakVirtualSize  : 0x28b000
   +0x0b0 VirtualSize      : 0x1c7000
   +0x0b4 SessionProcessLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
   +0x0bc DebugPort        : (null) 
   +0x0c0 ExceptionPort    : (null) 
   +0x0c4 ObjectTable      : 0xe1000d10 _HANDLE_TABLE
   +0x0c8 Token            : _EX_FAST_REF
   +0x0cc WorkingSetLock   : _FAST_MUTEX
   +0x0ec WorkingSetPage   : 0
   +0x0f0 AddressCreationLock : _FAST_MUTEX
   +0x110 HyperSpaceLock   : 0
   +0x114 ForkInProgress   : (null) 
   +0x118 HardwareTrigger  : 0
   +0x11c VadRoot          : 0x89c25078 Void
   +0x120 VadHint          : 0x89c25078 Void
   +0x124 CloneRoot        : (null) 
   +0x128 NumberOfPrivatePages : 3
   +0x12c NumberOfLockedPages : 0
   +0x130 Win32Process     : (null) 
   +0x134 Job              : (null) 
   +0x138 SectionObject    : (null) 
   +0x13c SectionBaseAddress : (null) 
   +0x140 QuotaBlock       : 0x80562400 _EPROCESS_QUOTA_BLOCK
   +0x144 WorkingSetWatch  : (null) 
   +0x148 Win32WindowStation : (null) 
   +0x14c InheritedFromUniqueProcessId : (null) 
   +0x150 LdtInformation   : (null) 
   +0x154 VadFreeHint      : (null) 
   +0x158 VdmObjects       : (null) 
   +0x15c DeviceMap        : 0xe10087c0 Void
   +0x160 PhysicalVadList  : _LIST_ENTRY [ 0x89bf1b28 - 0x89bf1b28 ]
   +0x168 PageDirectoryPte : _HARDWARE_PTE_X86
   +0x168 Filler           : 0
   +0x170 Session          : (null) 
   +0x174 ImageFileName    : [16]  "System"
   +0x184 JobLinks         : _LIST_ENTRY [ 0x0 - 0x0 ]
   +0x18c LockedPagesList  : (null) 
   +0x190 ThreadListHead   : _LIST_ENTRY [ 0x89bf197c - 0x899bffd4 ]
   +0x198 SecurityPort     : 0xe1964988 Void
   +0x19c PaeTop           : (null) 
   +0x1a0 ActiveThreads    : 0x36
   +0x1a4 GrantedAccess    : 0x1f0fff
   +0x1a8 DefaultHardErrorProcessing : 1
   +0x1ac LastThreadExitStatus : 0n0
   +0x1b0 Peb              : (null) 
   +0x1b4 PrefetchTrace    : _EX_FAST_REF
   +0x1b8 ReadOperationCount : _LARGE_INTEGER 0x64
   +0x1c0 WriteOperationCount : _LARGE_INTEGER 0x6f
   +0x1c8 OtherOperationCount : _LARGE_INTEGER 0xf0e
   +0x1d0 ReadTransferCount : _LARGE_INTEGER 0x777c8
   +0x1d8 WriteTransferCount : _LARGE_INTEGER 0x5a2c8
   +0x1e0 OtherTransferCount : _LARGE_INTEGER 0x48db5
   +0x1e8 CommitChargeLimit : 0
   +0x1ec CommitChargePeak : 0x1cc
   +0x1f0 AweInfo          : (null) 
   +0x1f4 SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO
   +0x1f8 Vm               : _MMSUPPORT
   +0x238 LastFaultCount   : 0
   +0x23c ModifiedPageCount : 0x66d
   +0x240 NumberOfVads     : 4
   +0x244 JobStatus        : 0
   +0x248 Flags            : 0x40000
   +0x248 CreateReported   : 0y0
   +0x248 NoDebugInherit   : 0y0
   +0x248 ProcessExiting   : 0y0
   +0x248 ProcessDelete    : 0y0
   +0x248 Wow64SplitPages  : 0y0
   +0x248 VmDeleted        : 0y0
   +0x248 OutswapEnabled   : 0y0
   +0x248 Outswapped       : 0y0
   +0x248 ForkFailed       : 0y0
   +0x248 HasPhysicalVad   : 0y0
   +0x248 AddressSpaceInitialized : 0y00
   +0x248 SetTimerResolution : 0y0
   +0x248 BreakOnTermination : 0y0
   +0x248 SessionCreationUnderway : 0y0
   +0x248 WriteWatch       : 0y0
   +0x248 ProcessInSession : 0y0
   +0x248 OverrideAddressSpace : 0y0
   +0x248 HasAddressSpace  : 0y1
   +0x248 LaunchPrefetched : 0y0
   +0x248 InjectInpageErrors : 0y0
   +0x248 VmTopDown        : 0y0
   +0x248 Unused3          : 0y0
   +0x248 Unused4          : 0y0
   +0x248 VdmAllowed       : 0y0
   +0x248 Unused           : 0y00000 (0)
   +0x248 Unused1          : 0y0
   +0x248 Unused2          : 0y0
   +0x24c ExitStatus       : 0n259
   +0x250 NextPageColor    : 0x583d
   +0x252 SubSystemMinorVersion : 0 ''
   +0x253 SubSystemMajorVersion : 0 ''
   +0x252 SubSystemVersion : 0
   +0x254 PriorityClass    : 0x2 ''
   +0x255 WorkingSetAcquiredUnsafe : 0 ''
   +0x258 Cookie           : 0

调度链表

优先级是0-31,0为最低优先级,31为最高,默认优先级一般是8
改变优先级就是从一个圈里面卸下来挂到另外一个圈上
只有一个CPU但有10个线程在运行,那么某一时刻,正在运行的线程在KPCR中,其他9个在这32个圈中

//既然有32个链表,就有32个链表头

kd> dd KiDispatcherReadyListHead 
8055baa0  8055baa0 8055baa0 8055baa8 8055baa8
8055bab0  8055bab0 8055bab0 8055bab8 8055bab8
8055bac0  8055bac0 8055bac0 8055bac8 8055bac8
8055bad0  8055bad0 8055bad0 8055bad8 8055bad8
8055bae0  8055bae0 8055bae0 8055bae8 8055bae8
8055baf0  8055baf0 8055baf0 8055baf8 8055baf8
8055bb00  8055bb00 8055bb00 8055bb08 8055bb08
8055bb10  8055bb10 8055bb10 8055bb18 8055bb18

现在每个成员的地址都和当前地址一样,前结点和后结点一样,这就是说明当前没有在调度链表的线程。这是因为我们中断操作系统调试输入命令的时候,它会把操作系统的所有线程挂起,所以都在等待链表中。如果你真把线程结构体从上面几个摘掉的话,这线程真的就跑不起来了。由此可知,线程是永远没法隐藏的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值