jiurl玩玩win2k进程线程篇 ethread.htm

来自「关于win2000核心编程的文章」· HTM 代码 · 共 224 行 · 第 1/2 页

HTM
224
字号
      *SystemArgument2<BR>+18c char ApcStateIndex<BR>+18d char ApcMode<BR>+18e 
      byte Inserted<BR>+190 struct _KSEMAPHORE SuspendSemaphore<BR>+190 struct 
      _DISPATCHER_HEADER Header<BR>+190 byte Type<BR>+191 byte Absolute<BR>+192 
      byte Size<BR>+193 byte Inserted<BR>+194 int32 SignalState<BR>+198 struct 
      _LIST_ENTRY WaitListHead<BR>+198 struct _LIST_ENTRY *Flink<BR>+19c struct 
      _LIST_ENTRY *Blink<BR>+1a0 int32 Limit<BR>+1a4 struct _LIST_ENTRY 
      ThreadListEntry<BR>+1a4 struct _LIST_ENTRY *Flink<BR>+1a8 struct 
      _LIST_ENTRY *Blink<BR>+1ac char FreezeCount<BR>+1ad char 
      SuspendCount<BR>+1ae byte IdealProcessor<BR>+1af byte DisableBoost<BR>+1b0 
      union _LARGE_INTEGER CreateTime<BR>+1b0 uint32 LowPart<BR>+1b4 int32 
      HighPart<BR>+1b0 struct __unnamed3 u<BR>+1b0 uint32 LowPart<BR>+1b4 int32 
      HighPart<BR>+1b0 int64 QuadPart<BR>+1b0 bits0-1 NestedFaultCount<BR>+1b0 
      bits2-2 ApcNeeded<BR>+1b8 union _LARGE_INTEGER ExitTime<BR>+1b8 uint32 
      LowPart<BR>+1bc int32 HighPart<BR>+1b8 struct __unnamed3 u<BR>+1b8 uint32 
      LowPart<BR>+1bc int32 HighPart<BR>+1b8 int64 QuadPart<BR>+1b8 struct 
      _LIST_ENTRY LpcReplyChain<BR>+1b8 struct _LIST_ENTRY *Flink<BR>+1bc struct 
      _LIST_ENTRY *Blink<BR>+1c0 int32 ExitStatus<BR>+1c0 void *OfsChain<BR>+1c4 
      struct _LIST_ENTRY PostBlockList<BR>+1c4 struct _LIST_ENTRY *Flink<BR>+1c8 
      struct _LIST_ENTRY *Blink<BR>+1cc struct _LIST_ENTRY 
      TerminationPortList<BR>+1cc struct _LIST_ENTRY *Flink<BR>+1d0 struct 
      _LIST_ENTRY *Blink<BR>+1d4 uint32 ActiveTimerListLock<BR>+1d8 struct 
      _LIST_ENTRY ActiveTimerListHead<BR>+1d8 struct _LIST_ENTRY *Flink<BR>+1dc 
      struct _LIST_ENTRY *Blink<BR>+1e0 struct _CLIENT_ID Cid<BR>+1e0 void 
      *UniqueProcess<BR>+1e4 void *UniqueThread<BR>+1e8 struct _KSEMAPHORE 
      LpcReplySemaphore<BR>+1e8 struct _DISPATCHER_HEADER Header<BR>+1e8 byte 
      Type<BR>+1e9 byte Absolute<BR>+1ea byte Size<BR>+1eb byte Inserted<BR>+1ec 
      int32 SignalState<BR>+1f0 struct _LIST_ENTRY WaitListHead<BR>+1f0 struct 
      _LIST_ENTRY *Flink<BR>+1f4 struct _LIST_ENTRY *Blink<BR>+1f8 int32 
      Limit<BR>+1fc void *LpcReplyMessage<BR>+200 uint32 
      LpcReplyMessageId<BR>+204 uint32 PerformanceCountLow<BR>+208 struct 
      _PS_IMPERSONATION_INFORMATION *ImpersonationInfo<BR>+20c struct 
      _LIST_ENTRY IrpList<BR>+20c struct _LIST_ENTRY *Flink<BR>+210 struct 
      _LIST_ENTRY *Blink<BR>+214 uint32 TopLevelIrp<BR>+218 struct 
      _DEVICE_OBJECT *DeviceToVerify<BR>+21c uint32 ReadClusterSize<BR>+220 byte 
      ForwardClusterOnly<BR>+221 byte DisablePageFaultClustering<BR>+222 byte 
      DeadThread<BR>+223 byte HideFromDebugger<BR>+224 uint32 
      HasTerminated<BR>+228 uint32 GrantedAccess<BR>+22c struct _EPROCESS 
      *ThreadsProcess<BR>+230 void *StartAddress<BR>+234 void 
      *Win32StartAddress<BR>+234 uint32 LpcReceivedMessageId<BR>+238 byte 
      LpcExitThreadCalled<BR>+239 byte HardErrorsAreDisabled<BR>+23a byte 
      LpcReceivedMsgIdValid<BR>+23b byte ActiveImpersonationInfo<BR>+23c int32 
      PerformanceCountHigh<BR>+240 struct _LIST_ENTRY ThreadListEntry<BR>+240 
      struct _LIST_ENTRY *Flink<BR>+244 struct _LIST_ENTRY *Blink<BR><BR>struct 
      _KTRAP_FRAME (sizeof=140)<BR>+00 uint32 DbgEbp<BR>+04 uint32 DbgEip<BR>+08 
      uint32 DbgArgMark<BR>+0c uint32 DbgArgPointer<BR>+10 uint32 
      TempSegCs<BR>+14 uint32 TempEsp<BR>+18 uint32 Dr0<BR>+1c uint32 Dr1<BR>+20 
      uint32 Dr2<BR>+24 uint32 Dr3<BR>+28 uint32 Dr6<BR>+2c uint32 Dr7<BR>+30 
      uint32 SegGs<BR>+34 uint32 SegEs<BR>+38 uint32 SegDs<BR>+3c uint32 
      Edx<BR>+40 uint32 Ecx<BR>+44 uint32 Eax<BR>+48 uint32 
      PreviousPreviousMode<BR>+4c struct _EXCEPTION_REGISTRATION_RECORD 
      *ExceptionList<BR>+50 uint32 SegFs<BR>+54 uint32 Edi<BR>+58 uint32 
      Esi<BR>+5c uint32 Ebx<BR>+60 uint32 Ebp<BR>+64 uint32 ErrCode<BR>+68 
      uint32 Eip<BR>+6c uint32 SegCs<BR>+70 uint32 EFlags<BR>+74 uint32 
      HardwareEsp<BR>+78 uint32 HardwareSegSs<BR>+7c uint32 V86Es<BR>+80 uint32 
      V86Ds<BR>+84 uint32 V86Fs<BR>+88 uint32 
      V86Gs<BR><BR><B>遍历一个进程的所有线程</B><BR><BR>一个进程的所有线程通过 LIST_ENTRY 
      结构链在了一个双向循环链表上。<BR>一个链表是以 EPROCESS 结构的 KPROCESS Pcb 中的 ThreadListHead 
      为链表的链表头。链上的每一项是一个线程的 KTHREAD ETHREAD 结构的 Tcb 中的 ThreadListEntry 
      。<BR>另一个链表是以 EPROCESS 结构中的 ThreadListHead 为链表的链表头。链上的每一项是一个线程的 ETHREAD 
      结构中的 ThreadListEntry 。<BR>通过这两个链表中的任何一个,都可以找到一个进程的所有线程的 ETHREAD 结构,当然找到 
      ETHREAD 结构,就可以找到 ETHREAD 结构中的 KTHREAD。<BR><BR>KTHREAD 链表<BR><BR>struct 
      _EPROCESS (sizeof=648)<BR>+000 struct _KPROCESS Pcb<BR>+050 struct 
      _LIST_ENTRY ThreadListHead<BR>+050 struct _LIST_ENTRY *Flink<BR>+054 
      struct _LIST_ENTRY *Blink<BR><BR>struct _ETHREAD (sizeof=584)<BR>+000 
      struct _KTHREAD Tcb<BR>+1a4 struct _LIST_ENTRY ThreadListEntry<BR>+1a4 
      struct _LIST_ENTRY *Flink<BR>+1a8 struct _LIST_ENTRY *Blink<BR><BR>ETHREAD 
      链表<BR><BR>struct _EPROCESS (sizeof=648)<BR>+270 struct _LIST_ENTRY 
      ThreadListHead<BR>+270 struct _LIST_ENTRY *Flink<BR>+274 struct 
      _LIST_ENTRY *Blink<BR><BR>struct _ETHREAD (sizeof=584)<BR>+240 struct 
      _LIST_ENTRY ThreadListEntry<BR>+240 struct _LIST_ENTRY *Flink<BR>+244 
      struct _LIST_ENTRY *Blink<BR><BR><B>线程ID和线程所在进程的进程ID</B><BR><BR>+1e0 
      struct _CLIENT_ID Cid<BR>+1e0 void *UniqueProcess<BR>+1e4 void 
      *UniqueThread<BR><BR><BR><B>线程所在进程</B><BR><BR>+000 struct _KTHREAD 
      Tcb<BR>+034 struct _KAPC_STATE ApcState<BR>+044 struct _KPROCESS 
      *Process<BR><BR>+22c struct _EPROCESS *ThreadsProcess<BR><BR>KTHREAD 偏移 
      +044 处的 KPROCESS *Process ,是指向线程所在进程的 KPROCESS 结构的指针。<BR>KTHREAD 偏移 +22c 
      处的 EPROCESS *ThreadsProcess ,是指向线程所在进程的 EPROCESS 结构的指针。<BR>我们 KPROCESS 结构在 
      EPROCESS 结构中,并且位于 EPROCESS 结构开始处。+044 *Process 和&nbsp;<BR>+22c 
      *ThreadsProcess 指向的是同一地址。<BR><BR><B>线程内核模式下的堆栈</B><BR><BR>+018 void 
      *InitialStack<BR>+15c void *StackBase<BR><BR>+01c void 
      *StackLimit<BR><BR>一个线程,有两个自己的堆栈(Stack)。一个是内核模式下的堆栈,一个是用户模式下的堆栈。当线程在内核模式,也就是 
      ring0 下,执行代码的时候,使用的是内核模式堆栈。当线程在用户模式下,也就是 ring3 
      下,执行代码的时候,使用的是用户模式堆栈。某些只在内核模式运行的线程没有用户模式堆栈,比如 System 
      进程(PID为8的进程)的一些线程。<BR><BR>一个线程的内核模式堆栈,位于系统地址空间。该线程 ETHREAD 结构偏移 +018 处的 
      InitialStack 是该线程内核模式堆栈的最高地址,也就是开始地址,堆栈是向下增长的。该线程 ETHREAD 结构偏移 +15c 处的 
      StackBase 也指向该线程内核模式堆栈的最高地址。该线程 ETHREAD 结构偏移 +01c 处的 StackLimit 
      是该线程内核模式堆栈的最低地址。<BR><BR>线程的用户模式堆栈的信息在线程TEB中。<BR><BR>下面我们举一个使用两个堆栈的例子<BR><BR>比如一个应用程序调用 
      kernel32.dll 中的API CloseHandle()。<BR>这时 esp 和 ebp 
      都是在用户模式堆栈上。(用户模式堆栈的信息在线程TEB中)。<BR>kernel32!CloseHandle 调用 
      ntdll.dll!NtClose。<BR>ntdll.dll!NtClose 会执行 INT 2E 指令,到中断之前,一直是在 ring3 
      下,使用的是用户模式堆栈(esp 和 ebp 都是在用户模式堆栈上)。产生 2e 中断。<BR>CPU 处理 2e 中断,将转去执行 2e 
      中断的中断处理程序 ntoskrnl!KiSystemService。当转到ntoskrnl!KiSystemService 时,CPU 
      已经把当前特权级从 ring3 变为 ring0 ,使用的堆栈也变成了内核模式堆栈(esp 和 ebp 
      在内核模式堆栈上)。ntoskrnl!KiSystemService 最终会调用 ntoskrnl!NtClose 
      完成处理。<BR><BR><BR><B>线程TEB</B><BR><BR>+020 void 
      *Teb<BR><BR><BR><B>线程所执行的代码</B><BR><BR>+230 void 
      *StartAddress<BR>StartAddress 
      就是这个线程所执行代码的开始地址<BR><BR><BR><B>线程对象的对象体</B><BR><BR>需要说明的是 ETHREAD 
      就是线程对象的对象体,象其他类型的对象一样,ETHREAD 之前也有对象头。使用 kd 可以很容易看到这一点<BR>kd&gt; !thread 
      8141eda0 0<BR>!thread 8141eda0 0<BR>THREAD 8141eda0 Cid 8.4 Teb: 00000000 
      Win32Thread: 00000000 WAIT<BR><BR>kd&gt; !object 8141eda0<BR>!object 
      8141eda0<BR>Object: 8141eda0 Type: (814523e0) Thread<BR>ObjectHeader: 
      8141ed88<BR>HandleCount: 0 PointerCount: 3<BR><BR>根据 ETHREAD 的地址,kd 
      可以正确分析出对象类型是线程,说明了 ETHREAD 的确是对象体。<BR>
      <P>欢迎交流,欢迎交朋友,<BR>欢迎访问 <A 
      href="http://jiurl.yeah.net/">http://jiurl.yeah.net/</A> <A 
      href="http://jiurl.cosoft.org.cn/forum">http://jiurl.cosoft.org.cn/forum</A> 

      <P>  
      <P>  
      <P>  </P></TD></TR></TBODY></TABLE></DIV></BODY></HTML>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?