windows编程的人都知道,在其操作系统下,进程被创建,通常被赋予很多属性,其中一项属性就是用户名,及进程所属的权限。打开任务管理器,可查看到.
通常桌面系统explorer的权限是User权限,即用户权限的,它可以是你administrator,可以是你PC的名字,可以是Guest等,所以我们开启并运行的所有进程都继承它的权限。
在添加服务后,服务所对应的进程权限是SYSTEM权限,那么由这个SYSTEM调用的所有子进程,在常规下,都将是SYSTEM权限,如果有这样一个需求,需要通过服务调用某个具备User权限的进程,则需要通过CreateProcess
API的扩展即,CreateProcessAsUser.
WINADVAPI BOOL
WINAPI CreateProcessAsUser (
__in_opt HANDLE hToken,
__in_opt LPCSTR lpApplicationName,
__inout_opt LPSTR lpCommandLine,
__in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in BOOL bInheritHandles,
__in DWORD dwCreationFlags,
__in_opt LPVOID lpEnvironment,
__in_opt LPCSTR lpCurrentDirectory,
__in LPSTARTUPINFOA lpStartupInfo,
__out LPPROCESS_INFORMATION lpProcessInformation
);
其中hToken是最关键的,它表示进程所需要的会话令牌,通俗点就是权限的一个标识,有了它,就可以创建其他权限的进程了。
hToken的获取,网上资料特别多,就不列举了,这里直接贴关键代码
int CreateProcessByToken(LPSTR lpTokenProcessName,LPSTR lpProcess,LPSTR lpCommend) { HANDLE hToken = 0; LPSTR lpName = lpTokenProcessName; HANDLE hProcessSnap = 0; PROCESSENTRY32 pe32 = {0}; hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); pe32.dwSize = sizeof(PROCESSENTRY32); for(Process32First(hProcessSnap,&pe32);Process32Next(hProcessSnap,&pe32);) { if(strcmp(strupr(pe32.szExeFile),strupr(lpName))) continue; HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,pe32.th32ProcessID); OpenProcessToken(hProcess,TOKEN_ALL_ACCESS,&hToken); CloseHandle(hProcessSnap); } if(hToken == 0) return 0; STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si,sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.lpDesktop = "winsta0\default"; si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; return CreateProcessAsUser(hToken,lpProcess,lpCommend,0,0,FALSE,NORMAL_PRIORITY_CLASS,0,0,&si,&pi); }
调用方式为:
char tokenname[64]="explorer.exe"; CreateProcessByToken(tokenname,0,"myservice_userchild.exe");