管理员权限程序以普通用户的权限运行不需要管理员权限的程序

来源:互联网 发布:电脑看书软件 编辑:程序博客网 时间:2024/05/17 01:03

工作中碰到这样的需求,A程序需要管理员权限(也就是会弹UAC验证),B程序不需要,现在B程序是通过A程序CreateProcess启动的,发现其实B程序继承了A的权限,解决方法如下:

DWORD GetProcessIL(DWORD u32_PID, DWORD* pu32_ProcessIL){*pu32_ProcessIL = 0;HANDLE h_Process   = 0;HANDLE h_Token     = 0;DWORD  u32_Size    = 0;BYTE*  pu8_Count   = 0;DWORD* pu32_ProcIL = 0;TOKEN_MANDATORY_LABEL* pk_Label = 0;h_Process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, u32_PID);if (!h_Process)goto _CleanUp;if (!OpenProcessToken(h_Process, TOKEN_QUERY, &h_Token))goto _CleanUp;if (!GetTokenInformation(h_Token, TokenIntegrityLevel, NULL, 0, &u32_Size) &&GetLastError() != ERROR_INSUFFICIENT_BUFFER)goto _CleanUp;pk_Label = (TOKEN_MANDATORY_LABEL*) HeapAlloc(GetProcessHeap(), 0, u32_Size);if (!pk_Label)goto _CleanUp;if (!GetTokenInformation(h_Token, TokenIntegrityLevel, pk_Label, u32_Size, &u32_Size))goto _CleanUp;pu8_Count = GetSidSubAuthorityCount(pk_Label->Label.Sid);if (!pu8_Count)goto _CleanUp;pu32_ProcIL = GetSidSubAuthority(pk_Label->Label.Sid, *pu8_Count-1);if (!pu32_ProcIL)goto _CleanUp;*pu32_ProcessIL = *pu32_ProcIL;SetLastError(ERROR_SUCCESS);_CleanUp:DWORD u32_Error = GetLastError();if (pk_Label)  HeapFree(GetProcessHeap(), 0, pk_Label);if (h_Token)   CloseHandle(h_Token);if (h_Process) CloseHandle(h_Process);return u32_Error;}

DWORD CreateProcessMediumIL(WCHAR* u16_Path, WCHAR* u16_CmdLine, WCHAR* u16_CurrentDirectory, PROCESS_INFORMATION *pProcessInfo){HANDLE h_Process = 0;HANDLE h_Token   = 0;HANDLE h_Token2  = 0;PROCESS_INFORMATION k_ProcInfo    = {0};STARTUPINFOW        k_StartupInfo = {0};BOOL b_UseToken = FALSE;// Detect Windows Vista, 2008, Windows 7 and higherif (GetProcAddress(GetModuleHandleA("Kernel32"), "GetProductInfo")){DWORD u32_CurIL;DWORD u32_Err = GetProcessIL(GetCurrentProcessId(), &u32_CurIL);if (u32_Err)return u32_Err;if (u32_CurIL > SECURITY_MANDATORY_MEDIUM_RID)b_UseToken = TRUE;}// Create the process normally (before Windows Vista or if current process runs with a medium IL)if (!b_UseToken){if (!::CreateProcessW(u16_Path, u16_CmdLine, 0, 0, FALSE, 0, 0, u16_CurrentDirectory, &k_StartupInfo, &k_ProcInfo)){return GetLastError();}if(pProcessInfo){*pProcessInfo = k_ProcInfo;}else{CloseHandle(k_ProcInfo.hThread);CloseHandle(k_ProcInfo.hProcess); }return ERROR_SUCCESS;}defCreateProcessWithTokenW f_CreateProcessWithTokenW = (defCreateProcessWithTokenW) GetProcAddress(GetModuleHandleA("Advapi32"), "CreateProcessWithTokenW");if (!f_CreateProcessWithTokenW) // This will never happen on Vista!return ERROR_INVALID_FUNCTION; HWND h_Progman = ::GetShellWindow();DWORD u32_ExplorerPID = 0;GetWindowThreadProcessId(h_Progman, &u32_ExplorerPID);// ATTENTION:// If UAC is turned OFF all processes run with SECURITY_MANDATORY_HIGH_RID, also Explorer!// But this does not matter because to start the new process without UAC no elevation is required.h_Process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, u32_ExplorerPID);if (!h_Process)goto _CleanUp;if (!OpenProcessToken(h_Process, TOKEN_DUPLICATE, &h_Token))goto _CleanUp;if (!DuplicateTokenEx(h_Token, TOKEN_ALL_ACCESS, 0, SecurityImpersonation, TokenPrimary, &h_Token2))goto _CleanUp;if (!f_CreateProcessWithTokenW(h_Token2, 0, u16_Path, u16_CmdLine, 0, 0, u16_CurrentDirectory, &k_StartupInfo, &k_ProcInfo)){goto _CleanUp;}if(pProcessInfo)*pProcessInfo = k_ProcInfo;SetLastError(ERROR_SUCCESS);_CleanUp:DWORD u32_Error = GetLastError();if (h_Token)   CloseHandle(h_Token);if (h_Token2)  CloseHandle(h_Token2);if (h_Process) CloseHandle(h_Process);if(!pProcessInfo){CloseHandle(k_ProcInfo.hThread);CloseHandle(k_ProcInfo.hProcess); }return u32_Error;}
用法和CreateProcess一样,可以自己扩展一下




0 0
原创粉丝点击