据微软公开文献解释到 这种结构包含了特定于 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; // 进程和初始线程的唯一标识符
传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!