Windows进程和线程


Windows进程和线程

众所周知,进程是空间,线程是任务

Windows函数命名规则

进程结构体

进程有两个结构体_kprocess_eprocess_eprocess继承了_kprocess

在Windbg中可以使用dt _kprocess [ADDR]dt _eprocess [ADDR]查看这两个结构体

在windows系统中,所有的活动进程都是连在一起的,构成一个双向链表,表头是全局变量PsActiveProcessHead,当一个进程被创建时,其ActiveProcessList域将被作为节点加入到此链表中;当进程被删除时,则从此链表中移除,访问此链表即可遍历进程

Windbg 查看链表头:dd psactiveprocesshead

_kprocess

+0x000 Header           : _DISPATCHER_HEADER          // 可等待对象,比如:进程,线程,事件,互斥

+0x010 ProfileListHead  : _LIST_ENTRY [ 0x89797840 - 0x89797840 ]  //性能分析
+0x018 DirectoryTableBase : [2] 0xb37000  //[CR3, 超空间页目录表地址]
+0x020 LdtDescriptor    : _KGDTENTRY      //LDT表
+0x028 Int21Descriptor  : _KIDTENTRY      //允许使用 int 0x21 (兼容DOS)

+0x030 IopmOffset       : 0x20ac          //指定IOPM 用户I/O权限的
+0x032 Iopl             : 0 ''
+0x033 Unused           : 0 ''

+0x034 ActiveProcessors : 0        //当前进程在哪个处理器上运行

+0x038 KernelTime       : 0x3f58   //统计内核下所花的时间
+0x03c UserTime         : 0        //统计用户下所花的时间
//以上的时间在线程结束时才更新,所以在运行结束前均为0

+0x040 ReadyListHead    : _LIST_ENTRY [ 0x89797870 - 0x89797870 ]  //全局的就绪链表头(线程)
// 进程换内存的链表,当进程要被换出内存是,通过此域加入到KiProcessOutSwapListHead为链头的单链表中
// 换出内存是通过此域加入到KiProcessInSwapListHead为链头的单链表中
+0x048 SwapListEntry    : _SINGLE_LIST_ENTRY  

+0x04c VdmTrapcHandler  : (null) // 处理 Ctrl+C中断(仅用于 Virtual DOS Machine)
+0x050 ThreadListHead   : _LIST_ENTRY [ 0x89797768 - 0x896fec88 ]  // 链表头,该进程里面的所有线程

+0x058 ProcessLock      : 0     // 自旋锁(保护该进程的数据成员)
+0x05c Affinity         : 1     //规定进程里面的所有线程能在哪个CPU上跑(其二进制的每一位分别对应CPU的一个核,为1就是能跑)也称为CPU的亲和性
+0x060 StackCount       : 0x2b  //堆栈访问的次数
+0x062 BasePriority     : 8 ''  //当前线程的基本优先级 0-31,最开始为8
+0x063 ThreadQuantum    : 6 ''  //当前进程的处理器

+0x064 AutoAlignment    : 0 ''  //对齐
+0x065 State            : 0 ''  //一个进程是否是在内存中(6种状态)
+0x066 ThreadSeed       : 0 ''  //当前进程里面的线程选一个理想的处理器
+0x067 DisableBoost     : 0 ''  //优先级提示
+0x068 PowerState       : 0 ''  //电源的状态
+0x069 DisableQuantum   : 0 ''  //时限
+0x06a IdealNode        : 0 ''  //进程优先处理器节点
+0x06b Flags            : _KEXECUTE_OPTIONS
+0x06b ExecuteOptions   : 0 ''  //设置一个进程的内存执行选项

_eprocess

+0x000 Pcb              : _KPROCESS     //继承_kprocess
+0x06c ProcessLock      : _EX_PUSH_LOCK // 推锁对象,用了保护eprocess数据成员


+0x070 CreateTime       : _LARGE_INTEGER 0x0  //进程的创建时间
+0x078 ExitTime         : _LARGE_INTEGER 0x0  //进程的退出时间
+0x080 RundownProtect   : _EX_RUNDOWN_REF     //进程的停止保护锁

+0x084 UniqueProcessId  : 0x00000004 Void   //PID

+0x088 ActiveProcessLinks : _LIST_ENTRY [ 0x8932cda0 - 0x8055b158 ]  //所有的活动的进程组成一个双向链表

+0x090 QuotaUsage       : [3] 0  //内存使用量   物理页的统计信息
+0x09c QuotaPeak        : [3] 0  // 尖峰(最大)使用量


+0x0a8 CommitCharge     : 7         //虚拟内存已提交的页面
+0x0ac PeakVirtualSize  : 0x3c0000  //虚拟内存大小的尖峰值
+0x0b0 VirtualSize      : 0x1c7000  //虚拟内存的大小


+0x0b4 SessionProcessLinks : _LIST_ENTRY [ 0x0 - 0x0 ] //系统会话链表


+0x0bc DebugPort        : (null)  //调试端口
+0x0c0 ExceptionPort    : (null)  //异常端口


+0x0c4 ObjectTable      : 0xe1000cf8 _HANDLE_TABLE  //句柄表
+0x0c8 Token            : _EX_FAST_REF              //令牌,进程的安全访问检查


+0x0cc WorkingSetLock   : _FAST_MUTEX
+0x0ec WorkingSetPage   : 0              //包含进程工作集的页面
+0x0f0 AddressCreationLock : _FAST_MUTEX // 保护虚拟地址的互斥锁
+0x110 HyperSpaceLock   : 0              //自旋锁,用于保护进程的超空间


+0x114 ForkInProgress   : (null)  //指向正在复制地址空间的线程
+0x118 HardwareTrigger  : 0       //记录硬件错误性能分析次数

+0x11c VadRoot          : 0x89793200 Void  VAD树
+0x120 VadHint          : 0x89793200 Void
+0x124 CloneRoot        : (null) //当进程空间地址被复制时,次树才会创建


+0x128 NumberOfPrivatePages : 3  //进程私有页面的数量
+0x12c NumberOfLockedPages : 0   //进程被锁住页面的数量


+0x130 Win32Process     : (null) 不为NULL,指向的是一个GUI的进程
+0x134 Job              : (null)   //进程作业对象
+0x138 SectionObject    : (null)   //进程可执行映像文件的内存对象
+0x13c SectionBaseAddress : (null) 内存区对象的基地址
+0x140 QuotaBlock       : 0x8055b200 _EPROCESS_QUOTA_BLOCK  //指向该进程的配额块
+0x144 WorkingSetWatch  : (null)   // 用于监视一个进程的页面错误
+0x148 Win32WindowStation : (null) // 进程所属的窗口站的句柄


+0x14c InheritedFromUniqueProcessId : (null) //父进程的ID
+0x150 LdtInformation   : (null)  //LDT表


+0x154 VadFreeHint      : (null)             //指向一个提示VAD的节点
+0x158 VdmObjects       : (null)             //指向进程的VDM数据区
+0x15c DeviceMap        : 0xe1004440 Void    //指向进程使用的设备表
+0x160 PhysicalVadList  : _LIST_ENTRY [ 0x89797990 - 0x89797990 ] //物理页的VAD链表
+0x168 PageDirectoryPte : _HARDWARE_PTE_X86  //顶级页面的页表项


+0x168 Filler           : 0
+0x170 Session          : (null)    进程会话
+0x174 ImageFileName    : [16]  "System"   进程名称


+0x184 JobLinks         : _LIST_ENTRY [ 0x0 - 0x0 ]               //作业进程链表
+0x18c LockedPagesList  : (null)                // 哪些页表被锁住
+0x190 ThreadListHead   : _LIST_ENTRY [ 0x897977e4 - 0x896fed04 ] //当前进程的所有线程都在这个链表里面
+0x198 SecurityPort     : 0xe19011b8 Void                // 安全端口


+0x19c PaeTop           : (null)   // 支持PAE内存访问机制
+0x1a0 ActiveThreads    : 0x39     //活动线程的数量
+0x1a4 GrantedAccess    : 0x1f0fff //进程访问的权限


+0x1a8 DefaultHardErrorProcessing : 1 指定了默认的硬件错误处理
+0x1ac LastThreadExitStatus : 0n0 //记录了最后一个线程的退出状态


+0x1b0 Peb              : (null)  //进程的环境控制块(3环的进程信息)


+0x1b4 PrefetchTrace    : _EX_FAST_REF             //快速引用
+0x1b8 ReadOperationCount : _LARGE_INTEGER 0x64    //NtReadFile系统服务被调用的次数
+0x1c0 WriteOperationCount : _LARGE_INTEGER 0xf27  //NtWriteFile系统服务被调用的次数
+0x1c8 OtherOperationCount : _LARGE_INTEGER 0x2285 //读写除外的I/O服务次数


+0x1d0 ReadTransferCount : _LARGE_INTEGER 0x7cb98   //I/O读完成的次数
+0x1d8 WriteTransferCount : _LARGE_INTEGER 0xde6368 //I/O写完成的次数
+0x1e0 OtherTransferCount : _LARGE_INTEGER 0x8c5c6 //非读写完成的次数


+0x1e8 CommitChargeLimit : 0           //已提交的页面数量的限制值,0表示没有限制
+0x1ec CommitChargePeak : 0x201    //尖峰时刻已提交的页面数量


+0x1f0 AweInfo          : (null)   //支持AWE

+0x1f4 SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO // 进程所在的路径

+0x1f8 Vm               : _MMSUPPORT //虚拟内存的重要数据结构
+0x238 LastFaultCount   : 0
+0x23c ModifiedPageCount : 0x2340c  //进程中已修改页面的数量
+0x240 NumberOfVads     : 4
+0x244 JobStatus        : 0         //作业的状态

+0x248 Flags            : 0x40000     //进程的标志位
+0x248 CreateReported   : 0y0
+0x248 NoDebugInherit   : 0y0
+0x248 ProcessExiting   : 0y0
+0x248 ProcessDelete    : 0y0
+0x248 Wow64SplitPages  : 0y0
+0x248 VmDeleted        : 0y0
+0x248 OutswapEnabled   : 0y0
+0x248 Outswapped       : 0y0
+0x248 ForkFailed       : 0y0
+0x248 HasPhysicalVad   : 0y0
+0x248 AddressSpaceInitialized : 0y00
+0x248 SetTimerResolution : 0y0
+0x248 BreakOnTermination : 0y0
+0x248 SessionCreationUnderway : 0y0
+0x248 WriteWatch       : 0y0
+0x248 ProcessInSession : 0y0
+0x248 OverrideAddressSpace : 0y0
+0x248 HasAddressSpace  : 0y1
+0x248 LaunchPrefetched : 0y0
+0x248 InjectInpageErrors : 0y0
+0x248 VmTopDown        : 0y0
+0x248 Unused3          : 0y0
+0x248 Unused4          : 0y0
+0x248 VdmAllowed       : 0y0
+0x248 Unused           : 0y00000 (0)
+0x248 Unused1          : 0y0
+0x248 Unused2          : 0y0


+0x24c ExitStatus       : 0n259      //进程退出的状态
+0x250 NextPageColor    : 0x5b45     //物理页面分配算法
+0x252 SubSystemMinorVersion : 0 ''  //进程子系统的次版本号
+0x253 SubSystemMajorVersion : 0 ''  //进程子系统的主版本号
+0x252 SubSystemVersion : 0          //子系统版本
+0x254 PriorityClass    : 0x2 ''     //进程的优先级
+0x255 WorkingSetAcquiredUnsafe : 0 ''
+0x258 Cookie           : 0          //进程的随机值

CreateProcess

如果调用的是CreateProcessA,Windows会先调用CreateProcessInternalA将参数中ANSI参数值全部转换为unicode,再调用CreateProcessInternalW

CreateProcess创建流程

调用CreateProcessInternalW

初始化一系列参数

判断dwCreationFlags是否为CREATE_NEW_CONSOLE | DETACHED_PROCESS的组合

根据传入的dwCreationFlags设置优先级

当满足IDLE_PRIORITY_CLASS时,置优先级标志为1.
当满足NORMAL_PRIORITY_CLASS时,置优先级标志为2.
当满足HIGH_PRIORITY_CLASS时,置优先级标志3.
当满足REALTIME_PRIORITY_CLASS时,置优先级标志4,该优先级比操作系统优先级还高.

将预设的几个参数加入dwCreationFlags

如果dwCreationFlags不正确则退出创建进程

设置环境变量字符串

如果不是Unicode字符串,则将ANSI字符串转化为Unicode

如果没有成功则退出进程创建

查找对应字符串的文件路径

NtOpenFile

NtCreateSection

BasepIsProcessAllowed判断应用程序名是否再授权文件列表中

NtQuerySection将内存区对象作为镜像文件查询信息,返回后得到节的基本信息(节基地址,大小,属性)

修改dwCreationFlags,并判断是否包含DEBUG_PROCESSDEBUG_ONLY_THIS_PROCESS

如果存在则调用LdrQueryImageFileExecutionOptions检查应用程序是否在注册表Image File Execution Options

不存在则判断peb->ReadImageFileExecOptions是否为0,如果不为0则执行上一步

检查PE信息部分域的有效性

加载advapi32.dll,并获取CreateProcessAsUserSecure函数地址

BashFormatObjectAttributes返回对象属性作为参数传递给下层函数

调用NtCreateProcessEx

PspCreateProcess

CreateProcessNtCreateProcessEx只是处理并检查了一下参数以及将文件加载到内存中,真正创建进程的流程在PspCreateProcess

PspCreateProcess执行流程

004B42CF        push    11Ch
004B42D4        push    offset stru_4285D8
004B42D9        call    __SEH_prolog    ; 异常
004B42DE        mov     eax, large fs:_KPCR.PrcbData.CurrentThread
004B42E4        mov     [ebp+currentThread], eax
004B42EA        mov     cl, [eax+140h]
004B42F0        mov     [ebp+PreviousMode], cl
004B42F3        mov     eax, [eax+44h]
004B42F6        mov     [ebp+var_Process], eax
004B42F9        xor     esi, esi
004B42FB        mov     [ebp+var_1D], 0
004B42FF        mov     [ebp+SpinLock], esi
004B4302        mov     [ebp+var_44], esi
004B4305        test    [ebp+arg_10], 0FFFFFFF0h
004B430C        jnz     loc_52DD8B
004B4312        cmp     [ebp+ParentProcess], esi
004B4315        jz      loc_4EB0B6      ; 父进程为空
004B431B        push    esi             ; HandleInformation
004B431C        lea     eax, [ebp+Object] ; 父进程句柄转换为进程对象
004B431F        push    eax             ; Object
004B4320        push    dword ptr [ebp+PreviousMode] ; AccessMode
004B4323        push    _PsProcessType  ; ObjectType
004B4329        push    80h ; '€'       ; DesiredAccess
004B432E        push    [ebp+ParentProcess] ; Handle
004B4331        call    _ObReferenceObjectByHandle@24 ; 把句柄转换为eprocess结构体
004B4336        mov     ecx, [ebp+Object] ; Object
004B4339        mov     [ebp+eprocess], ecx
004B433C        cmp     eax, esi
004B433E        jl      loc_4B4791
004B4344        cmp     [ebp+injob], esi
004B4347        jnz     loc_52DD7A
004B434D
004B434D loc_4B434D:                    ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+79AB1↓j
004B434D        mov     eax, [ecx+_EPROCESS.Pcb.Affinity]
004B4350
004B4350 loc_4B4350:                    ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+36DEF↓j
004B4350        mov     [ebp+Affinity], eax
004B4353        mov     eax, ds:_PsMinimumWorkingSet ; 工作集的最小值
004B4358        mov     dword ptr [ebp+var_60], eax
004B435B        mov     eax, ds:_PsMaximumWorkingSet ; 工作集的最大值
004B4360        mov     [ebp+var_68], eax
004B4363        lea     eax, [ebp+var_54]
004B4366        push    eax             ; int
004B4367        push    esi             ; int
004B4368        push    esi             ; int
004B4369        push    260h            ; int
004B436E        push    esi             ; int
004B436F        push    dword ptr [ebp+PreviousMode] ; BackTraceHash
004B4372        push    [ebp+arg_8]     ; int
004B4375        push    _PsProcessType  ; int
004B437B        push    dword ptr [ebp+PreviousMode] ; PreviousMode
004B437E        call    _ObCreateObject@36 ; 创建EPROCESS对象
004B4383        mov     edi, eax
004B4385        cmp     edi, esi
004B4387        jl      loc_4B4783      ; 判断obCreateObject有没有成功
004B438D        mov     ecx, 98h
004B4392        xor     eax, eax
004B4394        mov     ebx, [ebp+var_54]
004B4397        mov     edi, ebx
004B4399        rep stosd               ; 将新建对象初始化为0
004B439B        mov     [ebx+80h], esi
004B43A1        mov     [ebx+6Ch], esi
004B43A4        lea     eax, [ebx+190h]
004B43AA        mov     [eax+4], eax
004B43AD        mov     [eax], eax
004B43AF        push    [ebp+eprocess]
004B43B2        push    ebx
004B43B3        call    _PspInheritQuota@8 ; 继承资源分配
004B43B8        push    [ebp+eprocess]
004B43BB        push    ebx
004B43BC        call    _ObInheritDeviceMap@8 ; 继承父进程的设备位图
004B43C1        mov     edi, [ebp+eprocess]
004B43C4        cmp     edi, esi
004B43C6        jz      loc_4EB0C3
004B43CC        mov     eax, [edi+1A8h]
004B43D2        mov     [ebx+1A8h], eax
004B43D8        mov     eax, [edi+84h]
004B43DE        mov     [ebx+14Ch], eax
004B43E4
004B43E4 loc_4B43E4:                    ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+36E04↓j
004B43E4        cmp     [ebp+arg_14], esi
004B43E7        jz      loc_4EB0D8      ; 判断区对象句柄是否为0
004B43ED        push    esi             ; HandleInformation
004B43EE        lea     eax, [ebp+var_88]
004B43F4        push    eax             ; Object
004B43F5        push    dword ptr [ebp+PreviousMode] ; AccessMode
004B43F8        push    _MmSectionObjectType ; ObjectType
004B43FE        push    8               ; DesiredAccess
004B4400        push    [ebp+arg_14]    ; Handle
004B4403        call    _ObReferenceObjectByHandle@24 ; 通过句柄获取文件映射区的对象
004B4408        mov     ecx, [ebp+var_88] ; 新进程的内存区对象初始化完成
004B440E        mov     [ebp+var_28], ecx
004B4411        mov     edi, eax
004B4413        cmp     eax, esi
004B4415        jl      loc_4B477C
004B441B        mov     edi, [ebp+eprocess]
004B441E
004B441E loc_4B441E:                    ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+36E12↓j
004B441E                       ; PspCreateProcess(x,x,x,x,x,x,x,x,x)+79B3B↓j
004B441E        mov     eax, [ebp+var_28]
004B4421        mov     [ebx+138h], eax
004B4427        cmp     [ebp+arg_18], esi
004B442A        jnz     loc_52DD95
004B4430        cmp     edi, esi
004B4432        jz      short loc_4B443B ; 初始化debugport成员
004B4434        push    edi             ; FastMutex
004B4435        push    ebx             ; int
004B4436        call    _DbgkCopyProcessDebugPort@8 ; 从父进程拷贝debugport给新进程
004B443B
004B443B loc_4B443B:                    ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+163↑j
004B443B                       ; PspCreateProcess(x,x,x,x,x,x,x,x,x)+79AF5↓j ...
004B443B        cmp     [ebp+arg_1C], esi ; 初始化debugport成员
004B443E        jnz     loc_52DE1A
004B4444
004B4444 loc_4B4444:                    ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+79B75↓j
004B4444        mov     dword ptr [ebx+24Ch], 103h
004B444E        push    ebx             ; 新进程对象
004B444F        push    [ebp+eprocess]  ; 父进程对象
004B4452        call    _PspInitializeProcessSecurity@8 ; 复制父进程的Token,设置新进程的安全属性
004B4452                       ; 主要设置新进程的安全令牌对象
004B4457        mov     edi, eax
004B4459        cmp     edi, esi
004B445B        jl      loc_4B477C
004B4461        mov     edi, [ebp+eprocess]
004B4464        cmp     edi, esi
004B4466        jz      loc_4F35E4
004B446C        lea     eax, [ebp+SpinLock]
004B446F        push    eax             ; SpinLock
004B4470        push    ebx
004B4471        push    dword ptr [ebp+var_60] ; 新进程对象
004B4474        call    _MmCreateProcessAddressSpace@12 ; 为新进程创建地址空间并构建页目录表、页表以及物理页的关系
004B4479        test    al, al
004B447B        jz      loc_52DF0F
004B4481
004B4481 loc_4B4481:                    ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+3F32E↓j
004B4481        mov     eax, 40000h
004B4486        lea     ecx, [ebx+248h]
004B448C        lock or [ecx], eax
004B448F        mov     eax, [ebp+var_68]
004B4492        mov     [ebx+214h], eax
004B4498        xor     eax, eax
004B449A        mov     al, [ebx+1A8h]
004B44A0        and     eax, 0FFFFFF04h
004B44A5        push    eax
004B44A6        lea     eax, [ebp+SpinLock]
004B44A9        push    eax             ; 页目录表地址
004B44AA        push    [ebp+Affinity]
004B44AD        push    8               ; 进程基本优先级
004B44AF        push    ebx             ; 新进程eprocess
004B44B0        call    _KeInitializeProcess@20 ; 初始化新进程对象中的内核对象、优先级、亲和性、页目录表物理地址等
004B44B5        mov     al, _PspForegroundQuantum
004B44BA        mov     [ebx+63h], al
004B44BD        lea     eax, [ebx+254h]
004B44C3        mov     byte ptr [eax], 2
004B44C6        cmp     edi, esi
004B44C8        jz      loc_4F3654
004B44CE        mov     cl, [edi+254h]
004B44D4        cmp     cl, 1
004B44D7        jz      loc_4F365F
004B44DD        cmp     cl, 5
004B44E0        jz      loc_4F365F
004B44E6
004B44E6 loc_4B44E6:                    ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+3F392↓j
004B44E6        push    ebx
004B44E7        mov     eax, [ebp+arg_10]
004B44EA        and     al, 4
004B44EC        neg     al
004B44EE        sbb     eax, eax
004B44F0        and     eax, [ebp+eprocess]
004B44F3        push    eax             ; 父进程的句柄
004B44F4        call    _ObInitProcess@8 ; 初始化新进程对象表或句柄表
004B44F4                       ; 如果父进程被指定,父进程的对象拷贝到新进程中
004B44F9
004B44F9 loc_4B44F9:                    ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+3F38B↓j
004B44F9                       ; 0052DE4E↓j
004B44F9        mov     edi, eax
004B44FB        cmp     edi, esi
004B44FD        jl      loc_4B477C
004B4503        mov     [ebp+var_34], esi
004B4506        cmp     [ebp+arg_14], esi
004B4509        jz      loc_4EB0EC
004B450F        lea     eax, [ebx+1F4h] ; 对象信息名称
004B4515        push    eax
004B4516        push    [ebp+var_28]    ; int
004B4519        push    esi
004B451A        push    ebx             ; 新进程的对象
004B451B        call    _MmInitializeProcessAddressSpace@16 ; 初始化新进程的地址空间
004B451B                       ; 把进程空间映射到内存
004B4520        mov     edi, eax
004B4522        cmp     edi, esi
004B4524        jl      loc_4B477C
004B452A        mov     [ebp+var_34], edi
004B452D        push    esi             ; 需要映射DLL的基地址
004B452E        push    ebx             ; 新进程的对象
004B452F        call    _PspMapSystemDll@8 ; 映射系统模块、指定进程的区对象(映射第一个DLL)ntdll.dll
004B4534        mov     edi, eax
004B4536        cmp     edi, esi
004B4538        jl      loc_4B477C
004B453E        mov     [ebp+var_1D], 1
004B4542
004B4542 loc_4B4542:                    ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+36E22↓j
004B4542                       ; PspCreateProcess(x,x,x,x,x,x,x,x,x)+79BBA↓j ...
004B4542        mov     edi, [ebx+0C8h]
004B4548        and     edi, 0FFFFFFF8h
004B454B        push    ebx
004B454C        call    _MmGetSessionId@4 ; 获取指定进程的会话ID
004B4551        push    eax             ; SessionId
004B4552        push    edi             ; Token
004B4553        call    _SeSetSessionIdToken@8 ; 设置令牌ID
004B4558        mov     [ebp+var_70], ebx
004B455B        mov     [ebp+var_6C], esi
004B455E        lea     eax, [ebp+var_70]
004B4561        push    eax
004B4562        push    _PspCidTable    ; 把该内核对象加入到进程现场对象表(pspcidtable)并得到进程ID
004B4568        call    _ExCreateHandle@8 ; 在pspCidTable中添加一项
004B456D        mov     [ebx+84h], eax
004B4573        cmp     eax, esi
004B4575        jz      loc_52DF0F
004B457B        mov     ecx, [ebx+0C4h]
004B4581        mov     [ecx+8], eax
004B4584        xor     ecx, ecx
004B4586        call    @SeDetailedAuditingWithToken@4 ; SeDetailedAuditingWithToken(x)
004B458B        test    al, al
004B458D        jnz     loc_52DF19
004B4593
004B4593 loc_4B4593:                    ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+79C50↓j
004B4593        mov     eax, [ebp+eprocess]
004B4596        cmp     eax, esi
004B4598        jz      short loc_4B45A8
004B459A        mov     eax, [eax+134h]
004B45A0        cmp     eax, esi
004B45A2        jnz     loc_52DF24
004B45A8
004B45A8 loc_4B45A8:                    ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+2C9↑j
004B45A8                       ; PspCreateProcess(x,x,x,x,x,x,x,x,x)+3F399↓j ...
004B45A8        cmp     [ebp+eprocess], esi
004B45AB        jz      short loc_4B45E1
004B45AD        cmp     [ebp+var_1D], 0
004B45B1        jz      short loc_4B45E1
004B45B3        xor     eax, eax
004B45B5        lea     edi, [ebp+var_40]
004B45B8        stosd
004B45B9        or      [ebp+var_3C], 0FFFFFFFFh
004B45BD        cmp     [ebp+arg_14], esi
004B45C0        jz      loc_52DFCA
004B45C6        lea     eax, [ebx+1B0h]
004B45CC        push    eax             ; int
004B45CD        lea     eax, [ebp+var_40]
004B45D0        push    eax             ; int
004B45D1        push    ebx             ; Process
004B45D2        call    _MmCreatePeb@12 ; 创建PEB
004B45D7        mov     edi, eax
004B45D9        cmp     edi, esi
004B45DB        jl      loc_52DFBF
004B45E1
004B45E1 loc_4B45E1:                    ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+2DC↑j
004B45E1                       ; PspCreateProcess(x,x,x,x,x,x,x,x,x)+2E2↑j ...
004B45E1        mov     edi, [ebp+currentThread]
004B45E7        dec     dword ptr [edi+0D4h]
004B45ED        mov     ecx, offset _PspActiveProcessMutex ; FastMutex
004B45F2        call    @ExAcquireFastMutexUnsafe@4 ; ExAcquireFastMutexUnsafe(x)
004B45F7        lea     eax, [ebx+88h]
004B45FD        mov     ecx, dword_49265C
004B4603        mov     [eax+_LIST_ENTRY.Flink], offset _PsActiveProcessHead ; 把新进程加入到全局进程链表中
004B4609        mov     [eax+_LIST_ENTRY.Blink], ecx
004B460C        mov     [ecx+_LIST_ENTRY.Flink], eax
004B460E        mov     dword_49265C, eax
004B4613        mov     ecx, offset _PspActiveProcessMutex ; FastMutex
004B4618        call    @ExReleaseFastMutexUnsafe@4 ; ExReleaseFastMutexUnsafe(x)
004B461D        inc     dword ptr [edi+0D4h]
004B4623        jnz     short loc_4B4630
004B4625        lea     eax, [edi+34h]
004B4628        cmp     [eax], eax
004B462A        jnz     loc_52DFFA
004B4630
004B4630 loc_4B4630:                    ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+354↑j
004B4630                       ; PspCreateProcess(x,x,x,x,x,x,x,x,x)+79D37↓j
004B4630        cmp     [ebp+eprocess], esi
004B4633        jz      short loc_4B463F
004B4635        mov     eax, _PsInitialSystemProcess
004B463A        cmp     [ebp+eprocess], eax
004B463D        jz      short loc_4B4642
004B463F
004B463F loc_4B463F:                    ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+364↑j
004B463F        mov     eax, [edi+44h]
004B4642
004B4642 loc_4B4642:                    ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+36E↑j
004B4642        mov     ecx, _PsProcessType
004B4648        add     ecx, 68h ; 'h'
004B464B        push    ecx             ; GenericMapping
004B464C        push    [ebp+DesiredAccess] ; AccessMask
004B464F        lea     ecx, [ebp+var_B8]
004B4655        push    ecx             ; int
004B4656        lea     ecx, [ebp+PassedAccessState]
004B465C        push    ecx             ; int
004B465D        push    eax             ; Process
004B465E        push    esi             ; Thread
004B465F        call    _SeCreateAccessStateEx@24 ; 判断父进程是否为系统进程,调用SeCreateAccessStateEx设置访问状态
004B4664        mov     edi, eax
004B4666        cmp     edi, esi
004B4668        jl      loc_4B477C
004B466E        lea     eax, [ebp+var_30]
004B4671        push    eax             ; Handle
004B4672        push    esi             ; NewObject
004B4673        push    1               ; ObjectPointerBias
004B4675        push    [ebp+DesiredAccess] ; DesiredAccess
004B4678        lea     eax, [ebp+PassedAccessState]
004B467E        push    eax             ; PassedAccessState
004B467F        push    ebx             ; Object
004B4680        call    _ObInsertObject@24 ; 插入一个对象到进程的功能表,并返回该对象的句柄值(可Hook)
004B4685        mov     edi, eax
004B4687        mov     [ebp+var_50], edi
004B468A        lea     eax, [ebp+PassedAccessState]
004B4690        push    eax
004B4691        call    _SeDeleteAccessState@4 ; SeDeleteAccessState(x)
004B4696        cmp     edi, esi
004B4698        jl      loc_4B4783
004B469E        mov     dword ptr [ebx+1A4h], 1
004B46A8        push    esi
004B46A9        push    ebx
004B46AA        call    _PsSetProcessPriorityByClass@8 ; PsSetProcessPriorityByClass(x,x)
004B46AF        cmp     [ebp+eprocess], esi
004B46B2        jz      loc_4E188E
004B46B8        mov     eax, [ebp+eprocess]
004B46BB        cmp     eax, _PsInitialSystemProcess
004B46C1        jz      loc_4E188E
004B46C7        lea     eax, [ebp+MemoryAllocated]
004B46CA        push    eax             ; MemoryAllocated
004B46CB        lea     eax, [ebp+SecurityDescriptor]
004B46CE        push    eax             ; SecurityDescriptor
004B46CF        push    ebx             ; Object
004B46D0        call    _ObGetObjectSecurity@12 ; ObGetObjectSecurity(x,x,x)
004B46D5        mov     edi, eax
004B46D7        mov     [ebp+var_50], edi
004B46DA        cmp     edi, esi
004B46DC        jl      loc_52E00B
004B46E2        mov     [ebp+SubjectSecurityContext.ProcessAuditId], ebx
004B46E8        push    ebx             ; Process
004B46E9        call    _PsReferencePrimaryToken@4 ; PsReferencePrimaryToken(x)
004B46EE        mov     [ebp+SubjectSecurityContext.PrimaryToken], eax
004B46F4        mov     [ebp+SubjectSecurityContext.ClientToken], esi
004B46FA        lea     eax, [ebp+AccessStatus]
004B46FD        push    eax             ; AccessStatus
004B46FE        lea     eax, [ebx+1A4h]
004B4704        push    eax             ; GrantedAccess
004B4705        push    dword ptr [ebp+PreviousMode] ; AccessMode
004B4708        mov     eax, _PsProcessType
004B470D        add     eax, 68h ; 'h'
004B4710        push    eax             ; GenericMapping
004B4711        push    esi             ; Privileges
004B4712        push    esi             ; PreviouslyGrantedAccess
004B4713        push    2000000h        ; DesiredAccess
004B4718        push    esi             ; SubjectContextLocked
004B4719        lea     eax, [ebp+SubjectSecurityContext]
004B471F        push    eax             ; SubjectSecurityContext
004B4720        push    [ebp+SecurityDescriptor] ; SecurityDescriptor
004B4723        call    _SeAccessCheck@40 ; SeAccessCheck(x,x,x,x,x,x,x,x,x,x)
004B4728        mov     [ebp+var_22], al
004B472B        mov     edx, [ebp+SubjectSecurityContext.PrimaryToken]
004B4731        lea     ecx, [ebx+0C8h]
004B4737        call    @ObFastDereferenceObject@8 ; ObFastDereferenceObject(x,x)
004B473C        push    dword ptr [ebp+MemoryAllocated] ; MemoryAllocated
004B473F        push    [ebp+SecurityDescriptor] ; SecurityDescriptor
004B4742        call    _ObReleaseObjectSecurity@8 ; ObReleaseObjectSecurity(x,x)
004B4747        cmp     [ebp+var_22], 0
004B474B        jz      loc_52E01B
004B4751
004B4751 loc_4B4751:                    ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+79D52↓j
004B4751        or      dword ptr [ebx+1A4h], 1F07FBh
004B475B
004B475B loc_4B475B:                    ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+2D5C9↓j
004B475B        lea     eax, [ebx+70h]
004B475E        push    eax             ; CurrentTime
004B475F        call    _KeQuerySystemTime@4 ; KeQuerySystemTime(x)
004B4764        mov     [ebp+ms_exc.registration.TryLevel], esi
004B4767        mov     eax, [ebp+arg_0]
004B476A        mov     ecx, [ebp+var_30]
004B476D        mov     [eax], ecx
004B476F        or      [ebp+ms_exc.registration.TryLevel], 0FFFFFFFFh
004B4773
004B4773 loc_4B4773:                    ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+79D74↓j
004B4773        cmp     [ebp+var_34], esi
004B4776        jnz     loc_52E048
004B477C
004B477C loc_4B477C:                    ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+146↑j
004B477C                       ; PspCreateProcess(x,x,x,x,x,x,x,x,x)+18C↑j ...
004B477C        mov     ecx, ebx        ; Object
004B477E        call    @ObfDereferenceObject@4 ; 减少内核对象的引用计数
004B4783
004B4783 loc_4B4783:                    ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+B8↑j
004B4783                       ; PspCreateProcess(x,x,x,x,x,x,x,x,x)+3C9↑j
004B4783        mov     ecx, [ebp+eprocess] ; Object
004B4786        cmp     ecx, esi
004B4788        jz      short loc_4B478F
004B478A        call    @ObfDereferenceObject@4 ; ObfDereferenceObject(x)
004B478F
004B478F loc_4B478F:                    ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+4B9↑j
004B478F        mov     eax, edi
004B4791
004B4791 loc_4B4791:                    ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+6F↑j
004B4791                       ; PspCreateProcess(x,x,x,x,x,x,x,x,x)+79AC1↓j
004B4791        call    __SEH_epilog
004B4796        retn    24h ; '$'
004B4796 ; } // starts at 4B42CF
004B4796 _PspCreateProcess@36 endp

线程结构体

_kthread

+0x000 Header           : _DISPATCHER_HEADER  // 可等待对象

+0x010 MutantListHead   : _LIST_ENTRY   // 互斥体的双向链表
+0x018 InitialStack     : Ptr32 Void    //原始栈底
+0x01c StackLimit       : Ptr32 Void    // 栈顶的最低地址(栈界限)
+0x020 Teb              : Ptr32 Void    // 线程控制块

+0x024 TlsArray         : Ptr32 Void
+0x028 KernelStack      : Ptr32 Void  //内核的栈顶,也就是ESP 
+0x02c DebugActive      : UChar  调试状态

+0x02d State            : UChar
+0x02e Alerted          : [2] UChar  //线程是否被唤醒

+0x030 Iopl             : UChar
+0x031 NpxState         : UChar  //浮点的状态
+0x032 Saturation       : Char


+0x033 Priority         : Char         //线程优先级
+0x034 ApcState         : _KAPC_STATE  //存储APC的所有信息

+0x04c ContextSwitches  : Uint4B
+0x050 IdleSwapBlock    : UChar
+0x051 Spare0           : [3] UChar

//线程等待
+0x054 WaitStatus       : Int4B
+0x058 WaitIrql         : UChar  //等待中断请求级别
+0x059 WaitMode         : Char   //等待的模式
+0x05a WaitNext         : UChar  //下一个等待
+0x05b WaitReason       : UChar  //线程等待的理由
+0x05c WaitBlockList    : Ptr32 _KWAIT_BLOCK  //等待块
+0x060 WaitListEntry    : _LIST_ENTRY //等待线程链表


+0x060 SwapListEntry    : _SINGLE_LIST_ENTRY  //当内核栈需要被换入的时候
+0x068 WaitTime         : Uint4B  //等待的时间
+0x06c BasePriority     : Char    //基本优先级

+0x06d DecrementCount   : UChar
+0x06e PriorityDecrement : Char
+0x06f Quantum          : Char

+0x070 WaitBlock        : [4] _KWAIT_BLOCK  //等待块
+0x0d0 LegoData         : Ptr32 Void
+0x0d4 KernelApcDisable : Uint4B            //禁用普通的内核APC

+0x0d8 UserAffinity     : Uint4B
+0x0dc SystemAffinityActive : UChar
+0x0dd PowerState       : UChar
+0x0de NpxIrql          : UChar
+0x0df InitialNode      : UChar

+0x0e0 ServiceTable     : Ptr32 Void     //系统服务表
+0x0e4 Queue            : Ptr32 _KQUEUE  //分发器对象
+0x0e8 ApcQueueLock     : Uint4B  

+0x0f0 Timer            : _KTIMER      //线程定时器  waitforsingleobject
+0x118 QueueListEntry   : _LIST_ENTRY  //线程处理队列时候的链表


+0x120 SoftAffinity     : Uint4B
+0x124 Affinity         : Uint4B  //线程亲和性
+0x128 Preempted        : UChar   // 当前线程有没有被高优先级抢占

+0x129 ProcessReadyQueue : UChar    //判断线程是否在进程的就绪链表里面
+0x12a KernelStackResident : UChar  //内核是否在内存中

+0x12b NextProcessor    : UChar        //下一个处理器
+0x12c CallbacStack    : Ptr32 Void    //线程堆栈回调
+0x130 Win32Thread      : Ptr32 Void   //GUI线程

+0x134 TrapFrame        : Ptr32 _KTRAP_FRAME // 线程切换保存环境

+0x138 ApcStatePointer  : [2] Ptr32 _KAPC_STATE //APC的状态 0正常  1 挂靠

+0x140 PreviousMode     : Char
+0x141 EnableStackSwap  : UChar
+0x142 LargeStack       : UChar
+0x143 ResourceIndex    : UChar

+0x144 KernelTime       : Uint4B  // 内核时间
+0x148 UserTime         : Uint4B  //用户的时间

+0x14c SavedApcState    : _KAPC_STATE  //保存APC的状态
+0x164 Alertable        : UChar
+0x165 ApcStateIndex    : UChar //APC状态索引
+0x166 ApcQueueable     : UChar
+0x167 AutoAlignment    : UChar
+0x168 StackBase        : Ptr32 Void  //栈基址
+0x16c SuspendApc       : _KAPC       //挂起的APC

+0x19c SuspendSemaphore : _KSEMAPHORE  
+0x1b0 ThreadListEntry  : _LIST_ENTRY  // 线程链表 (进程里面50--》 线程 1b0)
+0x1b8 FreezeCount      : Char
+0x1b9 SuspendCount     : Char  //挂起计数
+0x1ba IdealProcessor   : UChar // 线程的理想处理器

+0x1bb DisableBoost     : UChar

_ethread

+0x000 Tcb              : _KTHREAD
+0x1c0 CreateTime       : _LARGE_INTEGER  //线程的创建时间
+0x1c0 NestedFaultCount : Pos 0, 2 Bits
+0x1c0 ApcNeeded        : Pos 2, 1 Bit

+0x1c8 ExitTime         : _LARGE_INTEGER   //线程的退出时间
+0x1c8 LpcReplyChain    : _LIST_ENTRY      //跨进程通信
+0x1c8 KeyedWaitChain   : _LIST_ENTRY      // 代建事件等待链表

+0x1d0 ExitStatus       : Int4B  //线程的退出状态
+0x1d0 OfsChain         : Ptr32 Void


+0x1d4 PostBlockList    : _LIST_ENTRY //线程配置注册表键的变化通知


+0x1dc TerminationPort  : Ptr32 _TERMINATION_PORT //线程退出时候,终止事件的端口
+0x1dc ReaperLink       : Ptr32 _ETHREAD          //线程退出时候,回收
+0x1dc KeyedWaitValue   : Ptr32 Void              // 代建等待的键值


+0x1e0 ActiveTimerListLock : Uint4B      //定时器链表的自旋锁
+0x1e4 ActiveTimerListHead : _LIST_ENTRY //当前线程的所有定时器
+0x1ec Cid              : _CLIENT_ID     //线程ID


+0x1f4 LpcReplySemaphore : _KSEMAPHORE  // LPC应答通知
+0x1f4 KeyedWaitSemaphore : _KSEMAPHORE //LPC代键事件
+0x208 LpcReplyMessage  : Ptr32 Void    //LPC应答消息
+0x208 LpcWaitingOnPort : Ptr32 Void    //LPC的等待端口


+0x20c ImpersonationInfo : Ptr32 _PS_IMPERSONATION_INFORMATION //线程的模仿信息
+0x210 IrpList          : _LIST_ENTRY          //线程未完成的I/O请求(IRP对象)
+0x218 TopLevelIrp      : Uint4B               //线程顶级的IRP
+0x21c DeviceToVerify   : Ptr32 _DEVICE_OBJECT //设备对象

+0x220 ThreadsProcess   : Ptr32 _EPROCESS //当前线程所属的进程(父进程)

+0x224 StartAddress     : Ptr32 Void      //线程启动的地址

+0x228 Win32StartAddress : Ptr32 Void     //子系统启动的地址
+0x228 LpcReceivedMessageId : Uint4B

+0x22c ThreadListEntry  : _LIST_ENTRY      //线程链表 (进程190--》线程22c)

+0x234 RundownProtect   : _EX_RUNDOWN_REF  //线程停止保护锁
+0x238 ThreadLock       : _EX_PUSH_LOCK    //线程锁
+0x23c LpcReplyMessageId : Uint4B          //当前线程正在等待一个消息的应答
+0x240 ReadClusterSize  : Uint4B           //在I/O操作时读取了多少页面
+0x244 GrantedAccess    : Uint4B           //线程的访问权限

+0x248 CrossThreadFlags : Uint4B        //跨进程访问标志
+0x248 Terminated       : Pos 0, 1 Bit  //线程终止操作
+0x248 DeadThread       : Pos 1, 1 Bit  //线程创建失败
+0x248 HideFromDebugger : Pos 2, 1 Bit  //该线程对调试器不可见
+0x248 ActiveImpersonationInfo : Pos 3, 1 Bit   //线程正在模仿
+0x248 SystemThread     : Pos 4, 1 Bit          //是一个系统线程
+0x248 HardErrorsAreDisabled : Pos 5, 1 Bit     //对于该线程,硬件错误无效
+0x248 BreakOnTermination : Pos 6, 1 Bit //调试器在线程终止时 停下该线程
+0x248 SkipCreationMsg  : Pos 7, 1 Bit   //不向调试器发送创建消息
+0x248 SkipTerminationMsg : Pos 8, 1 Bit //不向调试器发送终止消息


+0x24c SameThreadPassiveFlags : Uint4B  //最低中断级别才能访问的标志
+0x24c ActiveExWorker   : Pos 0, 1 Bit
+0x24c ExWorkerCanWaitUser : Pos 1, 1 Bit
+0x24c MemoryMaker      : Pos 2, 1 Bit


+0x250 SameThreadApcFlags : Uint4B  //APC中断级别被该线程自身访问的标志位
+0x250 LpcReceivedMsgIdValid : Pos 0, 1 Bit
+0x250 LpcExitThreadCalled : Pos 1, 1 Bit
+0x250 AddressSpaceOwner : Pos 2, 1 Bit
+0x254 ForwardClusterOnly : UChar
+0x255 DisablePageFaultClustering : UChar

NtCreateThread

线程创建过程


文章作者: Kevin。
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Kevin。 !
评论
 上一篇
KiSwapThread线程切换 KiSwapThread线程切换
KiSwapThread线程切换KiSwapThread是通过切换线程上下文来实现线程切换的函数 KiSwapThread主函数0040AB8A mov edi, edi 0040AB8C push
2022-05-23
下一篇 
编写驱动Hook SSDT 编写驱动Hook SSDT
编写驱动Hook SSDT查找函数偏移要hook SSDT中的函数,就必须先找到这个函数在SSDT表中的偏移才能修改这个偏移上的地址 随意打开一个程序,下个API调用时候的断点,这里下writeFile的断点 F8调试指导出现调用ntdl
2022-05-14
  目录