JIURL玩玩Win2k进程线程篇 ETHREAD

每个线程都有一个 ETHREAD 结构。Win2k Build 2195 中 ETHREAD 结构定义如下 kd> !strct ethread !strct ethread struct _ETHREAD (sizeof=584) +000 struct _KTHREAD Tcb +000 struct _DISPATCHER_HEADER Header +000 byte Type +001 byte Absolute +002 byte Size +003 byte Inserted +004 int32 SignalState +008 struct _LIST_ENTRY WaitListHead +008 struct _LIST_ENTRY *Flink +00c struct _LIST_ENTRY *Blink +010 struct _LIST_ENTRY MutantListHead +010 struct _LIST_ENTRY *Flink +014 struct _LIST_ENTRY *Blink +018 void *InitialStack +01c void *StackLimit +020 void *Teb +024 void *TlsArray +028 void *KernelStack +02c byte DebugActive +02d byte State +02e byte Alerted[2] +030 byte Iopl +031 byte NpxState +032 char Saturation +033 char Priority +034 struct _KAPC_STATE ApcState +034 struct _LIST_ENTRY ApcListHead[2] struct _LIST_ENTRY *Flink struct _LIST_ENTRY *Blink +044 struct _KPROCESS *Process +048 byte KernelApcInProgress +049 byte KernelApcPending +04a byte UserApcPending +04c uint32 ContextSwitches +050 int32 WaitStatus +054 byte WaitIrql +055 char WaitMode +056 byte WaitNext +057 byte WaitReason +058 struct _KWAIT_BLOCK *WaitBlockList +05c struct _LIST_ENTRY WaitListEntry +05c struct _LIST_ENTRY *Flink +060 struct _LIST_ENTRY *Blink +064 uint32 WaitTime +068 char BasePriority +069 byte DecrementCount +06a char PriorityDecrement +06b char Quantum +06c struct _KWAIT_BLOCK WaitBlock[4] struct _LIST_ENTRY WaitListEntry struct _LIST_ENTRY *Flink struct _LIST_ENTRY *Blink struct _KTHREAD *Thread void *Object struct _KWAIT_BLOCK *NextWaitBlock uint16 WaitKey uint16 WaitType +0cc void *LegoData +0d0 uint32 KernelApcDisable +0d4 uint32 UserAffinity +0d8 byte SystemAffinityActive +0d9 byte PowerState +0da byte NpxIrql +0db byte Pad[1] +0dc void *ServiceTable +0e0 struct _KQUEUE *Queue +0e4 uint32 ApcQueueLock +0e8 struct _KTIMER Timer +0e8 struct _DISPATCHER_HEADER Header +0e8 byte Type +0e9 byte Absolute +0ea byte Size +0eb byte Inserted +0ec int32 SignalState +0f0 struct _LIST_ENTRY WaitListHead +0f0 struct _LIST_ENTRY *Flink +0f4 struct _LIST_ENTRY *Blink +0f8 union _ULARGE_INTEGER DueTime +0f8 uint32 LowPart +0fc uint32 HighPart +0f8 struct __unnamed12 u +0f8 uint32 LowPart +0fc uint32 HighPart +0f8 uint64 QuadPart +100 struct _LIST_ENTRY TimerListEntry +100 struct _LIST_ENTRY *Flink +104 struct _LIST_ENTRY *Blink +108 struct _KDPC *Dpc +10c int32 Period +110 struct _LIST_ENTRY QueueListEntry +110 struct _LIST_ENTRY *Flink +114 struct _LIST_ENTRY *Blink +118 uint32 Affinity +11c byte Preempted +11d byte ProcessReadyQueue +11e byte KernelStackResident +11f byte NextProcessor +120 void *CallbackStack +124 void *Win32Thread +128 struct _KTRAP_FRAME *TrapFrame +12c struct _KAPC_STATE *ApcStatePointer[2] +134 char PreviousMode +135 byte EnableStackSwap +136 byte LargeStack +137 byte ResourceIndex +138 uint32 KernelTime +13c uint32 UserTime +140 struct _KAPC_STATE SavedApcState +140 struct _LIST_ENTRY ApcListHead[2] struct _LIST_ENTRY *Flink struct _LIST_ENTRY *Blink +150 struct _KPROCESS *Process +154 byte KernelApcInProgress +155 byte KernelApcPending +156 byte UserApcPending +158 byte Alertable +159 byte ApcStateIndex +15a byte ApcQueueable +15b byte AutoAlignment +15c void *StackBase +160 struct _KAPC SuspendApc +160 int16 Type +162 int16 Size +164 uint32 Spare0 +168 struct _KTHREAD *Thread +16c struct _LIST_ENTRY ApcListEntry +16c struct _LIST_ENTRY *Flink +170 struct _LIST_ENTRY *Blink +174 function *KernelRoutine +178 function *RundownRoutine +17c function *NormalRoutine +180 void *NormalContext +184 void *SystemArgument1 +188 void *SystemArgument2 +18c char ApcStateIndex +18d char ApcMode +18e byte Inserted +190 struct _KSEMAPHORE SuspendSemaphore +190 struct _DISPATCHER_HEADER Header +190 byte Type +191 byte Absolute +192 byte Size +193 byte Inserted +194 int32 SignalState +198 struct _LIST_ENTRY WaitListHead +198 struct _LIST_ENTRY *Flink +19c struct _LIST_ENTRY *Blink +1a0 int32 Limit +1a4 struct _LIST_ENTRY ThreadListEntry +1a4 struct _LIST_ENTRY *Flink +1a8 struct _LIST_ENTRY *Blink +1ac char FreezeCount +1ad char SuspendCount +1ae byte IdealProcessor +1af byte DisableBoost +1b0 union _LARGE_INTEGER CreateTime +1b0 uint32 LowPart +1b4 int32 HighPart +1b0 struct __unnamed3 u +1b0 uint32 LowPart +1b4 int32 HighPart +1b0 int64 QuadPart +1b0 bits0-1 NestedFaultCount +1b0 bits2-2 ApcNeeded +1b8 union _LARGE_INTEGER ExitTime +1b8 uint32 LowPart +1bc int32 HighPart +1b8 struct __unnamed3 u +1b8 uint32 LowPart +1bc int32 HighPart +1b8 int64 QuadPart +1b8 struct _LIST_ENTRY LpcReplyChain +1b8 struct _LIST_ENTRY *Flink +1bc struct _LIST_ENTRY *Blink +1c0 int32 ExitStatus +1c0 void *OfsChain +1c4 struct _LIST_ENTRY PostBlockList +1c4 struct _LIST_ENTRY *Flink +1c8 struct _LIST_ENTRY *Blink +1cc struct _LIST_ENTRY TerminationPortList +1cc struct _LIST_ENTRY *Flink +1d0 struct _LIST_ENTRY *Blink +1d4 uint32 ActiveTimerListLock +1d8 struct _LIST_ENTRY ActiveTimerListHead +1d8 struct _LIST_ENTRY *Flink +1dc struct _LIST_ENTRY *Blink +1e0 struct _CLIENT_ID Cid +1e0 void *UniqueProcess +1e4 void *UniqueThread +1e8 struct _KSEMAPHORE LpcReplySemaphore +1e8 struct _DISPATCHER_HEADER Header +1e8 byte Type +1e9 byte Absolute +1ea byte Size +1eb byte Inserted +1ec int32 SignalState +1f0 struct _LIST_ENTRY WaitListHead +1f0 struct _LIST_ENTRY *Flink +1f4 struct _LIST_ENTRY *Blink +1f8 int32 Limit +1fc void *LpcReplyMessage +200 uint32 LpcReplyMessageId +204 uint32 PerformanceCountLow +208 struct _PS_IMPERSONATION_INFORMATION *ImpersonationInfo +20c struct _LIST_ENTRY IrpList +20c struct _LIST_ENTRY *Flink +210 struct _LIST_ENTRY *Blink +214 uint32 TopLevelIrp +218 struct _DEVICE_OBJECT *DeviceToVerify +21c uint32 ReadClusterSize +220 byte ForwardClusterOnly +221 byte DisablePageFaultClustering +222 byte DeadThread +223 byte HideFromDebugger +224 uint32 HasTerminated +228 uint32 GrantedAccess +22c struct _EPROCESS *ThreadsProcess +230 void *StartAddress +234 void *Win32StartAddress +234 uint32 LpcReceivedMessageId +238 byte LpcExitThreadCalled +239 byte HardErrorsAreDisabled +23a byte LpcReceivedMsgIdValid +23b byte ActiveImpersonationInfo +23c int32 PerformanceCountHigh +240 struct _LIST_ENTRY ThreadListEntry +240 struct _LIST_ENTRY *Flink +244 struct _LIST_ENTRY *Blink struct _KTRAP_FRAME (sizeof=140) +00 uint32 DbgEbp +04 uint32 DbgEip +08 uint32 DbgArgMark +0c uint32 DbgArgPointer +10 uint32 TempSegCs +14 uint32 TempEsp +18 uint32 Dr0 +1c uint32 Dr1 +20 uint32 Dr2 +24 uint32 Dr3 +28 uint32 Dr6 +2c uint32 Dr7 +30 uint32 SegGs +34 uint32 SegEs +38 uint32 SegDs +3c uint32 Edx +40 uint32 Ecx +44 uint32 Eax +48 uint32 PreviousPreviousMode +4c struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList +50 uint32 SegFs +54 uint32 Edi +58 uint32 Esi +5c uint32 Ebx +60 uint32 Ebp +64 uint32 ErrCode +68 uint32 Eip +6c uint32 SegCs +70 uint32 EFlags +74 uint32 HardwareEsp +78 uint32 HardwareSegSs +7c uint32 V86Es +80 uint32 V86Ds +84 uint32 V86Fs +88 uint32 V86Gs 遍历一个进程的所有线程 一个进程的所有线程通过 LIST_ENTRY 结构链在了一个双向循环链表上。 一个链表是以 EPROCESS 结构的 KPROCESS Pcb 中的 ThreadListHead 为链表的链表头。链上的每一项是一个线程的 KTHREAD ETHREAD 结构的 Tcb 中的 ThreadListEntry 。 另一个链表是以 EPROCESS 结构中的 ThreadListHead 为链表的链表头。链上的每一项是一个线程的 ETHREAD 结构中的 ThreadListEntry 。 通过这两个链表中的任何一个,都可以找到一个进程的所有线程的 ETHREAD 结构,当然找到 ETHREAD 结构,就可以找到 ETHREAD 结构中的 KTHREAD。 KTHREAD 链表 struct _EPROCESS (sizeof=648) +000 struct _KPROCESS Pcb +050 struct _LIST_ENTRY ThreadListHead +050 struct _LIST_ENTRY *Flink +054 struct _LIST_ENTRY *Blink struct _ETHREAD (sizeof=584) +000 struct _KTHREAD Tcb +1a4 struct _LIST_ENTRY ThreadListEntry +1a4 struct _LIST_ENTRY *Flink +1a8 struct _LIST_ENTRY *Blink ETHREAD 链表 struct _EPROCESS (sizeof=648) +270 struct _LIST_ENTRY ThreadListHead +270 struct _LIST_ENTRY *Flink +274 struct _LIST_ENTRY *Blink struct _ETHREAD (sizeof=584) +240 struct _LIST_ENTRY ThreadListEntry +240 struct _LIST_ENTRY *Flink +244 struct _LIST_ENTRY *Blink 线程ID和线程所在进程的进程ID +1e0 struct _CLIENT_ID Cid +1e0 void *UniqueProcess +1e4 void *UniqueThread 线程所在进程 +000 struct _KTHREAD Tcb +034 struct _KAPC_STATE ApcState +044 struct _KPROCESS *Process +22c struct _EPROCESS *ThreadsProcess KTHREAD 偏移 +044 处的 KPROCESS *Process ,是指向线程所在进程的 KPROCESS 结构的指针。 KTHREAD 偏移 +22c 处的 EPROCESS *ThreadsProcess ,是指向线程所在进程的 EPROCESS 结构的指针。 我们 KPROCESS 结构在 EPROCESS 结构中,并且位于 EPROCESS 结构开始处。+044 *Process 和  +22c *ThreadsProcess 指向的是同一地址。 线程内核模式下的堆栈 +018 void *InitialStack +15c void *StackBase +01c void *StackLimit 一个线程,有两个自己的堆栈(Stack)。一个是内核模式下的堆栈,一个是用户模式下的堆栈。当线程在内核模式,也就是 ring0 下,执行代码的时候,使用的是内核模式堆栈。当线程在用户模式下,也就是 ring3 下,执行代码的时候,使用的是用户模式堆栈。某些只在内核模式运行的线程没有用户模式堆栈,比如 System 进程(PID为8的进程)的一些线程。 一个线程的内核模式堆栈,位于系统地址空间。该线程 ETHREAD 结构偏移 +018 处的 InitialStack 是该线程内核模式堆栈的最高地址,也就是开始地址,堆栈是向下增长的。该线程 ETHREAD 结构偏移 +15c 处的 StackBase 也指向该线程内核模式堆栈的最高地址。该线程 ETHREAD 结构偏移 +01c 处的 StackLimit 是该线程内核模式堆栈的最低地址。 线程的用户模式堆栈的信息在线程TEB中。 下面我们举一个使用两个堆栈的例子 比如一个应用程序调用 kernel32.dll 中的API CloseHandle()。 这时 esp 和 ebp 都是在用户模式堆栈上。(用户模式堆栈的信息在线程TEB中)。 kernel32!CloseHandle 调用 ntdll.dll!NtClose。 ntdll.dll!NtClose 会执行 INT 2E 指令,到中断之前,一直是在 ring3 下,使用的是用户模式堆栈(esp 和 ebp 都是在用户模式堆栈上)。产生 2e 中断。 CPU 处理 2e 中断,将转去执行 2e 中断的中断处理程序 ntoskrnl!KiSystemService。当转到ntoskrnl!KiSystemService 时,CPU 已经把当前特权级从 ring3 变为 ring0 ,使用的堆栈也变成了内核模式堆栈(esp 和 ebp 在内核模式堆栈上)。ntoskrnl!KiSystemService 最终会调用 ntoskrnl!NtClose 完成处理。 线程TEB +020 void *Teb 线程所执行的代码 +230 void *StartAddress StartAddress 就是这个线程所执行代码的开始地址 线程对象的对象体 需要说明的是 ETHREAD 就是线程对象的对象体,象其他类型的对象一样,ETHREAD 之前也有对象头。使用 kd 可以很容易看到这一点 kd> !thread 8141eda0 0 !thread 8141eda0 0 THREAD 8141eda0 Cid 8.4 Teb: 00000000 Win32Thread: 00000000 WAIT kd> !object 8141eda0 !object 8141eda0 Object: 8141eda0 Type: (814523e0) Thread ObjectHeader: 8141ed88 HandleCount: 0 PointerCount: 3 根据 ETHREAD 的地址,kd 可以正确分析出对象类型是线程,说明了 ETHREAD 的确是对象体
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值