win32程序权限提升 杨大毛windows核心编程视频记录

#include<Windows.h>
#include<tchar.h>
#include<Shlobj.h>

//可以把这个函数当Windows API来用。这个函数返回BOOL,当函数返回TRUE的时候,函数成功,当函数返回FALSE的话
//函数失败。

/*
TOKEN_ELEVATION_TYPE* pElevationType:令牌提升类型。
BOOL* pIsAdmin :是否是管理员。保存结果

这个函数,确定了,运行当前程序的帐号,是否为管理员帐号,以及当前进程的令牌,是哪种令牌。甚至你还可以确定,当前
的这个操作系统是否启动了UAC功能。
*/
BOOL GetProcessElevation(TOKEN_ELEVATION_TYPE* pElevationType, BOOL* pIsAdmin) 
{
   HANDLE hToken = NULL;
   DWORD dwSize;

   // 获得当前进程的令牌句柄。
   if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
      return(FALSE);

   BOOL bResult = FALSE;

   // 看看这个令牌的权限提升类型是哪一种:
   /*
        TokenElevationTypeDefault:进程以缺省的用户身份运行,或者没有使用UAC功能,简单来说,就是用户没有启动UAC功能,那么程序使用的令牌,一定不是Filter Token。

        TokenElevationTypeFull:进程的权限已经被提升,进程令牌没有使用filter令牌

        TokenElevationTypeLimited:进程使用的令牌是Filter令牌。此时通过GetTokenInformation函数,并使用TokenLinkedToken标志,来获取原令牌。

    */
   if (GetTokenInformation(hToken, TokenElevationType,
      pElevationType, sizeof(TOKEN_ELEVATION_TYPE), &dwSize)) 
   {
      // 创建一个管理员SID
      BYTE adminSID[SECURITY_MAX_SID_SIZE];
      dwSize = sizeof(adminSID);
      CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, &adminSID,
         &dwSize);

      if (*pElevationType == TokenElevationTypeLimited) 
      {
         //通过Filter Token来获得原始的Token
         HANDLE hUnfilteredToken = NULL;
         //TokenLinkedToken标志,表示要获得Filter Token的原始Token。
         GetTokenInformation(hToken, TokenLinkedToken, (VOID*)
            &hUnfilteredToken, sizeof(HANDLE), &dwSize);

         // 检查原始Token中,管理员账户adminSID是否被激活,如果被激活,那么说明启动这个
         //程序的帐号是管理员帐号,否则不是。
         if (CheckTokenMembership(hUnfilteredToken, &adminSID, pIsAdmin)) 
            //这个CheckTokenMembership函数,结果被保存在pIsAdmin参数中,而这个函数的返回值
            //只是表示,这个函数是否成功。
         {
            bResult = TRUE;
         }

         // 不要忘了关闭原始令牌。
         CloseHandle(hUnfilteredToken);
      } 
      else //如果是原始令牌,只要IsUsrAndmin就可以确定,启动当前程序的帐号是否是管理员帐号。
      {
         *pIsAdmin = IsUserAnAdmin();
         bResult = TRUE;
      }
   }

   // 不要忘了关闭进程令牌。
   CloseHandle(hToken);
   return(bResult);
}

// 以管理员身份运行程序
void adminRun()
{
	SHELLEXECUTEINFO ShExecInfo = {0};  
	ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);  
	ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;  
	ShExecInfo.hwnd = NULL;  
	ShExecInfo.lpVerb = L"runas"; //这个参数设置,就是让ShellExecuteEx函数  启动的进程已管理员身份运行,而不使用过滤令牌。
	ShExecInfo.lpFile = L"cmd";  //这个就是你要启动的程序
	ShExecInfo.lpParameters = L"";  
	ShExecInfo.lpDirectory = NULL;  
	ShExecInfo.nShow = SW_SHOW; //如果这个参数不设置,那么你看不见被启动程序的
	//窗口。
	ShExecInfo.hInstApp = NULL;  
	ShellExecuteEx(&ShExecInfo);  
}
#include<Windows.h>
//这个函数,将进程权限提升成具有调试权限的进程,这个权限应该是进程
//所能具有的最大权限。
//这个函数成功的前提,必须是,启动这个进程的帐号必须是管理员帐号。
//当fEnable=TRUE的时候,授予当前进程权限
//当fEnable=FALSE的时候,取消当前进程权限。
//当函数返回TRUE时,说明权限调整成功,否则失败。

BOOL EnablePrivilege(PCTSTR szPrivilege, BOOL fEnable) {

    //启用debug特权允许应用程序查看 szPrivilege = SE_DEBUG_NAME
    //关于服务应用程序的信息
   BOOL fOk = FALSE;    // 假设函数失败
   HANDLE hToken;

   // 尝试打开此进程的访问令牌              TOKEN_ADJUST_PRIVILEGES 需要启用或禁用访问令牌中的特权
   if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES,  
      &hToken)) {

      // 试图修改给定的权限
      TOKEN_PRIVILEGES tp;
      /*
	  typedef struct _TOKEN_PRIVILEGES {
		DWORD               PrivilegeCount;
		//这个结构体,有几个权限,也就是第二个成员变量Privaileges数组,有几个元素。
		LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];
		} TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;
		
		typedef struct _LUID_AND_ATTRIBUTES {
			LUID  Luid;//本地唯一标识符。不肯能重复的一个数组。这个东西和GUID是一个东西
			DWORD Attributes;//权限属性。
		} LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES;
 */
      tp.PrivilegeCount = 1;
      // LookupPrivilegeValue函数检索在指定系统上使用的本地惟一标识符(LUID),以本地表示指定的特权名称。
      LookupPrivilegeValue(NULL, szPrivilege, &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);

      // Don't forget to close the token handle
      CloseHandle(hToken);
   }
   return(fOk);
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值