首页 > 学院 > 开发设计 > 正文

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

2019-11-08 01:01:02
字体:
来源:转载
供稿:网友

工作中碰到这样的需求,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 higher	if (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一样,可以自己扩展一下


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表