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 和 <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> !thread
8141eda0 0<BR>!thread 8141eda0 0<BR>THREAD 8141eda0 Cid 8.4 Teb: 00000000
Win32Thread: 00000000 WAIT<BR><BR>kd> !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 + -
显示快捷键?