在这篇很棒的MSDN 文章的帮助下,我的第一个想法是简单地检查进程是否使用提升的管理员组,并使用AdjustTokenGroups()
我将管理员组设置为SE_GROUP_USE_FOR_DENY_ONLY
. 不幸的是,我们无法修改当前运行进程的管理员组,因为它也具有SE_GROUP_MANDATORY
属性,这使得它无法更改。
MSDN 文档对此有这样的说法:
该AdjustTokenGroups
函数不能禁用结构中具有该SE_GROUP_MANDATORY
属性的组TOKEN_GROUPS
。改为使用CreateRestrictedToken
。
所以,我完成了以下代码来实现这一点;
bool _IsNewProcessLaunched()
{
HANDLE hToken = NULL;
bool hasRestarted = false;
if (!OpenProcessToken( GetCurrentProcess(),
TOKEN_ASSIGN_PRIMARY | TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ADJUST_GROUPS,
&hToken ))
{
return hasRestarted;
}
PSECURITY_DESCRIPTOR pSID = NULL;
SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
if(! AllocateAndInitializeSid( &SIDAuth, 2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&pSID) )
{
CloseHandle(hToken);
hToken = NULL;
return hasRestarted;
}
BOOL isAdmin = FALSE;
BOOL ok = CheckTokenMembership(NULL, pSID, &isAdmin);
// Create the SID structure for the administrator SID
SID_AND_ATTRIBUTES adminSID = {0};
adminSID.Sid = pSID;
// Create a restricted token which denies the administrator group
HANDLE restrictedToken;
CreateRestrictedToken(hToken,RESTR,DISABLE_MAX_PRIVILEGE,&adminSID,NULL,NULL,NULL,NULL,&restrictedToken);
//Create startup info
STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
si.lpDesktop = L"winsta0\\default";
si.cb = sizeof( si );
// Get the current executables name
TCHAR exePath[MAX_PATH];
GetModuleFileName(NULL,exePath,MAX_PATH);
// Start the new (non-administrator elevated) restricted process
if( CreateProcessAsUser(restrictedToken,exePath,NULL,NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi) == 0)
hasRestarted = false;
else
hasRestarted = true;
return hasRestarted;
}
但是新进程仍然以管理员身份运行,而不是以普通用户身份运行。
我该如何做到这一点?