跳转至

0x04. 会话与进程管理

一、NT kernel 中的进程与线程

在 Windows NT kernel 当中使用 _EPROCESS 结构体来表示一个进程,类似于 Linux 下的 task_struct,该结构体当中存储了 Windows 进程的所有信息,即用作 进程管理 ,所有进程的 _EPROCESS 之间构成一个双向链表

但不是所有的资源都记录在 EPROCESS 当中,例如进程环境块(Process Environment Block)在进程地址空间当中,工作集列表(working set list)在内存管理当中

NT Kernel 中的线程则使用 _ETHREAD 结构体表示, 线程是 CPU 实际调度的单位 ,一个线程归属于一个进程,而一个进程当中可以有多个线程,同一进程内的线程间互相共享系统资源以及地址空间

E 开头的 EPROCESS 和 ETHREAD 归属执行体层管理,而 K 开头的 KPROCESS 和 KTHREAD 归内核层管理

内核态 GS 寄存器指向 处理器控制区(Process Control Region),类似于 Linux 下的 .percpu 段,其中存放着指向当前线程控制块的指针,在这其中便又存放着指向当前进程控制块的指针

自己画的图

此外,对于 Win32 程序而言,Win32 子系统进程 Csrss 会在用户态并行维护一个 CSR_PROCESS 结构体,Win32 子系统的内核部分 Win32k.sys 也会维护一个 W32PROCESS 结构体

二、Session:用户登录会话

自 NT Kernel 6.0 版本之后引入了 会话 (Session)机制,会话机制旨在为用户间提供一个更加严格的隔离( 但众所周知大部分情况下 Windows 都是单用户场景 ),每次用户登录时 Windows 都会创建一个新的独立对话,在用户登出时销毁

、Token:进程权限凭证(令牌)

正如 Linux 在 task_struct 当中使用 cred 结构体标识进程的权限,NT kernel 中使用 令牌 (Token) 来标识进程的权限,存放在 _EPROCESS::Token::Object 当中(被用 _EX_FAST_REF 结构体包了一层),本质上是一个 _TOKEN 结构体,其中存储的各种信息比较多:

//0x498 bytes (sizeof)
struct _TOKEN
{
    struct _TOKEN_SOURCE TokenSource;                                       //0x0
    struct _LUID TokenId;                                                   //0x10
    struct _LUID AuthenticationId;                                          //0x18
    struct _LUID ParentTokenId;                                             //0x20
    union _LARGE_INTEGER ExpirationTime;                                    //0x28
    struct _ERESOURCE* TokenLock;                                           //0x30
    struct _LUID ModifiedId;                                                //0x38
    struct _SEP_TOKEN_PRIVILEGES Privileges;                                //0x40
    struct _SEP_AUDIT_POLICY AuditPolicy;                                   //0x58
    ULONG SessionId;                                                        //0x78
    ULONG UserAndGroupCount;                                                //0x7c
    ULONG RestrictedSidCount;                                               //0x80
    ULONG VariableLength;                                                   //0x84
    ULONG DynamicCharged;                                                   //0x88
    ULONG DynamicAvailable;                                                 //0x8c
    ULONG DefaultOwnerIndex;                                                //0x90
    struct _SID_AND_ATTRIBUTES* UserAndGroups;                              //0x98
    struct _SID_AND_ATTRIBUTES* RestrictedSids;                             //0xa0
    VOID* PrimaryGroup;                                                     //0xa8
    ULONG* DynamicPart;                                                     //0xb0
    struct _ACL* DefaultDacl;                                               //0xb8
    enum _TOKEN_TYPE TokenType;                                             //0xc0
    enum _SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;                  //0xc4
    ULONG TokenFlags;                                                       //0xc8
    UCHAR TokenInUse;                                                       //0xcc
    ULONG IntegrityLevelIndex;                                              //0xd0
    ULONG MandatoryPolicy;                                                  //0xd4
    struct _SEP_LOGON_SESSION_REFERENCES* LogonSession;                     //0xd8
    struct _LUID OriginatingLogonSession;                                   //0xe0
    struct _SID_AND_ATTRIBUTES_HASH SidHash;                                //0xe8
    struct _SID_AND_ATTRIBUTES_HASH RestrictedSidHash;                      //0x1f8
    struct _AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION* pSecurityAttributes; //0x308
    VOID* Package;                                                          //0x310
    struct _SID_AND_ATTRIBUTES* Capabilities;                               //0x318
    ULONG CapabilityCount;                                                  //0x320
    struct _SID_AND_ATTRIBUTES_HASH CapabilitiesHash;                       //0x328
    struct _SEP_LOWBOX_NUMBER_ENTRY* LowboxNumberEntry;                     //0x438
    struct _SEP_CACHED_HANDLES_ENTRY* LowboxHandlesEntry;                   //0x440
    struct _AUTHZBASEP_CLAIM_ATTRIBUTES_COLLECTION* pClaimAttributes;       //0x448
    VOID* TrustLevelSid;                                                    //0x450
    struct _TOKEN* TrustLinkedToken;                                        //0x458
    VOID* IntegrityLevelSidValue;                                           //0x460
    struct _SEP_SID_VALUES_BLOCK* TokenSidValues;                           //0x468
    struct _SEP_LUID_TO_INDEX_MAP_ENTRY* IndexEntry;                        //0x470
    struct _SEP_TOKEN_DIAG_TRACK_ENTRY* DiagnosticInfo;                     //0x478
    struct _SEP_CACHED_HANDLES_ENTRY* BnoIsolationHandlesEntry;             //0x480
    VOID* SessionObject;                                                    //0x488
    ULONGLONG VariablePart;                                                 //0x490
}; 

关键字段含义如下:

  • SessionId