首先说下ShellExecuteEx是如何提升权限的,ShellExecuteEx函数只有一个参数,就是SHELLEXECUTEINFO结构体,不过是指针类型的,这无所谓,关键是这个结构体中有一个参数lpVerb,它的作用就是指定如何操作文件lpFile,提升权限就是设置lpVerb为“runas”。
将lpVerb设定为”open”或NULL的时候,创建的子进程继承了主进程的权限,当主进程使用管理员身份运行时,经lpVerb设置为”open”或NULL时,就会发现创建的子进程依旧是管理员身份。
最终测试的结果是
(1).当主进程以管理员身份运行时,创建的子进程都是管理员身份;
(2).当主进程以普通用户身份运行时,若将lpVerb参数设置为“runas”,则创建的子进程是管理员身份;若将lpVerb设置为“open”或NULL时,则创建的子进程时普通用户身份。
函数原型
BOOL ShellExecuteEx(
_Inout_ SHELLEXECUTEINFO *pExecInfo
);
结构:
typedef struct _SHELLEXECUTEINFO {
DWORD cbSize; //这个是结构体大小,sizeof下SHELLEXECUTEINFO就行
ULONG fMask;
HWND hwnd; //主进程的窗口句柄,一般没用
LPCTSTR lpVerb; //设置成runas就可以以管理员身份运行了,其他的都是普通用户身份
LPCTSTR lpFile; //要运行的文件
LPCTSTR lpParameters; //要运行的文件的参数
LPCTSTR lpDirectory;
int nShow; //设置窗口显示(SW_SHOW)和不显示(SW_HIDE),当然还有其他的
HINSTANCE hInstApp;
LPVOID lpIDList;
LPCTSTR lpClass;
HKEY hkeyClass;
DWORD dwHotKey;
union {
HANDLE hIcon;
HANDLE hMonitor;
} DUMMYUNIONNAME;
HANDLE hProcess; //返回子进程句柄
} SHELLEXECUTEINFO, *LPSHELLEXECUTEINFO;
测试:
SHELLEXECUTEINFO ShExecInfo = {0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = L"runas";
ShExecInfo.lpFile = L"cmd";
ShExecInfo.lpParameters = L"";
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
WaitForSingleObject(ShExecInfo.hProcess,INFINITE);
运行结果可以明显看到,启动的cmd命令行窗口,的权限是不同的。