Windows下当前权限上下文

来源:互联网 发布:mac电脑程序强制退出 编辑:程序博客网 时间:2024/06/18 05:18

Windows核心编程第四章讲解UAC(用户账户控制)的时候,有一个函数GetProcessElevation能返回提升类型和一个指出进程是否正在以管理员身份运行的布尔值.

BOOL GetProcesElevation(TOKEN_ELEVATION_TYPE *pElevation, BOOL *pIsAdmin)  {      HANDLE  hToken = NULL;      DWORD   dwSize;         // 获得当前进程令牌      if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))          return FALSE;         BOOL b_Result = FALSE;         // 检索提升类型信息      if (GetTokenInformation(hToken, TokenElevationType, pElevation, sizeof(TOKEN_ELEVATION_TYPE), &dwSize))      {          if(*pElevation == TokenElevationTypeLimited)          {              // 创建 Administrator 组相应的 SID              BYTE adminSID[SECURITY_MAX_SID_SIZE];              dwSize = sizeof(adminSID);              CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, adminSID, &dwSize);                 // 获得链接令牌的句柄              HANDLE hUnfilteredToken = NULL;              GetTokenInformation(hToken, TokenLinkedToken, (LPVOID)&hUnfilteredToken, sizeof(HANDLE), &dwSize);                 // 检测令牌是否包含管理员SID              if(CheckTokenMembership(hUnfilteredToken, &adminSID, pIsAdmin))                  b_Result = TRUE;                 CloseHandle(hUnfilteredToken);          }else{              *pIsAdmin = IsUserAnAdmin();              b_Result = TRUE;          }             CloseHandle(hToken);             return b_Result;      }  }

2、主要函数:

BOOL OpenProcessToken(__in HANDLE ProcessHandle, //要修改访问权限的进程句柄__in DWORD DesiredAccess, //指定你要进行的操作类型__out PHANDLE TokenHandle //返回的访问令牌指针);

要对一个任意进程(包括系统安全进程和服务进程)进行指定了写相关的访问权的OpenProcess操作,只要当前进程具有SeDeDebug权限就可以了。要是一个用户是Administrator或是被给予了相应的权限,就可以具有该权限。可是,就算我们用Administrator帐号对一个系统安全进程执行。OpenProcess(PROCESS_ALL_ACCESS,FALSE, dwProcessID)还是会遇到“访问拒绝”的错误。什么原因呢?原来在默认的情况下进程的一些访问权限是没有被启用(Enabled)的,所以我们要做的首先是启用这些权限。与此相关的一些API函数有OpenProcessToken、LookupPrivilegevalue、
AdjustTokenPrivileges。我们要修改一个进程的访问令牌,首先要获得进程访问令牌的句柄,这可以通过Open

ProcessToken得到。


BOOL WINAPI GetTokenInformation(  _In_      HANDLE                  TokenHandle,  _In_      TOKEN_INFORMATION_CLASS TokenInformationClass,  _Out_opt_ LPVOID                  TokenInformation,  _In_      DWORD                   TokenInformationLength,  _Out_     PDWORD                  ReturnLength);

参数1:要获取信息令牌的指针
参数2:要获取信息的类型
参数3:缓冲区的指针,此缓冲区用来填充所请求的信息
参数4:缓冲区的大小(字节)
参数5:缓冲区接收到的字节数


其中参数2可以获取的信息如下:

typedef enum _TOKEN_INFORMATION_CLASS {   TokenUser                             = 1,  TokenGroups,  TokenPrivileges,  TokenOwner,  TokenPrimaryGroup,  TokenDefaultDacl,  TokenSource,  TokenType,  TokenImpersonationLevel,  TokenStatistics,  TokenRestrictedSids,  TokenSessionId,  TokenGroupsAndPrivileges,  TokenSessionReference,  TokenSandBoxInert,  TokenAuditPolicy,  TokenOrigin,  TokenElevationType,  TokenLinkedToken,  TokenElevation,  TokenHasRestrictions,  TokenAccessInformation,  TokenVirtualizationAllowed,  TokenVirtualizationEnabled,  TokenIntegrityLevel,  TokenUIAccess,  TokenMandatoryPolicy,  TokenLogonSid,  TokenIsAppContainer,  TokenCapabilities,  TokenAppContainerSid,  TokenAppContainerNumber,  TokenUserClaimAttributes,  TokenDeviceClaimAttributes,  TokenRestrictedUserClaimAttributes,  TokenRestrictedDeviceClaimAttributes,  TokenDeviceGroups,  TokenRestrictedDeviceGroups,  TokenSecurityAttributes,  TokenIsRestricted,  MaxTokenInfoClass} TOKEN_INFORMATION_CLASS, *PTOKEN_INFORMATION_CLASS;

对应的参数3指针所指向的缓冲区的结构:
TokenUser:
The buffer receives a TOKEN_USER structure that contains the user account of the token.

TokenGroups:
The buffer receives a TOKEN_GROUPS structure that contains the group accounts associated with the token.

TokenPrivileges:
The buffer receives a TOKEN_PRIVILEGES structure that contains the privileges of the token.

TokenOwner:
The buffer receives a TOKEN_OWNER structure that contains the default owner security identifier (SID) for newly created objects.

TokenPrimaryGroup:
The buffer receives a TOKEN_PRIMARY_GROUP structure that contains the default primary group SID for newly created objects.

TokenDefaultDacl:
The buffer receives a TOKEN_DEFAULT_DACL structure that contains the default DACL for newly created objects.

TokenSource:
The buffer receives a TOKEN_SOURCE structure that contains the source of the token. TOKEN_QUERY_SOURCE access is needed to retrieve this information.

TokenType:
The buffer receives a TOKEN_TYPE value that indicates whether the token is a primary or impersonation token.

TokenImpersonationLevel:
The buffer receives a SECURITY_IMPERSONATION_LEVEL value that indicates the impersonation level of the token. If the access token is not an impersonation token, the function fails.

TokenStatistics:
The buffer receives a TOKEN_STATISTICS structure that contains various token statistics.


TokenRestrictedSids:
The buffer receives a TOKEN_GROUPS structure that contains the list of restricting SIDs in a restricted token.

......

TokenElevationType:
The buffer receives a TOKEN_ELEVATION_TYPE value that specifies the elevation level of the token.

......
其它没列举出来的自行查询MSDN。


3、

2.提升进程的权限,VS开发过程。
判断一个进程是以提升的权限来启动的,还是正在使用筛选的令牌运行的?


GetCurrentProcess---------得到当前进程句柄
OpenProcessToken--------打开当前进程关联的令牌。(会得到一个令牌句柄)
GetTokenInformation-----------获得与进程关联的令牌的信息(记得使用TokenElevationType参数来获得提升类型)


如果令牌没有被筛选过,用IsUserAnAdmin函数来判断进程是否正在以管理员的身份运行是最理想的。


如果令牌已经被筛选,然后需要通过给GetTokenInformation传递TokenLinkedToken参数来获取一个未筛选的令牌,然后判断其中是否包含一个管理员SID。


CreateWellKnowSid---------传递WinbuiltinAministratorsSid参数来创建一个与管理员组一致的SID。


CheckTokenMembership----------检查一个令牌的权限组。

原创粉丝点击