首页 > WinDriver > WD-线程ETHREAD结构(WRK)
2015四月5

WD-线程ETHREAD结构(WRK)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
typedef struct _ETHREAD {
    KTHREAD Tcb;
 
    LARGE_INTEGER CreateTime;
 
    union {
        LARGE_INTEGER ExitTime;
        LIST_ENTRY LpcReplyChain;
        LIST_ENTRY KeyedWaitChain;
    };
    union {
        NTSTATUS ExitStatus;
        PVOID OfsChain;
    };
 
    //
    // Registry
    //
 
    LIST_ENTRY PostBlockList;
 
    //
    // Single linked list of termination blocks
    //
 
    union {
        //
        // List of termination ports
        //
 
        PTERMINATION_PORT TerminationPort;
 
        //
        // List of threads to be reaped. Only used at thread exit
        //
 
        struct _ETHREAD *ReaperLink;
 
        //
        // Keyvalue being waited for
        //
        PVOID KeyedWaitValue;
 
    };
 
    KSPIN_LOCK ActiveTimerListLock;
    LIST_ENTRY ActiveTimerListHead;
 
    CLIENT_ID Cid;
 
    //
    // Lpc
    //
 
    union {
        KSEMAPHORE LpcReplySemaphore;
        KSEMAPHORE KeyedWaitSemaphore;
    };
 
    union {
        PVOID LpcReplyMessage;          // -> Message that contains the reply
        PVOID LpcWaitingOnPort;
    };
 
    //
    // Security
    //
    //
    //    Client - If non null, indicates the thread is impersonating
    //        a client.
    //
 
    PPS_IMPERSONATION_INFORMATION ImpersonationInfo;
 
    //
    // Io
    //
 
    LIST_ENTRY IrpList;
 
    //
    //  File Systems
    //
 
    ULONG_PTR TopLevelIrp;  // either NULL, an Irp or a flag defined in FsRtl.h
    struct _DEVICE_OBJECT *DeviceToVerify;
 
    PEPROCESS ThreadsProcess;
    PVOID StartAddress;
    union {
        PVOID Win32StartAddress;
        ULONG LpcReceivedMessageId;
    };
    //
    // Ps
    //
 
    LIST_ENTRY ThreadListEntry;
 
    //
    // Rundown protection structure. Acquire this to do cross thread
    // TEB, TEB32 or stack references.
    //
 
    EX_RUNDOWN_REF RundownProtect;
 
    //
    // Lock to protect thread impersonation information
    //
    EX_PUSH_LOCK ThreadLock;
 
    ULONG LpcReplyMessageId;    // MessageId this thread is waiting for reply to
 
    ULONG ReadClusterSize;
 
    //
    // Client/server
    //
 
    ACCESS_MASK GrantedAccess;
 
    //
    // Flags for cross thread access. Use interlocked operations
    // via PS_SET_BITS etc.
    //
 
    //
    // Used to signify that the delete APC has been queued or the
    // thread has called PspExitThread itself.
    //
 
    #define PS_CROSS_THREAD_FLAGS_TERMINATED           0x00000001UL
 
    //
    // Thread create failed
    //
 
    #define PS_CROSS_THREAD_FLAGS_DEADTHREAD           0x00000002UL
 
    //
    // Debugger isn't shown this thread
    //
 
    #define PS_CROSS_THREAD_FLAGS_HIDEFROMDBG          0x00000004UL
 
    //
    // Thread is impersonating
    //
 
    #define PS_CROSS_THREAD_FLAGS_IMPERSONATING        0x00000008UL
 
    //
    // This is a system thread
    //
 
    #define PS_CROSS_THREAD_FLAGS_SYSTEM               0x00000010UL
 
    //
    // Hard errors are disabled for this thread
    //
 
    #define PS_CROSS_THREAD_FLAGS_HARD_ERRORS_DISABLED 0x00000020UL
 
    //
    // We should break in when this thread is terminated
    //
 
    #define PS_CROSS_THREAD_FLAGS_BREAK_ON_TERMINATION 0x00000040UL
 
    //
    // This thread should skip sending its create thread message
    //
    #define PS_CROSS_THREAD_FLAGS_SKIP_CREATION_MSG    0x00000080UL
 
    //
    // This thread should skip sending its final thread termination message
    //
    #define PS_CROSS_THREAD_FLAGS_SKIP_TERMINATION_MSG 0x00000100UL
 
    union {
 
        ULONG CrossThreadFlags;
 
        //
        // The following fields are for the debugger only. Do not use.
        // Use the bit definitions instead.
        //
 
        struct {
            ULONG Terminated              : 1;
            ULONG DeadThread              : 1;
            ULONG HideFromDebugger        : 1;
            ULONG ActiveImpersonationInfo : 1;
            ULONG SystemThread            : 1;
            ULONG HardErrorsAreDisabled   : 1;
            ULONG BreakOnTermination      : 1;
            ULONG SkipCreationMsg         : 1;
            ULONG SkipTerminationMsg      : 1;
        };
    };
 
    //
    // Flags to be accessed in this thread's context only at PASSIVE
    // level -- no need to use interlocked operations.
    //
 
    union {
        ULONG SameThreadPassiveFlags;
 
        struct {
 
            //
            // This thread is an active Ex worker thread; it should
            // not terminate.
            //
 
            ULONG ActiveExWorker : 1;
            ULONG ExWorkerCanWaitUser : 1;
            ULONG MemoryMaker : 1;
 
            //
            // Thread is active in the keyed event code. LPC should not run above this in an APC.
            //
            ULONG KeyedEventInUse : 1;
        };
    };
 
    //
    // Flags to be accessed in this thread's context only at APC_LEVEL.
    // No need to use interlocked operations.
    //
 
    union {
        ULONG SameThreadApcFlags;
        struct {
 
            //
            // The stored thread's MSGID is valid. This is only accessed
            // while the LPC mutex is held so it's an APC_LEVEL flag.
            //
 
            BOOLEAN LpcReceivedMsgIdValid : 1;
            BOOLEAN LpcExitThreadCalled   : 1;
            BOOLEAN AddressSpaceOwner     : 1;
            BOOLEAN OwnsProcessWorkingSetExclusive  : 1;
            BOOLEAN OwnsProcessWorkingSetShared     : 1;
            BOOLEAN OwnsSystemWorkingSetExclusive   : 1;
            BOOLEAN OwnsSystemWorkingSetShared      : 1;
            BOOLEAN OwnsSessionWorkingSetExclusive  : 1;
            BOOLEAN OwnsSessionWorkingSetShared     : 1;
 
            #define PS_SAME_THREAD_FLAGS_OWNS_A_WORKING_SET    0x000001F8UL
 
            BOOLEAN ApcNeeded                       : 1;
        };
    };
 
    BOOLEAN ForwardClusterOnly;
    BOOLEAN DisablePageFaultClustering;
    UCHAR ActiveFaultCount;
 
#if defined (PERF_DATA)
    ULONG PerformanceCountLow;
    LONG PerformanceCountHigh;
#endif
 
} ETHREAD, *PETHREAD;

第一个对象KTHREAD

LARGE_INTEGER CreateTime;// 线程的创建时间
  union {
        LARGE_INTEGER ExitTime;    // 线程退出时间
        LIST_ENTRY LpcReplyChain;  // 跨进程通信(LPC)
        LIST_ENTRY KeyedWaitChain; // 带键事件的等待链表
    };
   union {
        NTSTATUS ExitStatus;// 线程的退出状态
        PVOID OfsChain;// WRK未使用
    };
 LIST_ENTRY PostBlockList;

PostBlockList 域是一个双链表头节点,该链表中的各个节点类型为PCM_POST_BLOCK,它被用于一个线程向配置管理器登记注册表键的变化通知.

    union {
        PTERMINATION_PORT TerminationPort;
        struct _ETHREAD *ReaperLink;
        PVOID KeyedWaitValue;
    };

TerminationPort域是一个链表头,当一个线程退出时,系统会通知所有已经登记过要接收其终止事件的那些端口。ReaperLink 是一个单链表节点, 它仅在线程退出时使用.当线程被终止时, 该节点将被挂到PsReaperListHead 链表上,所以,在线程回收器(reaper)的工作项目(WorkItem)中该线程的内核栈得以收回.KeyedWaitValue 域是带键事件的键值。它和TerminationPort、ReaperLink 域构成了一个union,它们的有效时间不会重叠.

KSPIN_LOCK ActiveTimerListLock;
LIST_ENTRY ActiveTimerListHead;

ActiveTimerListHead域是一个双链表的头,链表中包含了当前线程的所有定时器.ActiveTimerListLock 域是操作此链表的自旋锁.

CLIENT_ID Cid;//包含了线程的唯一标识符
kd> dt _CLIENT_ID 84e74a38+1e4
ntdll!_CLIENT_ID
   +0x000 UniqueProcess    : 0x00000ad0 Void  //所属进程的PID
   +0x004 UniqueThread     : 0x00000acc Void  //此线程对象在进程句柄表中的句柄
    union {
        KSEMAPHORE LpcReplySemaphore;
        KSEMAPHORE KeyedWaitSemaphore;
    };

    union {
        PVOID LpcReplyMessage;          // -> Message that contains the reply
        PVOID LpcWaitingOnPort;
    };

LpcReplySemaphore 和KeyedWaitSemaphore域是两个信号量对象:LpcReplySemaphore 用于LPC 应答通知,KeyedWaitSemaphore 用于处理带键的事件.

LpcReplyMessage 域是一个指向LPCP_MESSAGE 的指针,其中包含了LPC应答消息;LpcWaitingOnPort 域说明了在哪个端口对象上等待。LpcReplyMessage 和LpcWaitingOnPort 两个域虽然共用同一个union 空间,但是其最低位可用来区分应该用哪个,具体做法参见base\ntos\lpc\lpcp.h 中的LpcpGetThreadMessage 和LpcpGetThreadPort宏.

PPS_IMPERSONATION_INFORMATION ImpersonationInfo;

ImpersonationInfo 域指向线程的模仿信息,Windows 允许一个线程在执行过程中模仿其他的用户来执行一段功能,这样可以实现更为灵活的访问控制安全特性.

LIST_ENTRY IrpList;

IrpList 域是一个双链表头,其中包含了当前线程所有正在处理但尚未完成的I/O 请求(IRP 对象).

ULONG_PTR TopLevelIrp;  // either NULL, an Irp or a flag defined in FsRtl.h

TopLevelIrp 域指向线程的顶级IRP,它或者指向NULL 或一个IRP,或者包含了fsrtl.h 中定义的标记FSRTL_FAST_IO_TOP_LEVEL_IRP 或FSRTL_FSP_TOP_LEVEL_IRP。仅当一个线程的I/O 调用层次中最顶级的组件是文件系统时,TopLevelIrp 域才指向当前IRP.

struct _DEVICE_OBJECT *DeviceToVerify;

DeviceToVerify 域指向一个待检验的设备对象,当磁盘或CD-ROM 设备的驱动程序发现自从上一次该线程访问该设备以来,该设备似乎有了变化,就会设置线程的DeviceToVerify域,从而使最高层的驱动程序,比如文件系统,可以检测到设备的变化.

PEPROCESS ThreadsProcess;//当前线程所属的进程
PVOID StartAddress;//包含了线程的启动地址,这是真正的线程启动地址
    union {
        PVOID Win32StartAddress;//Windows子系统的启动地址
        ULONG LpcReceivedMessageId;
    };
1
2
3
4
5
6
7
8
9
  +0x21c StartAddress     : 0x77e6b5c7 Void
  +0x220 Win32StartAddress : 0x010128a5 Void
  -->
  kd> ln 0x77e6b5c7 
Exact matches:
    kernel32!BaseProcessStartThunk (<no parameter info>)
  kd> ln 0x010128a5 
Exact matches:
    calc!WinMainCRTStartup (<no parameter info>)

StartAddress 域包含的通常是系统DLL 中的线程启动地址,因而往往是相同的(譬如kernel32.dll 中的BaseProcessStart 或BaseThreadStart 函数).

Win32StartAddress 域中包含的才真正是Windows子系统接收到的线程启动地址,即CreateThread API 函数接收到的线程启动地址。所以,Win32StartAddress 不仅对于Windows子系统有意义,对于诊断和分析不同线程的行为更有重要的意义.

LpcReceivedMessageId 域包含了接收到的LPC 消息的ID,此域仅当SameThreadApcFlags 域中的LpcReceivedMsgIdValid 位被置上的时候才有效.

由于LpcReceivedMessageId 和Win32StartAddress 域组成了一个union,所以,当一个Windows 子系统线程在接收LPC 消息时,它的Win32StartAddress 域也会被修改.

LIST_ENTRY ThreadListEntry;

ThreadListEntry 域是一个双链表的节点,每个线程都会加入到它所属进程EPROCESS结构的ThreadListHead 双链表中.

EX_RUNDOWN_REF RundownProtect;
EX_PUSH_LOCK ThreadLock;
ULONG LpcReplyMessageId;    // MessageId this thread is waiting for reply to
ULONG ReadClusterSize;
ACCESS_MASK GrantedAccess;

RundownProtect 域是线程的停止保护锁,对于跨线程引用TEB 结构或者挂起线程的执行等操作,需要获得此锁才能进行,以避免在操作过程中线程被销毁。ThreadLock 域是一把推锁, 用于保护线程的数据属性, 例如PspLockThreadSecurityExclusive 和PspLockThreadSecurityShared 利用该域来保护线程的安全属性.LpcReplyMessageId 域指明了当前线程正在等待对一个消息的应答.ReadClusterSize域指明了在一次I/O操作中读取多少个页面,用于页面交换文件和内存映射文件的读操作.GrantedAccess 域包含了线程的访问权限,这里的访问权限是一个位组合.

    union {
        ULONG CrossThreadFlags;// 一些针对跨线程访问的标志位
        //
        // The following fields are for the debugger only. Do not use.
        // Use the bit definitions instead.
        //
        struct {
            ULONG Terminated              : 1;//线程已执行终止操作
            ULONG DeadThread              : 1;//创建失败
            ULONG HideFromDebugger        : 1;//该线程对于调试器不可见
            ULONG ActiveImpersonationInfo : 1;//线程正在模仿
            ULONG SystemThread            : 1;//系统线程
            ULONG HardErrorsAreDisabled   : 1;//硬件错误无效
            ULONG BreakOnTermination      : 1;//调度器在线程终止时断下
            ULONG SkipCreationMsg         : 1;//不向调试器发送创建消息
            ULONG SkipTerminationMsg      : 1;//不向调试器发送终止消息
        };
    };
 ULONG SameThreadPassiveFlags;

SameThreadPassiveFlags域是一些只有在最低中断级别(被动级别)上才可以访问的标志位,并且只能被该线程自身访问,所以对这些标志位的访问不需要互锁操作.

 ULONG SameThreadApcFlags;

SameThreadApcFlags 域是一些在APC 中断级别上被该线程自身访问的标志位,同样地,对这些标志位的访问也不需要互锁操作.

//页面错误处理有关
 BOOLEAN ForwardClusterOnly;//是否仅仅前向聚集
 BOOLEAN DisablePageFaultClustering;//控制页面交换的聚集与否
 UCHAR ActiveFaultCount;//正在进行之中的页面错误数量

文章作者:hgy413
本文地址:http://hgy413.com/2912.html
版权所有 © 转载时必须以链接形式注明作者和原始出处!

本文目前尚无任何评论.

发表评论