windows软件权限相关

权限管理

以管理员权限重新打开进程

 WCHAR szApplication[MAX_PATH] = { 0 };
	DWORD cchLength = _countof(szApplication);
	//获取当前进程全路径QueryFullProcessImageName
	QueryFullProcessImageName(GetCurrentProcess(), 0,
		szApplication, &cchLength);

	// 3. 以管理员权限重新打开进程
	SHELLEXECUTEINFO sei = { sizeof(SHELLEXECUTEINFO) };
	sei.lpVerb = L"runas";      // 请求提升权限
	sei.lpFile = szApplication; // 可执行文件路径
	sei.lpParameters = NULL;	// 不需要参数
	sei.nShow = SW_SHOWNORMAL;	// 正常显示窗口
	if (ShellExecuteEx(&sei))
		exit(0);
	else
		ShowWindow( SW_SHOWNORMAL);

根据是否具有管理员权限来给Button加令牌图标

// 1. 获得本进程的令牌
	// 1. 获得本进程的令牌
	HANDLE hToken = NULL;
	if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
		return ;
	// 2. 获取提升类型
	TOKEN_ELEVATION_TYPE ElevationType = TokenElevationTypeDefault;
	BOOL                 bIsAdmin = false;
	DWORD                dwSize = 0;

	if (GetTokenInformation(hToken, TokenElevationType, &ElevationType,
		sizeof(TOKEN_ELEVATION_TYPE), &dwSize)) {
		// 2.1 创建管理员组的对应SID
		BYTE adminSID[SECURITY_MAX_SID_SIZE];
		dwSize = sizeof(adminSID);
		CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, &adminSID, &dwSize);
		// 2.2 判断当前进程运行用户角色是否为管理员
		if (ElevationType == TokenElevationTypeLimited) {
			// a. 获取连接令牌的句柄
			HANDLE hUnfilteredToken = NULL;
			GetTokenInformation(hToken, TokenLinkedToken, (PVOID)&hUnfilteredToken,
				sizeof(HANDLE), &dwSize);
			// b. 检查这个原始的令牌是否包含管理员的SID
			if (!CheckTokenMembership(hUnfilteredToken, &adminSID, &bIsAdmin))
				return ;
			CloseHandle(hUnfilteredToken);
		}
		else {
			bIsAdmin = IsUserAnAdmin();
		}
		CloseHandle(hToken);
	}

	// 3. 判断具体的权限状况
	BOOL bFullToken = false;
	switch (ElevationType) {
	case TokenElevationTypeDefault: /* 默认的用户或UAC被禁用 */
		if (IsUserAnAdmin())  bFullToken = true; // 默认用户有管理员权限
		else                  bFullToken = false;// 默认用户不是管理员组
		break;
	case TokenElevationTypeFull:    /* 已经成功提高进程权限 */
		if (IsUserAnAdmin())  bFullToken = true; //当前以管理员权限运行
		else                  bFullToken = false;//当前未以管理员权限运行
		break;
	case TokenElevationTypeLimited: /* 进程在以有限的权限运行 */
		if (bIsAdmin)  bFullToken = false;//用户有管理员权限,但进程权限有限
		else           bFullToken = false;//用户不是管理员组,且进程权限有限
	}
	// 4. 根据权限的不同控制按钮的显示
	if (!bFullToken)
		//如果不是管理员权限
		Button_SetElevationRequiredState(m_Button.GetSafeHwnd(),
		!bFullToken);
	else
		//如果是管理员权限
		::ShowWindow(m_Button.GetSafeHwnd(), SW_HIDE);


遍历当前进程权限

//遍历权限
void ShowPrviliges()
{
	//获取进程令牌句柄
	HANDLE hToken;
	OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken);
	if (!hToken)
	{
		printf("令牌获取失败\n");
		return;
	}
	//查询令牌中的权限
	DWORD dwSize;
	//第一次获取查询数据的大小
	GetTokenInformation(hToken, 
		TokenPrivileges, NULL, NULL, &dwSize);
	
	//第二次根据上次获取的大小申请足够大的内存后,
	//将内存地址传进去获取想要的数据
	//	TokenPrivileges的意思是:缓冲区接收 包含令牌权限的TOKEN_PRIVILEGES结构。
	char* pBuf = new char[dwSize]{};
	GetTokenInformation(hToken,
		TokenPrivileges, pBuf, dwSize, &dwSize);
	//将内存中的内容用要查询数据结构体解析
	//这里事权限的结构体
	TOKEN_PRIVILEGES* pTp = (TOKEN_PRIVILEGES*)pBuf;

	//权限个数
	DWORD dwCount = pTp->PrivilegeCount;
	//指向权限数组首地址
	LUID_AND_ATTRIBUTES* pLaa = pTp->Privileges;
	//输出权限
	for (int i = 0; i < dwCount; i++, pLaa++)
	{
		char szName[100] = {};
		DWORD dwLen = sizeof(szName);
		//查询此权限对应的字符串
		LookupPrivilegeNameA(0, &pLaa->Luid, szName, &dwLen);
		//状态,0:关闭,1:默认值,2:开启,3:默认开启 
		printf("[%s] -- 状态[%d]\n", szName, pLaa->Attributes);
	}
	delete pBuf;
}

示例–提升当前程序调试权限

/*************************************************
函数名称: EnableDebugPrivilege
函数功能: 打开进程的调试权限
参数:	是否提升为调试权限
函数返回值:
其它说明: 
*************************************************/
BOOL EnableDebugPrivilege(BOOL fEnable){   //提升为调试权限
	BOOL fOk = FALSE;    HANDLE hToken;
	// 以修改权限的方式,打开当前进程的令牌
	if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES,
		&hToken)) {
		// 令牌权限结构体
		TOKEN_PRIVILEGES tp;
		tp.PrivilegeCount = 1;
		//获得LUID(一个指定系统上用于局部地表示指定的权限名称)
		LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
		tp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0;
		AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL); //修改权限
		fOk = (GetLastError() == ERROR_SUCCESS);
		CloseHandle(hToken);
	}
	return(fOk);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值