由应用程序调用 Windows API 创建的进程,可通过如下方式创建:
- 调用 CreateProcess 函数: 使用与创建者相同的访问令牌创建进程
- 调用 CreateProcessAsUser 函数: 使用指定的访问令牌创建进程
- 调用 CreateProcessWithLogonW 函数: 使用特定用户凭据登录,并使用该用户的访问令牌创建进程
- 调用 CreateProcessWithTokenW 函数
不通过 Windows API ,直接调用内核函数创建的进程,通常为 Windows 原生进程、最小进程或 Pico 进程。
CreateProcess 或 CreateProcessAsUser ===> CreateProcessInternal ===> NtCreateUserProcess ===> NtCreateUserProcess
说明:
- 应用程序调用 【kernel32.dll】 中的 CreateProcess 或 CreateProcessAsUser 函数
- 调用 【kernel32.dll】 中的 CreateProcessInternal 函数
- 调用 【ntdll.dll】 中的 NtCreateUserProcess 函数
- 调用 【执行体】 中的 NtCreateUserProcess 函数
其中 执行体 中的操作使用内核模式,其他部分操作使用用户模式
CreateProcessWithLogonW 或 CreateProcessWithTokenW ===> SlrCreateProcessWithLogon ===> CreateProcessAsUser ===> NtCreateUserProcess ===> NtCreateUserProcess
说明:
- 应用程序调用 【advapi32.dll】 中的 CreateProcessWithLogonW 或 CreateProcessWithTokenW 函数
- RPC 方式调用 【svchost.exe】【seclogon.dll】 中的 SlrCreateProcessWithLogon 函数
- 调用 【svchost.exe】【kernel32.dll】 中的 CreateProcessAsUser 函数
- 调用 【svchost.exe】【ntdll.dll】 中的 NtCreateUserProcess 函数
- 调用 【执行体】 中的 NtCreateUserProcess 函数
其中 执行体 中的操作使用内核模式,其他部分操作使用用户模式
NtCreateUserProcess
说明:
Windows 特殊进程直接调用 NtCreateUserProcess 函数创建进程
Windows 不同的部件维护了不同的进程数据结构,主要的结构如下:
- EPROCESS 结构: Windows 进程的主结构
- CSR_EPROCESS 结构: Windows 子系统进程(csrss)维护的进程数据结构
- W32PROCESS 结构: Windows 子系统的内核模式(win32k.sys)部分维护的进程数据结构,当线程首次调用 Windows 并在内核模式中实现 USER 或 GUI 函数时创建的
- KPROCESS 结构: EPROCESS 中 进程控制块(PCB) 的数据结构
Windows 进程的主数据结构,除进程环境块(PEB)位于进程(用户)地址空间外,其余主要部分都位于系统地址空间中,主要有以下组成部分:
- 进程控制块(PCB)
- 保护锁
- 进程 ID 和父进程 ID
- 活动进程链接
- 进程标志
- 进程创建和退出时间
- 配额信息
- 会话进程链接
- 安全/异常/调试端口
- 主访问令牌
- 该进程所属的作业
- 句柄表
- 进程环境块(PEB)
- 映像文件名
- 映像基址
- 进程计数器(内存、I/O等)
- 线程列表头
- 序列号
- Win32K进程结构
- Wow64进程结构(仅 64 位)
- Trustlet标识(Win 10 x64)
- 能耗值(Win 10)
- Pico上下文(Win 10)
- 保护级别和签名
- DirectX进程
- 工作集
- 节对象
EPROCESS 结构中进程控制块(PCB)的数据结构,其主要有以下组成部分:
- 分发器头
- 进程页面目录基
- 内核时间
- 用户时间
- 周期时间
- 上下文切换
- 线程列表头
- 进程锁
- 进程相关性
- 进程标志
- 理想节点
- 线程种子
- 基准优先级
- 进程列表项
- Instrumentation回调
- 安全进程ID
由 Windows 子系统进程(csrss)维护的进程数据结构,仅 Windows 应用程序才有相关联的 CSR_EPROCESS 结构。
由于每个会话都有自己的 Windows 子系统实例,所以 CSR_EPROCESS 结构是由每个会话的 Windows 子系统进程维护的。
其主要有以下组成部分:
- 客户端ID
- 进程链接
- 线程列表头
- 客户端端口句柄
- 进程句柄
- 客户端视图数据
- 会话数据
- 进程标志
- 引用计数
- 消息数据
- 关闭级别
- 标志
- 进程组数据
- 服务器数据
由 Windows 子系统的内核模式(win32k.sys)部分维护的进程数据结构,当线程首次调用 Windows 并在内核模式中实现 USER 或 GUI 函数时创建的,包含了内核(win32k)中 Windows 图形和窗口管理代码维护 GUI 进程状态信息所需的全部信息。
其主要有以下组成部分:
- 进程
- 引用次数
- 标志
- 进程 ID
- GDI 句柄计数和峰值
- USER 句柄计数和峰值
- 进程链接
- GDI 列表
- DirectX进程数据
- DirectComposition进程数据
当一个进程所使用的令牌包含调试权限时,可向计算机上运行的其他任何进程请求所有访问权限,此时对某些进程来说便会存在风险,因此 Windows 提出了 “受保护的进程” 的概念,其属于一种特殊的进程,其他进程无法访问到受保护的进程的相关信息,受保护的进程需要由使用了 Windows 颁发的数字签名的映像文件创建。
Windows 中常见的受保护进程有:
- system 进程
- 音频设备图形进程(audiodg.exe)
- 媒体基础受保护管道(mfpmp.exe)
- Windows 错误报告客户端进程(werfaultsecure.exe)
受保护的进程创建过程是在内核模式下进行的,它会在自己的 eprocess 结构中设置一个特殊位,借此修改进程管理器中与安全有关的例程的行为,进而拒绝通常会授予管理员的某些访问权限。
受保护进程轻型(PPL)可以得到与传统受保护进程相同的保护,但其新增了一个属性值的维度,可用于标记不同的签名方,从而针对不同的签名方授予不同程度的保护。
PPL的签名方主要有:
- WinSystem: 优先级最高,主要供 system 进程以及 memory compression 进程等最小进程使用
- WinTcb: 对用户模式进程来说的最高优先级,可用于保护关键进程
- Windows
- Lsa
- Anti-malware
- Authenticode
受保护进程的能力始终胜过受保护进程轻型,高优先级签名方的进程可以访问低优先级签名方的进程,但是反之不行。
为了防止注入攻击,进程加载任何 DLL 都必须和主执行文件一样经过代码完整性组件的检查。
借助 PPL ,可实现反恶意软件程序,AM主要包括的组件如下:
- 内核驱动程序: 负责拦截文件系统或网络 I/O 请求,并使用对象、进程和线程回调实现阻止功能
- 用户模式的服务: 配置驱动程序的配置文件,从驱动程序处接收有关 “值得关注” 事件(例如有文件被感染)的通知,并可能要与本地服务器或互联网通信
- 用户模式的 GUI 进程: 向用户报告相关信息,让用户在必要时做出处理决策
运行 AM 时需要预先启动反恶意软件驱动程序(ELAM),其需要微软提供的特殊反恶意软件证书。
进程结构不完整的一种进程,其缺少部分常规进程的结构,Windows 中的最小进程有:
- system 进程
- memory compression 进程
- secure system 进程(启用基于虚拟化的安全性时)
Pico 进程需要依赖于 Pico 提供程序,Pico 提供程序 必须先于任何第三方驱动程序(包括引导驱动程序)加载。