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");