CreateProcess()函数

本文详细介绍了Windows API中的CreateProcess()函数,包括其调用原理、函数原型、参数说明。创建进程时,系统会创建进程内核对象和线程内核对象,分配虚拟地址空间,并加载可执行文件。同时,文章解析了函数参数如lpApplicationName、lpCommandLine等的用途,以及如何通过SECURITY_ATTRIBUTES设置安全属性。最后,提到了STARTUPINFO和PROCESS_INFORMATION结构体在创建进程过程中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

调用原理

当调用CreateProcess()函数时,系统所做的工作:

  1. 系统创建一个进程内核对象,初始使用计数为1;(进程内核对象并不代表进程本身,而是操作系统用来管理这个进程的一个数据结构)
  2. 系统为新进程创建一个虚拟地址空间,并且将可执行文件的代码及数据加载到进程的地址空间;
  3. 系统为新进程创建一个主线程内核对象,使用计数为1;(线程内核对象是操作系统用来管理线程的数据结构)

注释:内核对象

头文件

#include <windows>

CreateProcess()函数原型

BOOL CreateProcess(
LPCTSTR lpApplicationName, //可执行程序名
LPTSTR lpCommandLine, //命令行字符串,可以为NULL
LPSECURITY_ATTRIBUTES lpProcessAttributes, //新进程对象的安全属性
LPSECURITY_ATTRIBUTES lpThreadAttributes, //新进程对应的线程安全属性
BOOL blnheritHandles, //指定父进程的对象句柄能否被子进程继承
DWORD dwCreationFlags, //指定创建进程的附加标记,即指定新进程的特性
LPVOID lpEnvironment, //指定新进程使用的环境,NULL表示同父进程的环境
LPCTSTR lpCurrentDirection, //指定子进程当前路径,NULL表示同父进程相同
LPSTARTUPINFO lpStartupInfo, //指定新进程主窗口如何显示
LPPROCESS_INFORMATION lpProcessInformation, //作为返回值使用,是一个指针
);

参数说明

  1. LPCTSTR类型
    L:代表 Long,为了windows向后兼容,没有实际意义
    P:代表 Pointer
    C:代表 const 常量
    _T:在 Windows 32 中有一个_T宏
    STR:代表 String 表示这个变量是一个字符串

LPCTSTR 和 LPWSTR 是 Win32 和VC++ 所使用的一种字符串数据类型。一般情况下,LPCTSTR 相当于常量类型的字符串指针,即 LPCTSTR = const *char ;LPTSTR 相当于普通字符串,即 LPTSTR = *char,非常量可修改;

  1. SECURITY_ATTRIBUTES 类型

    为函数创建对象时提供安全性设置

typedef struct _SECURITY_ATTRIBUTES
{
   DWORD nlength; //结构体大小,可用sizeof()取得
   LPVOID lpSecurityDescriptor; //安全描述符
   BOOL blnheritHandle; //安全描述对象能否被新创建的进程继承
}SECURITY_ATTRIBUTES , *SECURITY_ATTRIBUTES;
  1. LPVOID 类型
    可以将其理解为long性的指针,指向void型,即可以将LPVOID类型的变量赋值给任意类型的指针。
  2. LPCSTR lpApplicationName
    lpApplicationName 参数指定新进程的可执行文件名称。可以是完整的路径和文件名,也可以是部分名称。(注意一定要加上文件扩展名 “.exe”)
CreateProcess("C:\\Users\\25054\\Desktop\\Child.exe",...)
  1. LPTSTR lpCommandLine
    lpCommandLine 参数用来指定传递给新进程的命令行字符串。
    (很多时候,我们将可执行文件名和命令行参数都传给 lpCommandLine 参数,CreateProcess()函数在分析这个参数时,会把第一个空格分隔的标记作为可执行文件名,如果可执行文件名是部分路径,则函数会在系统目录中只能从上到下的顺序搜索可执行文件)
  2. LPSECURITY_ATTRIBUTES lpProcessAttributes 和 LPSECURITY_ATTRIBUTES lpThreadAttributes
    lpProcessAttributes 和 lpThreadAttributes 都是指向指向 LPSECURITY_ATTRIBUTES 结构体的指针。
    作用: 当调用CreateProcess 函数创建新进程时,系统为新进程创建一个进程内核对象和主线程内核对象。lpProcessAttributes 和 lpThreadAttributes 参数就是分别用来设置新进程内核对象和主线程内核对象的安全属性。若传递 NULL 则表示系统为对象赋予默认的安全描述符。
  3. Bool blnheritHandles
    blheritHandles 用来指定父进程随后创建的子进程是否能够继承父进程对象的句柄。如果该参数为 true,那么父进程的每个可继承打开句柄都能被子进程继承。
  4. DWORD dwCreationFlags
    dwCreationFlags 指定进程创建的附加标记,也可以用于控制进程的优先级。
    如果只为启动子进程,不需要设置创建标记,直接设置为0;
    如果不需要为应用程序创建控制套窗口,则可以设置该参数为 CREATE_NO_WINDOWS ;
    如果需要创建新控制台窗口,而不是继承父进程的控制台窗口,则设置为 CREATE_NEW_WINDOWS 。
    该参数可以创建的标记很多,更多设置可以参看MSDN。
  5. LPVOID lpEnvironment
    lpEnvironment 是一个指向环境块的指针,如果此参数为NULL,那么新进程使用调用环境。通常都为此传递NULL值。
  6. LPTSTR lpCurrentDirectory
    lpCurrentDirectory 参数是一个指向空终止的字符串,用来指定子进程当前的路径,这个字符串不许是一个完整的路径名,包括驱动器的标识符,如果此参数为NULL,那么新的子进程将调用父进程拥有的相同的驱动器和目录。
  7. LPSTARTUPINFO lpStartupInfo
    lpStartupInfo 是一个指向STARTUPINFO 结构体的指针,用来指定新进程的主窗口将如何显示。
typedef struct_STARTUPINFO {
DWORD cb; //结构体本身的大小,以及字节为单位
LPSTR lpReserved;
LPSTR lpTitle;
......
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;
}STARTUPINFO , *LPSTARTUPINFO;

STARTUOINFO结构体成员较多不需要为其都赋值。通常要为其成员变量cb赋值,否则函数调用会失败。
创建进程之前准备工作包括给该结构体变量赋值。

//本实验中不需要其他启动信息,直接为 cb 赋值为结构体变量赋值即可
STARTUPINFO sui;
ZeroMemory (&sui,sizeof(sui));
sui.cb = sizeof(STARTUOINFO);

其中 ZeroMemory 函数可将指定的字节内存清零,使用结构体,数组前将内存清零是个好习惯

ZeroMemory(
PVOID Destination; //指向内存块开始地址的指针
SIZE_T length; // 需要清除的字节数;
  1. LPPROCESS_INFORMATION lpProcessInformation
    lpProcessInformation 参数作为返回值使用,是一个指向PROCESS_INFORMATION 结构体的指针,用来接收关于新进程的标志信息。
typedef struct _PROCESS_INFORMATION{
HANDLE hProcess; //表示新创建进程的句柄
HANDLE hThread; //表示新创建进程的主线程的句柄
DWORD dwProcessId; //全局进程标识
DWORD dwThreadId; // 全局线程标识
}PROCESS_INFOEMATION , *LPPROCESS_INFORMATION;
/*
当启动一个进程时,系统会为进程分配一个标识符,同时会为其线程分配一个标识符;
在进程运行时,该进程的标识符和线程标识符是唯一的,停止后,这些标识符都可能会被系统分配给其他进程和线程。
*/

在创建进程之前,另外一项准备工作就是要定义PROCESS_INFORMATION 结构体变量,准备用于创建进程后的返回消息。

PROCESS_INFORMATION pi;
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值