CreateProcess的流程 考虑管道

CreateProcess的流程                            

     到这章为止,你已经了解了进程相关的数据结构以及让你(或者操作系统)可以拿来操作进程的Windows API。你也可以知道如何使用工具了解系统与进程之间是如何相互作用的。但是这些进程是怎么开始的,在完成了任务之后又是如何退出的?在接下来的部分你将了解到Windows进程是如何产生的。
     一个Windows进程会在某应用程序调用了一个进程创建函数,比如CreateProcess、CreateProcessAsUser、CreateProcessWithTokenW或者CreateProcessWithLogonW之后被创建。创建Windows进程的工作由发生在操作系统的三个不同部分中几个阶段组成,三个部分是指:Windows 客户端库 Kernel32.dll、Windows执行体以及Windows子系统进程Csrss。由于Windows的结构中包含了多个环境子系统,所以创建Windows执行体进程物件(该物件其他子系统也可以使用)是与创建Windows进程的工作分离的。所以,虽然后面对于函数CreateProcess的描述有点复杂, 但请记得相对于创建Windows执行体进程物件这个核心工作而言,某些部分只是Windows子系统为语义考虑而添加的。
     以下列表概述了使用函数CreateProcess创建进程的主要阶段。每一阶段所作的操作会在后面详述。

    1. 打开要在进程中执行的文件(.exe)。
    2. 创建Windows执行体进程物件。
    3. 创建主线程(栈、上下文以及Windows执行体线程物件)。
    4. 告知子系统要创建新进程以配置新进程及其线程。
    5. 开始执行主线程(除非指定了标识CREATE_ SUSPENDED)。
    6. 在新进程的上下文中完成地址空间的初始化(如加载所需的DLLs)并开始执行程序。

     Figure 6-5所示为Windows创建进程的简图。
     在打开可执行文件之前,CreateProcess要做以下工作:

    + 对于CreateProcess,可以逐位设置参数CreationFlags指定新进程的优先级。因此,你可以在一次CreateProcess调用中指定不止一个优先级。Windows会选择其中最低的那个优先级赋予进程。
    + 如果没有为新进程指定优先级,默认的优先级为NORMAL_PRIORITY_CLASS,除非其优先级为IDLE_PRIORITY_CLASS 或者 BELOW_NORMAL_PRIORITY_CLASS,在此情况下,新进程的优先级就会继承其父进程的。
    + 如果新进程的优先级被指定为REALTIME_PRIORITY_CLASS而进程的调用者却没有Increase Scheduling Priority特权,就会将新进程的优先级改为HIGH_PRIORITY_CLASS。换句话说,CreateProcess不会因为调用者没有足够的特权创建一个REALTIME_PRIORITY_CLASS进程而失败;而新进程也不会有一个REALTIME_PRIORITY_CLASS优先级。
    + 所有的窗口都会与桌面(工作区的图形化表示)关联。如果没有在CreateProcess中指定桌面,该进程就会被关联到调用者的当前桌面。

 阶段1:打开可执行文件                           

     如Figure6-6所示,CreateProcess的第一步是找到合适Windows 程序以执行由调用者指定的可执行文件并创建一个section object再在之后将其映射到新进程的地址空间。如果没有指定程序名,那么命令行的第一个记号(其定义为命令行字符串的第一部分,以空格或者tab作为有效分隔符)就会被作为可执行文件名。
     在Windows XP和Windows Server 2003中,CreateProcess会检查本机的软件限制策略是否会阻止该程序执行。
     如果可执行文件为Windows的.exe文件,就会被直接使用。如果不是.exe文件(比如是一个MS-DOS、Win16或者POSIX程序),CreateProcess就会做一系列动作找到一个支持该文件的Windows 程序。这一过程的必要性是缘于非Windows程序不能直接运行——于是Windows从几个程序中选择一个负责实际执行该文件。比如,你要运行一个POSIX程序,CreateProcess就会运行程序Posix.exe。如果要运行的是一个MS-DOS或者Win16程序,就会运行程序Ntvdm.exe。简单来说,你不能直接创建一个非Windows的进程。如果Windows不能找到一个Windows进程能够执行的Windows程序 (参见Table 6-5), CreateProcess就宣告失败。
     CreateProcess在执行程序的过程中所遍历的决策树如下:

    + 如果是一个后缀名为.exe、.com或者.pif的MS-DOS的应用程序,就会向Windows子系统发送一条消息检查该会话是否已经创建了一个MS-DOS的支持进程(在注册表值HKLM\SYSTEM\CurrentControlSet\Control\WOW\cmdline中指定的Ntvdm.exe)。如果已经指定,就用它来运行该MS-DOS应用程序(Windows子系统会发送消息给VDM[Virtual DOS Machine]进程以执行程序)。然后CreateProcess返回。如果支持进程尚未创建,那么首先要执行的程序就变成了Ntvdm.exe,而CreateProcess重新回到阶段1。
    + 如果可执行文件的后缀为.bat或者.cmd,要执行的程序就变成了Cmd.exe——Windows命令行提示符,而CreateProcess重新回到阶段1(批处理文件的文件名被作为第一个参数传递给了Cmd.exe)。
    + 如果是 Win16 (Windows 3.1)可执行文件,CreateProcess就需要判断是要创建一个新的VDM进程还是使用默认的会话范围内共享的VDM进程(该进程也可能尚未创建)。这由CreateProcess的标识CREATE_SEPARATE_WOW_VDM / CREATE_SHARED_WOW_VDM 来决定。如果未指定该标识,就根据注册表值HKLM\SYSTEM\CurrentControlSet\Control\WOW\ DefaultSeparateVDM采取默认行为。如果程序要在一个独立的VDM中运行,那么要执行的就变为注册表值HKLM\SYSTEM\CurrentControlSet\Control\WOW\wowcmdline中所指定的而CreateProcess重新回到阶段1。否则,Windows子系统发送消息以查看是否存在一个可用的共享VDM进程(如果该VDM进程与调用者使用不同的桌面或安全上下文,就不可用,必须要创建一个新的)。如果该共享VDM可用,Windows子系统就发送消息让它运行一个新程序而CreateProcess返回。如果该VDM未被创建(或存在而不可用),就转而运行VDM支持程序且CreateProcess重新回到阶段1。

     到此为止,CreateProcess已经成功地打开了一个Windows可执行文件并为它创建了一个section object。该物件尚未被映射进内存,但它是打开的。但是,能成功创建一个section object并不意味着相应的文件是一个有效的Windows程序,它可能是一个DLL或者POSIX可执行文件。如果是一个POSIX可执行文件,那么就要转而执行Posix.exe,而CreateProcess重新回到阶段1。如果是DLL,那么CreateProcess就宣告失败。   
     现在CreateProcess已经找到了一个有效的可执行程序,它需要查看注册表键HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options 看是否存在一个对应于可执行程序的文件名及后缀的子键(不含路径信息——比如,Image.exe)。如果存在,CreateProcess就在该键中寻找一个叫Debugger的值。如果找到,执行程序就变为该值所表示的,而CreateProcess重新回到阶段1。

     你可以利用的这一行为在Windows服务进程启动前调式其启动代码而不是在它们启动之后使用调式器(它不能调式启动代码)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值