据微软公开文献解释到 这种结构包含了特定于 Windows 子系统(Csrss)的进程信息。也就是说,只有 Windows 应用程序才有与之关联的结构(例如,会话管理器进程 Smss 就没有这样的结构)。 此外,由于每个会话都有其独立的 Windows 子系统实例,这些结构是由每个单独会话内的 Csrss 进程来维护的。 这个结构体在多个版本Windows更新中依旧很稳定
既然微软提供了文献,那我们就可以利用其遍历进程 第一步 我们要了解_CSR_PROCESS结构从哪里得到? 根据资料中提到,其位于 CSRSRV.dll下的全局参数 "CsrRootProcess"
那么这个CsrRootProcess里面第一个值就是CSRSS进程的_CSR_PROCESS结构体,由此我们可以先附加上CSRSS进程,然后找出CSRSRV.dll模块,然后找到CsrRootProcess即可得到结构体
结构体内容如下:
通过获取特定结构体,我们可以访问所需的信息。例如,对于存储在每个进程中的链表,其位置处于每个 _CSR_PROCESS 结构体的 0x10 偏移处。每个 CSRSS 实例内部都维护着这样一个结构体链表。因此,要获取这些信息,您需要遍历所有 CSRSS 实例中的结构体链表。如果有多个 CSRSS.exe 进程,则对每个进程重复这一操作流程。整个过程相对直接。
_CSR_PROCESS结构体用于存储特定于Windows应用程序的进程信息,包括客户端ID、线程列表、关联的NT会话结构指针等重要成员。该结构体位于CSRSRV.dll模块下的全局参数CsrRootProcess中,其中第一个值即为CSRSS进程的_CSR_PROCESS结构体。 通过附加到CSRSS进程,并定位CSRSRV.dll模块中的CsrRootProcess,即可获取到_CSR_PROCESS结构体,从而开始遍历与之相关的进程信息。 _CSR_NT_SESSION结构体则包含了关于NT会话的信息,如会话ID、引用计数以及根目录信息等。此结构体与_CSR_PROCESS结构体相关联,共同维护了Windows子系统的会话管理信息。 遍历所有由Csrss实例维护的进程链表时,需注意对于每个Csrss.exe实例重复这一过程,特别是当存在多个这样的实例时。
/
/
_CSR_NT_SESSION 结构体定义 (根据 WinDbg 输出)
typedef struct _CSR_NT_SESSION {
/
*
+
0x000
*
/
LIST_ENTRY SessionLink;
/
/
用于链接到全局 CSR 会话列表
/
*
+
0x010
*
/
ULONG SessionId;
/
/
NT 会话的
ID
/
*
+
0x014
*
/
LONG
ReferenceCount;
/
/
CSRSS 内部对此结构的引用计数
/
*
+
0x018
*
/
STRING RootDirectory;
/
/
会话相关的根目录信息 (可能是对象管理器路径)
/
/
注意: STRING 结构本身大小是
16
字节 (在
64
位下,USHORT
+
USHORT
+
Padding
+
PCHAR),
/
/
所以下一个成员应该在
0x18
+
0x10
=
0x28
处开始 (如果还有其他成员)
} CSR_NT_SESSION,
*
PCSR_NT_SESSION;
/
/
_CSR_PROCESS 结构体定义 (
64
位, 包含对 _CSR_NT_SESSION 的引用)
typedef struct _CSR_PROCESS {
/
*
+
0x000
*
/
CLIENT_ID ClientId;
/
/
进程和初始线程的唯一标识符
/
*
+
0x010
*
/
LIST_ENTRY ListLink;
/
/
用于链接到全局 CSR 进程列表
/
*
+
0x020
*
/
LIST_ENTRY ThreadList;
/
/
此进程内 CSR 线程 (_CSR_THREAD) 列表的头部
/
*
+
0x030
*
/
struct _CSR_NT_SESSION
*
NtSession;
/
/
指向关联的 NT 会话结构
/
*
+
0x038
*
/
HANDLE ClientPort;
/
/
客户端连接到 CSRSS 的 LPC 端口句柄
/
*
+
0x040
*
/
PVOID ClientViewBase;
/
/
指向与客户端共享内存区域的基地址
/
*
+
0x048
*
/
PVOID ClientViewBounds;
/
/
共享内存区域的边界或大小信息
/
*
+
0x050
*
/
HANDLE ProcessHandle;
/
/
CSRSS 持有的此客户端进程的句柄
/
*
+
0x058
*
/
ULONG SequenceNumber;
/
/
CSRSS 分配的进程序列号
/
*
+
0x05c
*
/
ULONG Flags;
/
/
描述进程状态的标志位 (e.g., CSR_PROCESS_
*
)
/
*
+
0x060
*
/
ULONG DebugFlags;
/
/
与调试相关的标志
/
*
+
0x064
*
/
LONG
ReferenceCount;
/
/
CSRSS 内部对此结构的引用计数 (进程本身的)
/
*
+
0x068
*
/
ULONG ProcessGroupId;
/
/
控制台进程组
ID
/
*
+
0x06c
*
/
ULONG ProcessGroupSequence;
/
/
进程在组内的序列号
/
*
+
0x070
*
/
ULONG LastMessageSequence;
/
/
最后处理的消息序列号
/
*
+
0x074
*
/
ULONG NumOutstandingMessages;
/
/
未完成(待回复)的消息数
/
*
+
0x078
*
/
ULONG ShutdownLevel;
/
/
进程的关机级别
/
优先级
/
*
+
0x07c
*
/
ULONG ShutdownFlags;
/
/
关机相关的标志
/
*
+
0x080
*
/
LUID Luid;
/
/
进程所属的登录会话 LUID
/
*
+
0x088
*
/
PVOID ServerDllPerProcessData[
1
];
/
/
指向服务器 DLL 特定于此进程的数据的指针数组(或指针)
} CSR_PROCESS,
*
PCSR_PROCESS;
/
/
_CSR_NT_SESSION 结构体定义 (根据 WinDbg 输出)
typedef struct _CSR_NT_SESSION {
/
*
+
0x000
*
/
LIST_ENTRY SessionLink;
/
/
用于链接到全局 CSR 会话列表
/
*
+
0x010
*
/
ULONG SessionId;
/
/
NT 会话的
ID
/
*
+
0x014
*
/
LONG
ReferenceCount;
/
/
CSRSS 内部对此结构的引用计数
/
*
+
0x018
*
/
STRING RootDirectory;
/
/
会话相关的根目录信息 (可能是对象管理器路径)
/
/
注意: STRING 结构本身大小是
16
字节 (在
64
位下,USHORT
+
USHORT
+
Padding
+
PCHAR),
/
/
所以下一个成员应该在
0x18
+
0x10
=
0x28
处开始 (如果还有其他成员)
} CSR_NT_SESSION,
*
PCSR_NT_SESSION;
/
/
_CSR_PROCESS 结构体定义 (
64
位, 包含对 _CSR_NT_SESSION 的引用)
typedef struct _CSR_PROCESS {
/
*
+
0x000
*
/
CLIENT_ID ClientId;
/
/
进程和初始线程的唯一标识符
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课