CreateProcess函数
使用CreateProcess函数来创建一个进程
BOOL CreateProcess(
LPCTSTR pszApplicationName,// name of executable module
LPTSTR pszCommandLine,// command line string
LPSECURITY_ATTRIBUTES psaProcess,// SD
LPSECURITY_ATTRIBUTES psaThread,// SD
BOOL bInheritHandles,// handle inheritance option
DWORD fdwCreationFlags,// creation flags
LPVOID pvEnvironment,// new environment block
LPCTSTR pszCurDir,// current directory name
LPSTARTUPINFO psiStartupInfo,// startup information
LPPROCESS_INFORMATION lpProcessInformation // process information
);
CreateProcess按以下的顺序搜索可执行文件:
1.主调进程.exe文件所在的目录
2.主调进程的当前目录
3.windows系统目录,即GetSystemDirectory()返回的System32文件夹
4.Windows目录
5.PATH环境变量中列出的目录
(c/c++运行时启动例程会检查进程的命令行,将可执行文件名之后的第一个实参的地址传给WinMain的pszCmdLine参数)
lpApplicationName:
指定了新进程要使用的可执行文件的名称
一般此参数为NULL 如果不为NULL可以传递一个字符串地址,并在字符串中包含想要运行的可执行文件的名称,且要指定扩展名,系统不会自动加个.exe的扩展名
如果不指定路径,CreateProcess只会在当前路径下寻找文件,如果找不到调用就会失败,然而即使在pszApplicatioName中指定文件名,CreateProcess也会将pszCommandLine参数作为新进程的命令行传给他,例如:
#include<iostream>
#include<windows.h>
int main()
{
char buf[]="WORDPAD README.txt";
STARTUPINFO si ={sizeof(STARTUPINFO)};
PROCESS_INFORMATION pi;
CreateProcess("C:\\WINDOWS\\SYSTEM32\\NOTEPAD.EXE",buf,NULL,NULL,false,0,NULL,NULL,&si,&pi);
}
#include<iostream>
#include<windows.h>
int main()
{
char buf[]="C:\\WINDOWS\\SYSTEM32\\NOTEPAD README.txt";
STARTUPINFO si ={sizeof(STARTUPINFO)};
PROCESS_INFORMATION pi;
CreateProcess(NULL,buf,NULL,NULL,false,0,NULL,NULL,&si,&pi);
}
4.3 有以下4种方式:
2.使用函数ExitProcess(要避免这种方式)
3.使用函数TerminateProcess( 要避免这种方式 )
4.进程中的所有线程终止运行(几乎不会发生)
#include<windows.h>
#include<iostream>
usingnamespace std;
class PPP
{
public:
PPP(){ cout <<"this is constructor!"<< endl;}
~PPP(){ cout <<"this is destructor!"<< endl;}
};
PPP p1;
int main()
{
PPP p;
ExitProcess(0);
cout <<"run this ?"<< endl;
}
BOOL TerminateProcess(
HANDLE hProcess,// handle to the process
UINT uExitCode // exit code for the process
);
- 进程中剩余的所有线程全部终止运行。
- 释放该进程引用的GDI和用户对象,内核对象被关闭(别的进程有引用则计数器减1,如果没有引用则关闭内核对象)。
- 推出代码将从STILL_ACTIVE(后面章节线程将介绍该结构)改为传递给ExitProcess和TerminiateProcess代码。
- 内核对象状态变为收到通知状态(线程中介绍),其他线程挂起,知道进程终止。
- 进程内核对象计数减去1,或者关闭。
BOOL GetExitCodeProcess(HANDLE hProcess, PDWORD pdwExitCode);
4.4 子进程没什么好说的,前面的都说了,用CloseHandle关闭子进程和子进程中主线程的句柄值来切断父进程和子进程的所有联系。
进程的权限
用户账户控制(UAC)技术
Windows操作系统会创建一个安全令牌(security token).每当有代码试图访问一个受保护的安全资源时时,操作系统就会使用(出示)这个安全令牌,
从Windows在内的第一个进程开始,这个令牌会与新建的所有进程关联,这样如果新下载了一个恶意程序,就会继承管理员的高权限,------因此可以肆无忌惮的修改机器上的任何内容,甚至启动同一个高特权的进程。
那么从vista开始,如果用户使用管理员帐号来登录这样一个被授予高特权的账户登录,那么除了与这个账户登录对应的安全令牌之外,还会创建一个进过筛选的令牌(filtered token)后者只给标准用户的权限(Standard User).以后包括Windows资源管理器在内的第一个进程开始,这个筛选后的令牌会与系统表示最终用户启动启动的所有新进程关联,权限受限制的进程无法访问需要更高权限才能访问的安全资源.4.5.1 自动提升进程的权限manifest文件
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="highestAvailable"></requestedExecutionLevel>
</requestedPrivileges>
</security>
</trustInfo>
如上 被称为一种特殊的资源RT_MANIFEST特殊资源,将其编译到exe资源节区中,系统会按照requestedExecutionLevel节来判断进程的权限,并执行一些操作
requireAdministrator -->应用程序必须以管理员权限启动,否则不会运行
可将清单嵌入到可执行文件的资源中,或保存到可执行文件所在目录下,扩展名用. manifest[注:不会立即被系统发现,有时需注销用户]
highestAvailable-->应用程序以当前可用的最高权限运行
-->如果用户使用管理员帐号登录,就会出现一个要求批准提升权限的对话框
-->如果用户使用普通用户账户登录系统,就使用标准权限来启动
asInvoker -->应用程序以主调应用程序一样的权限来启动
4.5.2 手动提升进程的权限4.5.3当前权限上下文4.5.4枚举运行进程4.5.5 Process Information 示例程序