Windows 过程创立过程

一、过程创立函数

Windows API 提供了多个创立过程的函数,最简略的是CreateProess(),该函数创立一个和以后过程具备雷同用户Token的过程。

如果想要创立和以后过程具备不同用户Token的过程,则须要应用CreateProcessAsUser(),该函数能够承受一个Token句柄作为参数,并创立一个具备该Token的过程。

其余创立过程的函数还包含CreateProcessWithTokenW()以及CreateProcessWithLogonW()(都是advapi.dll的导出函数)。CreateProcessWithTokenW()和函数CreateProcessAsUser()很类似,然而两者对以后过程Token的权限要求不同。CreateProcsssWithTokenW()须要以后过程中的用户Token具备 SE_IMPERSONATE_NAME 权限,CreateProcessWithLogonW()则须要以后过程中具备 SE_INCREASE_NOT_HELD 权限。

CreateProcessWithLogonW()是通过用户凭证登录并创立具备对应用户Token的过程的便捷形式。

这两个函数都要通过 RPC 来调用位于 Svchost.exe 中的 SecLogon.dll 来实现理论的过程创立。SecLogon 调用位于外部的SLrCreatePrcoessWithLogonW()函数,如果该过程顺利进行,最终会调用CreateProcssAsUser()函数。

SecLogon 服务被默认配置为手动启动,所以当第一次调用 CreateProcessWithTokenW() 以及 CreateProcessWithLogonW() 时,该服务会被启动。如果该服务启动失败,则这两个函数也无奈执行。罕用的命令runas,就调用了这两个函数。

用户态创立过程函数调用流程图:

二、过程创立过程

下面所形容的4个函数都只能对一个具备的PE文件构造的文件(不须要有.exe拓展)、批处理文件或者16位COM利用进行解决。

对于除了这三种文件外的其余类型的文件,上述的这些函数不晓得如何依据文件拓展名来定位到能够执行的应用程序 ( 比方:不能依据.txt扩大定位到,能够启动 Notepad 来关上该txt文件。

然而Windows Shell 提供了这种定位性能,就是对于函数ShellExecute()以及ShellExecuteEx()来说,其能够承受一个非可执行文件作为输出,并且能够依据其拓展名以及位于HKEY_CLASSES_ROOT中的设置来定位适合的可执行程序来关上这些文件。最初,这两个函数会通过具备适合的命令行参数的CreateProcess()函数实现用户须要的用意。

CreateProcess()函数会首先找到咱们指定的可执行文件映像,并创立一个内存区域,稍后会调用其余函数将该文件映像映射到过程的地址空间中。此外,当然,依据不同的文件映像名和参数,该函数还会启动其余程序来反对指定文件类型的运行,并从新执行CreateProcess()函数。

之后,如上图所述,CreateProcess() 函数会调用 CreateProcessInternel()。该函数实现创立一个用户模式过程的理论工作。

-->CreateProcessInternel()首先会对传入的参数进行一些判断,并将参数或者构造体中的ANSI格局的字符串转化为Unicode字符串.-->再做一些初始化和判断后,会调用NtOpenFile()失去映像文件句柄,并调用NtCreateSection()来失去内存区句柄,即咱们所说的过程用户空间的虚拟地址空间会在这一步实现创立。-->接着会调用BaseplsProcessAllowed()函数来判断应用程序是否在受权文件列表中,该函数通过调用 NtOpenKey()函数关上注册表的 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Option键-->失去过程对应的内存区对象句柄后,调用NtQuerySection()函数,返回失去的节的根本信息(基址、大小、属性)-->而后对映像文件信息的有效性进行判断,判断是否蕴含DEBUG_PROCESS或者DEBUG_ONLY_THIS_PROCESS,查看机器类型、子系统版本号、控制台、GUI等,并通过BaseIsImageVersionOk()判断镜像文件版本是否非法。-->如果创立标记中蕴含DEBUG_PROCESS或者DEBUG_ONLY_THIS_PROCESS(即以后处于调试模式中),就加载advapi32.dl并获取CreateProcessAsSecure()函数的地址。-->而后调用BaseFormatObjectAttrubutes()将平安属性构造(对于过程平安、权限方面的信息)格局为NT对象属性构造(失去了对象属性)。-->接着调用_DbgUiConnectToDbg()实现通过调用NtCreateDebugObject()函数来创立调试对象,调用DbgUiGetThreadObject()来取得调试对象。

而最终,CreateProcessInternel()会调用位于NTdll.dll中的NtCreateUserProcess()来转换到位于内核模式的执行体模块中的同名函数中,实现过程创立过程内核局部的行为。

此外,内核中的 执行体模块还反对必须绕过Windows API的过程 的创立。例如:native processesminimal processes,以及 Pico processes

像 Smss(the Session Manager) 就是一个 native process,其间接被内核创立,显然不会应用CreateProcess()接口,而是间接调用进入执行体模块的NtCreateUserProcess()函数中。同样的,当 Smss 创立 Autochk(检测磁盘组件) 或者 Csrss (Windows subsystem process) 时,Windows API 也是不可用的。此外,native processes 也不能作为 Windows应用程序 被创立,因为CreatePrcoessInternel()会回绝具备 native subsysem 映像类型的内存映像。而为了加重上诉的复杂性Ntdll.dll中存在一个封装于NtCreateUserProcess()的函数RtlCreateUserProcess()

对于一些内核模式的过程,比方 System process 以及 Memory Compression processes(minimal processes) 以及被 Windows Subsystem for Linux 治理的 Pico procsses 。这些过程的创立通过调用NtCreateProcessEx()函数(仅仅能被内核态过程调用)实现。

对于被 Pico providers 治理的过程,在创立时,Pico providers会调用一个帮忙函数 PspCreatePicoProcess(),该函数不仅能够创立 minimal process,也会初始化 Pico provider上下文环境。该函数并未导出,仅仅可能被 Pico providers 通过其非凡接口调用。

最初,尽管NtCreateProcessEx()以及函数NtCreateUserProcess()是不同的零碎调用,但这两个函数最初会调用雷同的外部子例程[PspAllocateProcess()以及PspInsertProcess()] 来实现创立过程的工作。并且,所有的你能举进去的创立过程的形式,从WMI Powershell cmdlet到 内核驱动,都会在这两个函数处终止。

三、参考

1. 链接:

郑瀚Andrew_Hann

2. 书籍

Windows Internals 7th Edition Part 1