Check if another process has admin privileges
I have wrote a code to check is a process running on the same machine has administrator privileges or not. But it always returns false.
Can you tell me what's wrong with it.
private static bool HasAdminPrivileges(int processId)
{
var hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryInformation, false, processId);
var opened = WinApi.OpenProcessToken(hProcess, WinApi.TOKEN_QUERY, out IntPtr hToken);
if (opened)
{
var token = new IntPtr(hProcess.ToInt64() + hToken.ToInt64()); // 64 bit machine only
WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, IntPtr.Zero, out uint cbSidUint);
var cbSid = new IntPtr(cbSidUint);
var succeed = WinApi.CheckTokenMembership(token, cbSid, out bool isMember);
return succeed && isMember;
}
return false;
}
public class WinApi
{
public const int TOKEN_QUERY = 0X00000008;
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool CreateWellKnownSid(WELL_KNOWN_SID_TYPE WellKnownSidType, IntPtr DomainSid, IntPtr pSid, out uint cbSid);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool CheckTokenMembership(IntPtr TokenHandle, IntPtr SidToCheck, out bool IsMember);
}
public enum ProcessAccessFlags : uint
{
QueryInformation = 0x00000400
}
public enum WELL_KNOWN_SID_TYPE
{
WinBuiltinAdministratorsSid = 26
}
windows winapi process system32 advapi32
add a comment |
I have wrote a code to check is a process running on the same machine has administrator privileges or not. But it always returns false.
Can you tell me what's wrong with it.
private static bool HasAdminPrivileges(int processId)
{
var hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryInformation, false, processId);
var opened = WinApi.OpenProcessToken(hProcess, WinApi.TOKEN_QUERY, out IntPtr hToken);
if (opened)
{
var token = new IntPtr(hProcess.ToInt64() + hToken.ToInt64()); // 64 bit machine only
WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, IntPtr.Zero, out uint cbSidUint);
var cbSid = new IntPtr(cbSidUint);
var succeed = WinApi.CheckTokenMembership(token, cbSid, out bool isMember);
return succeed && isMember;
}
return false;
}
public class WinApi
{
public const int TOKEN_QUERY = 0X00000008;
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool CreateWellKnownSid(WELL_KNOWN_SID_TYPE WellKnownSidType, IntPtr DomainSid, IntPtr pSid, out uint cbSid);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool CheckTokenMembership(IntPtr TokenHandle, IntPtr SidToCheck, out bool IsMember);
}
public enum ProcessAccessFlags : uint
{
QueryInformation = 0x00000400
}
public enum WELL_KNOWN_SID_TYPE
{
WinBuiltinAdministratorsSid = 26
}
windows winapi process system32 advapi32
2
errors: 1 you must open process with accessPROCESS_QUERY_LIMITED_INFORMATION
but notPROCESS_QUERY_INFORMATION
(you get access denied here if you not run as admin) 2CheckTokenMembership
work only with impersonation token.but you try pass primary token to it. 3 you not create admin sid - in single call toCreateWellKnownSid
you not pass pointer to memory where this sid can be stored. 4 you not close opened handles. 5 you not check any errors
– RbMm
Nov 24 '18 at 15:03
6 you not debug self code at all
– RbMm
Nov 24 '18 at 15:11
add a comment |
I have wrote a code to check is a process running on the same machine has administrator privileges or not. But it always returns false.
Can you tell me what's wrong with it.
private static bool HasAdminPrivileges(int processId)
{
var hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryInformation, false, processId);
var opened = WinApi.OpenProcessToken(hProcess, WinApi.TOKEN_QUERY, out IntPtr hToken);
if (opened)
{
var token = new IntPtr(hProcess.ToInt64() + hToken.ToInt64()); // 64 bit machine only
WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, IntPtr.Zero, out uint cbSidUint);
var cbSid = new IntPtr(cbSidUint);
var succeed = WinApi.CheckTokenMembership(token, cbSid, out bool isMember);
return succeed && isMember;
}
return false;
}
public class WinApi
{
public const int TOKEN_QUERY = 0X00000008;
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool CreateWellKnownSid(WELL_KNOWN_SID_TYPE WellKnownSidType, IntPtr DomainSid, IntPtr pSid, out uint cbSid);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool CheckTokenMembership(IntPtr TokenHandle, IntPtr SidToCheck, out bool IsMember);
}
public enum ProcessAccessFlags : uint
{
QueryInformation = 0x00000400
}
public enum WELL_KNOWN_SID_TYPE
{
WinBuiltinAdministratorsSid = 26
}
windows winapi process system32 advapi32
I have wrote a code to check is a process running on the same machine has administrator privileges or not. But it always returns false.
Can you tell me what's wrong with it.
private static bool HasAdminPrivileges(int processId)
{
var hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryInformation, false, processId);
var opened = WinApi.OpenProcessToken(hProcess, WinApi.TOKEN_QUERY, out IntPtr hToken);
if (opened)
{
var token = new IntPtr(hProcess.ToInt64() + hToken.ToInt64()); // 64 bit machine only
WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, IntPtr.Zero, out uint cbSidUint);
var cbSid = new IntPtr(cbSidUint);
var succeed = WinApi.CheckTokenMembership(token, cbSid, out bool isMember);
return succeed && isMember;
}
return false;
}
public class WinApi
{
public const int TOKEN_QUERY = 0X00000008;
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool CreateWellKnownSid(WELL_KNOWN_SID_TYPE WellKnownSidType, IntPtr DomainSid, IntPtr pSid, out uint cbSid);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool CheckTokenMembership(IntPtr TokenHandle, IntPtr SidToCheck, out bool IsMember);
}
public enum ProcessAccessFlags : uint
{
QueryInformation = 0x00000400
}
public enum WELL_KNOWN_SID_TYPE
{
WinBuiltinAdministratorsSid = 26
}
windows winapi process system32 advapi32
windows winapi process system32 advapi32
edited Nov 24 '18 at 17:41
Uwe Keim
27.6k32132212
27.6k32132212
asked Nov 24 '18 at 14:23
Grigor YeghiazaryanGrigor Yeghiazaryan
12816
12816
2
errors: 1 you must open process with accessPROCESS_QUERY_LIMITED_INFORMATION
but notPROCESS_QUERY_INFORMATION
(you get access denied here if you not run as admin) 2CheckTokenMembership
work only with impersonation token.but you try pass primary token to it. 3 you not create admin sid - in single call toCreateWellKnownSid
you not pass pointer to memory where this sid can be stored. 4 you not close opened handles. 5 you not check any errors
– RbMm
Nov 24 '18 at 15:03
6 you not debug self code at all
– RbMm
Nov 24 '18 at 15:11
add a comment |
2
errors: 1 you must open process with accessPROCESS_QUERY_LIMITED_INFORMATION
but notPROCESS_QUERY_INFORMATION
(you get access denied here if you not run as admin) 2CheckTokenMembership
work only with impersonation token.but you try pass primary token to it. 3 you not create admin sid - in single call toCreateWellKnownSid
you not pass pointer to memory where this sid can be stored. 4 you not close opened handles. 5 you not check any errors
– RbMm
Nov 24 '18 at 15:03
6 you not debug self code at all
– RbMm
Nov 24 '18 at 15:11
2
2
errors: 1 you must open process with access
PROCESS_QUERY_LIMITED_INFORMATION
but not PROCESS_QUERY_INFORMATION
(you get access denied here if you not run as admin) 2 CheckTokenMembership
work only with impersonation token.but you try pass primary token to it. 3 you not create admin sid - in single call to CreateWellKnownSid
you not pass pointer to memory where this sid can be stored. 4 you not close opened handles. 5 you not check any errors– RbMm
Nov 24 '18 at 15:03
errors: 1 you must open process with access
PROCESS_QUERY_LIMITED_INFORMATION
but not PROCESS_QUERY_INFORMATION
(you get access denied here if you not run as admin) 2 CheckTokenMembership
work only with impersonation token.but you try pass primary token to it. 3 you not create admin sid - in single call to CreateWellKnownSid
you not pass pointer to memory where this sid can be stored. 4 you not close opened handles. 5 you not check any errors– RbMm
Nov 24 '18 at 15:03
6 you not debug self code at all
– RbMm
Nov 24 '18 at 15:11
6 you not debug self code at all
– RbMm
Nov 24 '18 at 15:11
add a comment |
2 Answers
2
active
oldest
votes
You cannot add handles together (new IntPtr(hProcess.ToInt64() + hToken.ToInt64());
), that makes no sense.
You need the process handle to get the process token handle, then pass the token handle to CheckTokenMembership
.
You also need to close these handles with CloseHandle
.
using System;
using System.Runtime.InteropServices;
...
public class WinApi
{
public const int TOKEN_DUPLICATE = 0x0002;
public const int TOKEN_QUERY = 0x00000008;
public const int SecurityImpersonation = 2;
public const int TokenImpersonation = 2;
[DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
[DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DuplicateTokenEx(IntPtr hTok, UInt32 DesiredAccess, IntPtr SecAttPtr, int ImpLvl, int TokType, out IntPtr TokenHandle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId);
[DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CreateWellKnownSid(WELL_KNOWN_SID_TYPE WellKnownSidType, IntPtr DomainSid, IntPtr pSid, ref uint cbSid);
[DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CheckTokenMembership(IntPtr TokenHandle, IntPtr SidToCheck, out bool IsMember);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int GetCurrentProcessId();
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int CloseHandle(IntPtr h);
}
public enum ProcessAccessFlags : uint
{
QueryInformation = 0x00000400,
QueryLimitedInformation = 0x1000
}
public enum WELL_KNOWN_SID_TYPE
{
WinBuiltinAdministratorsSid = 26
}
private static bool IsAdminGroupMember(int processId)
{
IntPtr hPriToken = IntPtr.Zero, hImpToken = IntPtr.Zero;
var hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryLimitedInformation, false, processId);
if (hProcess == IntPtr.Zero) hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryInformation, false, processId); // < Vista
var haveToken = WinApi.OpenProcessToken(hProcess, WinApi.TOKEN_DUPLICATE, out hPriToken);
if (haveToken)
{
haveToken = WinApi.DuplicateTokenEx(hPriToken, WinApi.TOKEN_QUERY, IntPtr.Zero, WinApi.SecurityImpersonation, WinApi.TokenImpersonation, out hImpToken);
WinApi.CloseHandle(hPriToken);
}
if (hProcess != IntPtr.Zero) WinApi.CloseHandle(hProcess);
if (haveToken)
{
uint cbSid = 0;
bool isMember = false;
WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, IntPtr.Zero, ref cbSid);
IntPtr pSid = Marshal.AllocCoTaskMem(Convert.ToInt32(cbSid));
var succeed = pSid != IntPtr.Zero && WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, pSid, ref cbSid);
succeed = succeed && WinApi.CheckTokenMembership(hImpToken, pSid, out isMember);
Marshal.FreeCoTaskMem(pSid);
WinApi.CloseHandle(hImpToken);
return succeed && isMember;
}
return false;
}
[STAThread]static void Main(/*string args*/)
{
bool admin = IsAdminGroupMember(WinApi.GetCurrentProcessId());
Console.WriteLine(string.Format("IsAdminGroupMember={0}", admin));
}
must be notProcessAccessFlags.QueryInformation
but ask only forPROCESS_QUERY_LIMITED_INFORMATION
(not admin process can not open admin withProcessAccessFlags.QueryInformation
(i guess that this is equal toPROCESS_QUERY_INFORMATION
. also we can callDuplicateToken
withoutEx
here and if want be correct check that first call toCreateWellKnownSid
fail withERROR_INSUFFICIENT_BUFFER
– RbMm
Nov 24 '18 at 17:35
@RbMM: It tries limited information first, then it tries the old one for XP. Technically, the documentation does not say that CreateWellKnownSid fails with a specific error. Either way, if cbSid is somehow incorrect then the memory allocation will fail or the next call to CreateWellKnownSid will fail, either way, the code is safe.
– Anders
Nov 24 '18 at 17:46
It tries limited information first, then it tries the old one for XP - sorry - not note this in your code.CreateWellKnownSid
- yes, which error returned in case we pass 0 pointer and 0 size not documented, but from another side not check error of api call and just try allocatecbSid
also wrong. may be sid type unknown ? more correct anyway check for this error, even if not explicit documented
– RbMm
Nov 24 '18 at 17:54
about access - i be usedwAccess = ver < 6.0 ? QueryInformation : QueryLimitedInformation
and call OpenProcess only once
– RbMm
Nov 24 '18 at 18:02
1
Microsoft says you are not suppose to do version checks. Anyway, only on < Vista will it call OpenProcess twice, not a big deal. Just allocating cbSid is fine, if it is a very large size then memory allocation might fail but that is fine if the SID was not well known. In this case we hardcode the well known sid so we know it will work.
– Anders
Nov 24 '18 at 18:43
|
show 1 more comment
I have created Process.Extensions.dll extension using solution offered by Anders
using System;
using ProcessExtensions;
using System.Diagnostics;
static void Main(string args)
{
bool isAdminGroupMember = Process.GetCurrentProcess().IsAdminGroupMember();
Console.WriteLine(string.Format("IsAdminGroupMember={0}", isAdminGroupMember));
}
https://github.com/IamhereTeam/Process.Extensions.git
Process.Extensions.dll
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53459123%2fcheck-if-another-process-has-admin-privileges%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You cannot add handles together (new IntPtr(hProcess.ToInt64() + hToken.ToInt64());
), that makes no sense.
You need the process handle to get the process token handle, then pass the token handle to CheckTokenMembership
.
You also need to close these handles with CloseHandle
.
using System;
using System.Runtime.InteropServices;
...
public class WinApi
{
public const int TOKEN_DUPLICATE = 0x0002;
public const int TOKEN_QUERY = 0x00000008;
public const int SecurityImpersonation = 2;
public const int TokenImpersonation = 2;
[DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
[DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DuplicateTokenEx(IntPtr hTok, UInt32 DesiredAccess, IntPtr SecAttPtr, int ImpLvl, int TokType, out IntPtr TokenHandle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId);
[DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CreateWellKnownSid(WELL_KNOWN_SID_TYPE WellKnownSidType, IntPtr DomainSid, IntPtr pSid, ref uint cbSid);
[DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CheckTokenMembership(IntPtr TokenHandle, IntPtr SidToCheck, out bool IsMember);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int GetCurrentProcessId();
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int CloseHandle(IntPtr h);
}
public enum ProcessAccessFlags : uint
{
QueryInformation = 0x00000400,
QueryLimitedInformation = 0x1000
}
public enum WELL_KNOWN_SID_TYPE
{
WinBuiltinAdministratorsSid = 26
}
private static bool IsAdminGroupMember(int processId)
{
IntPtr hPriToken = IntPtr.Zero, hImpToken = IntPtr.Zero;
var hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryLimitedInformation, false, processId);
if (hProcess == IntPtr.Zero) hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryInformation, false, processId); // < Vista
var haveToken = WinApi.OpenProcessToken(hProcess, WinApi.TOKEN_DUPLICATE, out hPriToken);
if (haveToken)
{
haveToken = WinApi.DuplicateTokenEx(hPriToken, WinApi.TOKEN_QUERY, IntPtr.Zero, WinApi.SecurityImpersonation, WinApi.TokenImpersonation, out hImpToken);
WinApi.CloseHandle(hPriToken);
}
if (hProcess != IntPtr.Zero) WinApi.CloseHandle(hProcess);
if (haveToken)
{
uint cbSid = 0;
bool isMember = false;
WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, IntPtr.Zero, ref cbSid);
IntPtr pSid = Marshal.AllocCoTaskMem(Convert.ToInt32(cbSid));
var succeed = pSid != IntPtr.Zero && WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, pSid, ref cbSid);
succeed = succeed && WinApi.CheckTokenMembership(hImpToken, pSid, out isMember);
Marshal.FreeCoTaskMem(pSid);
WinApi.CloseHandle(hImpToken);
return succeed && isMember;
}
return false;
}
[STAThread]static void Main(/*string args*/)
{
bool admin = IsAdminGroupMember(WinApi.GetCurrentProcessId());
Console.WriteLine(string.Format("IsAdminGroupMember={0}", admin));
}
must be notProcessAccessFlags.QueryInformation
but ask only forPROCESS_QUERY_LIMITED_INFORMATION
(not admin process can not open admin withProcessAccessFlags.QueryInformation
(i guess that this is equal toPROCESS_QUERY_INFORMATION
. also we can callDuplicateToken
withoutEx
here and if want be correct check that first call toCreateWellKnownSid
fail withERROR_INSUFFICIENT_BUFFER
– RbMm
Nov 24 '18 at 17:35
@RbMM: It tries limited information first, then it tries the old one for XP. Technically, the documentation does not say that CreateWellKnownSid fails with a specific error. Either way, if cbSid is somehow incorrect then the memory allocation will fail or the next call to CreateWellKnownSid will fail, either way, the code is safe.
– Anders
Nov 24 '18 at 17:46
It tries limited information first, then it tries the old one for XP - sorry - not note this in your code.CreateWellKnownSid
- yes, which error returned in case we pass 0 pointer and 0 size not documented, but from another side not check error of api call and just try allocatecbSid
also wrong. may be sid type unknown ? more correct anyway check for this error, even if not explicit documented
– RbMm
Nov 24 '18 at 17:54
about access - i be usedwAccess = ver < 6.0 ? QueryInformation : QueryLimitedInformation
and call OpenProcess only once
– RbMm
Nov 24 '18 at 18:02
1
Microsoft says you are not suppose to do version checks. Anyway, only on < Vista will it call OpenProcess twice, not a big deal. Just allocating cbSid is fine, if it is a very large size then memory allocation might fail but that is fine if the SID was not well known. In this case we hardcode the well known sid so we know it will work.
– Anders
Nov 24 '18 at 18:43
|
show 1 more comment
You cannot add handles together (new IntPtr(hProcess.ToInt64() + hToken.ToInt64());
), that makes no sense.
You need the process handle to get the process token handle, then pass the token handle to CheckTokenMembership
.
You also need to close these handles with CloseHandle
.
using System;
using System.Runtime.InteropServices;
...
public class WinApi
{
public const int TOKEN_DUPLICATE = 0x0002;
public const int TOKEN_QUERY = 0x00000008;
public const int SecurityImpersonation = 2;
public const int TokenImpersonation = 2;
[DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
[DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DuplicateTokenEx(IntPtr hTok, UInt32 DesiredAccess, IntPtr SecAttPtr, int ImpLvl, int TokType, out IntPtr TokenHandle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId);
[DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CreateWellKnownSid(WELL_KNOWN_SID_TYPE WellKnownSidType, IntPtr DomainSid, IntPtr pSid, ref uint cbSid);
[DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CheckTokenMembership(IntPtr TokenHandle, IntPtr SidToCheck, out bool IsMember);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int GetCurrentProcessId();
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int CloseHandle(IntPtr h);
}
public enum ProcessAccessFlags : uint
{
QueryInformation = 0x00000400,
QueryLimitedInformation = 0x1000
}
public enum WELL_KNOWN_SID_TYPE
{
WinBuiltinAdministratorsSid = 26
}
private static bool IsAdminGroupMember(int processId)
{
IntPtr hPriToken = IntPtr.Zero, hImpToken = IntPtr.Zero;
var hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryLimitedInformation, false, processId);
if (hProcess == IntPtr.Zero) hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryInformation, false, processId); // < Vista
var haveToken = WinApi.OpenProcessToken(hProcess, WinApi.TOKEN_DUPLICATE, out hPriToken);
if (haveToken)
{
haveToken = WinApi.DuplicateTokenEx(hPriToken, WinApi.TOKEN_QUERY, IntPtr.Zero, WinApi.SecurityImpersonation, WinApi.TokenImpersonation, out hImpToken);
WinApi.CloseHandle(hPriToken);
}
if (hProcess != IntPtr.Zero) WinApi.CloseHandle(hProcess);
if (haveToken)
{
uint cbSid = 0;
bool isMember = false;
WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, IntPtr.Zero, ref cbSid);
IntPtr pSid = Marshal.AllocCoTaskMem(Convert.ToInt32(cbSid));
var succeed = pSid != IntPtr.Zero && WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, pSid, ref cbSid);
succeed = succeed && WinApi.CheckTokenMembership(hImpToken, pSid, out isMember);
Marshal.FreeCoTaskMem(pSid);
WinApi.CloseHandle(hImpToken);
return succeed && isMember;
}
return false;
}
[STAThread]static void Main(/*string args*/)
{
bool admin = IsAdminGroupMember(WinApi.GetCurrentProcessId());
Console.WriteLine(string.Format("IsAdminGroupMember={0}", admin));
}
must be notProcessAccessFlags.QueryInformation
but ask only forPROCESS_QUERY_LIMITED_INFORMATION
(not admin process can not open admin withProcessAccessFlags.QueryInformation
(i guess that this is equal toPROCESS_QUERY_INFORMATION
. also we can callDuplicateToken
withoutEx
here and if want be correct check that first call toCreateWellKnownSid
fail withERROR_INSUFFICIENT_BUFFER
– RbMm
Nov 24 '18 at 17:35
@RbMM: It tries limited information first, then it tries the old one for XP. Technically, the documentation does not say that CreateWellKnownSid fails with a specific error. Either way, if cbSid is somehow incorrect then the memory allocation will fail or the next call to CreateWellKnownSid will fail, either way, the code is safe.
– Anders
Nov 24 '18 at 17:46
It tries limited information first, then it tries the old one for XP - sorry - not note this in your code.CreateWellKnownSid
- yes, which error returned in case we pass 0 pointer and 0 size not documented, but from another side not check error of api call and just try allocatecbSid
also wrong. may be sid type unknown ? more correct anyway check for this error, even if not explicit documented
– RbMm
Nov 24 '18 at 17:54
about access - i be usedwAccess = ver < 6.0 ? QueryInformation : QueryLimitedInformation
and call OpenProcess only once
– RbMm
Nov 24 '18 at 18:02
1
Microsoft says you are not suppose to do version checks. Anyway, only on < Vista will it call OpenProcess twice, not a big deal. Just allocating cbSid is fine, if it is a very large size then memory allocation might fail but that is fine if the SID was not well known. In this case we hardcode the well known sid so we know it will work.
– Anders
Nov 24 '18 at 18:43
|
show 1 more comment
You cannot add handles together (new IntPtr(hProcess.ToInt64() + hToken.ToInt64());
), that makes no sense.
You need the process handle to get the process token handle, then pass the token handle to CheckTokenMembership
.
You also need to close these handles with CloseHandle
.
using System;
using System.Runtime.InteropServices;
...
public class WinApi
{
public const int TOKEN_DUPLICATE = 0x0002;
public const int TOKEN_QUERY = 0x00000008;
public const int SecurityImpersonation = 2;
public const int TokenImpersonation = 2;
[DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
[DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DuplicateTokenEx(IntPtr hTok, UInt32 DesiredAccess, IntPtr SecAttPtr, int ImpLvl, int TokType, out IntPtr TokenHandle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId);
[DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CreateWellKnownSid(WELL_KNOWN_SID_TYPE WellKnownSidType, IntPtr DomainSid, IntPtr pSid, ref uint cbSid);
[DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CheckTokenMembership(IntPtr TokenHandle, IntPtr SidToCheck, out bool IsMember);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int GetCurrentProcessId();
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int CloseHandle(IntPtr h);
}
public enum ProcessAccessFlags : uint
{
QueryInformation = 0x00000400,
QueryLimitedInformation = 0x1000
}
public enum WELL_KNOWN_SID_TYPE
{
WinBuiltinAdministratorsSid = 26
}
private static bool IsAdminGroupMember(int processId)
{
IntPtr hPriToken = IntPtr.Zero, hImpToken = IntPtr.Zero;
var hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryLimitedInformation, false, processId);
if (hProcess == IntPtr.Zero) hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryInformation, false, processId); // < Vista
var haveToken = WinApi.OpenProcessToken(hProcess, WinApi.TOKEN_DUPLICATE, out hPriToken);
if (haveToken)
{
haveToken = WinApi.DuplicateTokenEx(hPriToken, WinApi.TOKEN_QUERY, IntPtr.Zero, WinApi.SecurityImpersonation, WinApi.TokenImpersonation, out hImpToken);
WinApi.CloseHandle(hPriToken);
}
if (hProcess != IntPtr.Zero) WinApi.CloseHandle(hProcess);
if (haveToken)
{
uint cbSid = 0;
bool isMember = false;
WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, IntPtr.Zero, ref cbSid);
IntPtr pSid = Marshal.AllocCoTaskMem(Convert.ToInt32(cbSid));
var succeed = pSid != IntPtr.Zero && WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, pSid, ref cbSid);
succeed = succeed && WinApi.CheckTokenMembership(hImpToken, pSid, out isMember);
Marshal.FreeCoTaskMem(pSid);
WinApi.CloseHandle(hImpToken);
return succeed && isMember;
}
return false;
}
[STAThread]static void Main(/*string args*/)
{
bool admin = IsAdminGroupMember(WinApi.GetCurrentProcessId());
Console.WriteLine(string.Format("IsAdminGroupMember={0}", admin));
}
You cannot add handles together (new IntPtr(hProcess.ToInt64() + hToken.ToInt64());
), that makes no sense.
You need the process handle to get the process token handle, then pass the token handle to CheckTokenMembership
.
You also need to close these handles with CloseHandle
.
using System;
using System.Runtime.InteropServices;
...
public class WinApi
{
public const int TOKEN_DUPLICATE = 0x0002;
public const int TOKEN_QUERY = 0x00000008;
public const int SecurityImpersonation = 2;
public const int TokenImpersonation = 2;
[DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
[DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DuplicateTokenEx(IntPtr hTok, UInt32 DesiredAccess, IntPtr SecAttPtr, int ImpLvl, int TokType, out IntPtr TokenHandle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId);
[DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CreateWellKnownSid(WELL_KNOWN_SID_TYPE WellKnownSidType, IntPtr DomainSid, IntPtr pSid, ref uint cbSid);
[DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CheckTokenMembership(IntPtr TokenHandle, IntPtr SidToCheck, out bool IsMember);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int GetCurrentProcessId();
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int CloseHandle(IntPtr h);
}
public enum ProcessAccessFlags : uint
{
QueryInformation = 0x00000400,
QueryLimitedInformation = 0x1000
}
public enum WELL_KNOWN_SID_TYPE
{
WinBuiltinAdministratorsSid = 26
}
private static bool IsAdminGroupMember(int processId)
{
IntPtr hPriToken = IntPtr.Zero, hImpToken = IntPtr.Zero;
var hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryLimitedInformation, false, processId);
if (hProcess == IntPtr.Zero) hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryInformation, false, processId); // < Vista
var haveToken = WinApi.OpenProcessToken(hProcess, WinApi.TOKEN_DUPLICATE, out hPriToken);
if (haveToken)
{
haveToken = WinApi.DuplicateTokenEx(hPriToken, WinApi.TOKEN_QUERY, IntPtr.Zero, WinApi.SecurityImpersonation, WinApi.TokenImpersonation, out hImpToken);
WinApi.CloseHandle(hPriToken);
}
if (hProcess != IntPtr.Zero) WinApi.CloseHandle(hProcess);
if (haveToken)
{
uint cbSid = 0;
bool isMember = false;
WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, IntPtr.Zero, ref cbSid);
IntPtr pSid = Marshal.AllocCoTaskMem(Convert.ToInt32(cbSid));
var succeed = pSid != IntPtr.Zero && WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, pSid, ref cbSid);
succeed = succeed && WinApi.CheckTokenMembership(hImpToken, pSid, out isMember);
Marshal.FreeCoTaskMem(pSid);
WinApi.CloseHandle(hImpToken);
return succeed && isMember;
}
return false;
}
[STAThread]static void Main(/*string args*/)
{
bool admin = IsAdminGroupMember(WinApi.GetCurrentProcessId());
Console.WriteLine(string.Format("IsAdminGroupMember={0}", admin));
}
answered Nov 24 '18 at 15:59
AndersAnders
70.4k1075128
70.4k1075128
must be notProcessAccessFlags.QueryInformation
but ask only forPROCESS_QUERY_LIMITED_INFORMATION
(not admin process can not open admin withProcessAccessFlags.QueryInformation
(i guess that this is equal toPROCESS_QUERY_INFORMATION
. also we can callDuplicateToken
withoutEx
here and if want be correct check that first call toCreateWellKnownSid
fail withERROR_INSUFFICIENT_BUFFER
– RbMm
Nov 24 '18 at 17:35
@RbMM: It tries limited information first, then it tries the old one for XP. Technically, the documentation does not say that CreateWellKnownSid fails with a specific error. Either way, if cbSid is somehow incorrect then the memory allocation will fail or the next call to CreateWellKnownSid will fail, either way, the code is safe.
– Anders
Nov 24 '18 at 17:46
It tries limited information first, then it tries the old one for XP - sorry - not note this in your code.CreateWellKnownSid
- yes, which error returned in case we pass 0 pointer and 0 size not documented, but from another side not check error of api call and just try allocatecbSid
also wrong. may be sid type unknown ? more correct anyway check for this error, even if not explicit documented
– RbMm
Nov 24 '18 at 17:54
about access - i be usedwAccess = ver < 6.0 ? QueryInformation : QueryLimitedInformation
and call OpenProcess only once
– RbMm
Nov 24 '18 at 18:02
1
Microsoft says you are not suppose to do version checks. Anyway, only on < Vista will it call OpenProcess twice, not a big deal. Just allocating cbSid is fine, if it is a very large size then memory allocation might fail but that is fine if the SID was not well known. In this case we hardcode the well known sid so we know it will work.
– Anders
Nov 24 '18 at 18:43
|
show 1 more comment
must be notProcessAccessFlags.QueryInformation
but ask only forPROCESS_QUERY_LIMITED_INFORMATION
(not admin process can not open admin withProcessAccessFlags.QueryInformation
(i guess that this is equal toPROCESS_QUERY_INFORMATION
. also we can callDuplicateToken
withoutEx
here and if want be correct check that first call toCreateWellKnownSid
fail withERROR_INSUFFICIENT_BUFFER
– RbMm
Nov 24 '18 at 17:35
@RbMM: It tries limited information first, then it tries the old one for XP. Technically, the documentation does not say that CreateWellKnownSid fails with a specific error. Either way, if cbSid is somehow incorrect then the memory allocation will fail or the next call to CreateWellKnownSid will fail, either way, the code is safe.
– Anders
Nov 24 '18 at 17:46
It tries limited information first, then it tries the old one for XP - sorry - not note this in your code.CreateWellKnownSid
- yes, which error returned in case we pass 0 pointer and 0 size not documented, but from another side not check error of api call and just try allocatecbSid
also wrong. may be sid type unknown ? more correct anyway check for this error, even if not explicit documented
– RbMm
Nov 24 '18 at 17:54
about access - i be usedwAccess = ver < 6.0 ? QueryInformation : QueryLimitedInformation
and call OpenProcess only once
– RbMm
Nov 24 '18 at 18:02
1
Microsoft says you are not suppose to do version checks. Anyway, only on < Vista will it call OpenProcess twice, not a big deal. Just allocating cbSid is fine, if it is a very large size then memory allocation might fail but that is fine if the SID was not well known. In this case we hardcode the well known sid so we know it will work.
– Anders
Nov 24 '18 at 18:43
must be not
ProcessAccessFlags.QueryInformation
but ask only for PROCESS_QUERY_LIMITED_INFORMATION
(not admin process can not open admin with ProcessAccessFlags.QueryInformation
(i guess that this is equal to PROCESS_QUERY_INFORMATION
. also we can call DuplicateToken
without Ex
here and if want be correct check that first call to CreateWellKnownSid
fail with ERROR_INSUFFICIENT_BUFFER
– RbMm
Nov 24 '18 at 17:35
must be not
ProcessAccessFlags.QueryInformation
but ask only for PROCESS_QUERY_LIMITED_INFORMATION
(not admin process can not open admin with ProcessAccessFlags.QueryInformation
(i guess that this is equal to PROCESS_QUERY_INFORMATION
. also we can call DuplicateToken
without Ex
here and if want be correct check that first call to CreateWellKnownSid
fail with ERROR_INSUFFICIENT_BUFFER
– RbMm
Nov 24 '18 at 17:35
@RbMM: It tries limited information first, then it tries the old one for XP. Technically, the documentation does not say that CreateWellKnownSid fails with a specific error. Either way, if cbSid is somehow incorrect then the memory allocation will fail or the next call to CreateWellKnownSid will fail, either way, the code is safe.
– Anders
Nov 24 '18 at 17:46
@RbMM: It tries limited information first, then it tries the old one for XP. Technically, the documentation does not say that CreateWellKnownSid fails with a specific error. Either way, if cbSid is somehow incorrect then the memory allocation will fail or the next call to CreateWellKnownSid will fail, either way, the code is safe.
– Anders
Nov 24 '18 at 17:46
It tries limited information first, then it tries the old one for XP - sorry - not note this in your code.
CreateWellKnownSid
- yes, which error returned in case we pass 0 pointer and 0 size not documented, but from another side not check error of api call and just try allocate cbSid
also wrong. may be sid type unknown ? more correct anyway check for this error, even if not explicit documented– RbMm
Nov 24 '18 at 17:54
It tries limited information first, then it tries the old one for XP - sorry - not note this in your code.
CreateWellKnownSid
- yes, which error returned in case we pass 0 pointer and 0 size not documented, but from another side not check error of api call and just try allocate cbSid
also wrong. may be sid type unknown ? more correct anyway check for this error, even if not explicit documented– RbMm
Nov 24 '18 at 17:54
about access - i be use
dwAccess = ver < 6.0 ? QueryInformation : QueryLimitedInformation
and call OpenProcess only once– RbMm
Nov 24 '18 at 18:02
about access - i be use
dwAccess = ver < 6.0 ? QueryInformation : QueryLimitedInformation
and call OpenProcess only once– RbMm
Nov 24 '18 at 18:02
1
1
Microsoft says you are not suppose to do version checks. Anyway, only on < Vista will it call OpenProcess twice, not a big deal. Just allocating cbSid is fine, if it is a very large size then memory allocation might fail but that is fine if the SID was not well known. In this case we hardcode the well known sid so we know it will work.
– Anders
Nov 24 '18 at 18:43
Microsoft says you are not suppose to do version checks. Anyway, only on < Vista will it call OpenProcess twice, not a big deal. Just allocating cbSid is fine, if it is a very large size then memory allocation might fail but that is fine if the SID was not well known. In this case we hardcode the well known sid so we know it will work.
– Anders
Nov 24 '18 at 18:43
|
show 1 more comment
I have created Process.Extensions.dll extension using solution offered by Anders
using System;
using ProcessExtensions;
using System.Diagnostics;
static void Main(string args)
{
bool isAdminGroupMember = Process.GetCurrentProcess().IsAdminGroupMember();
Console.WriteLine(string.Format("IsAdminGroupMember={0}", isAdminGroupMember));
}
https://github.com/IamhereTeam/Process.Extensions.git
Process.Extensions.dll
add a comment |
I have created Process.Extensions.dll extension using solution offered by Anders
using System;
using ProcessExtensions;
using System.Diagnostics;
static void Main(string args)
{
bool isAdminGroupMember = Process.GetCurrentProcess().IsAdminGroupMember();
Console.WriteLine(string.Format("IsAdminGroupMember={0}", isAdminGroupMember));
}
https://github.com/IamhereTeam/Process.Extensions.git
Process.Extensions.dll
add a comment |
I have created Process.Extensions.dll extension using solution offered by Anders
using System;
using ProcessExtensions;
using System.Diagnostics;
static void Main(string args)
{
bool isAdminGroupMember = Process.GetCurrentProcess().IsAdminGroupMember();
Console.WriteLine(string.Format("IsAdminGroupMember={0}", isAdminGroupMember));
}
https://github.com/IamhereTeam/Process.Extensions.git
Process.Extensions.dll
I have created Process.Extensions.dll extension using solution offered by Anders
using System;
using ProcessExtensions;
using System.Diagnostics;
static void Main(string args)
{
bool isAdminGroupMember = Process.GetCurrentProcess().IsAdminGroupMember();
Console.WriteLine(string.Format("IsAdminGroupMember={0}", isAdminGroupMember));
}
https://github.com/IamhereTeam/Process.Extensions.git
Process.Extensions.dll
edited Nov 24 '18 at 17:44
answered Nov 24 '18 at 17:30
Grigor YeghiazaryanGrigor Yeghiazaryan
12816
12816
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53459123%2fcheck-if-another-process-has-admin-privileges%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
errors: 1 you must open process with access
PROCESS_QUERY_LIMITED_INFORMATION
but notPROCESS_QUERY_INFORMATION
(you get access denied here if you not run as admin) 2CheckTokenMembership
work only with impersonation token.but you try pass primary token to it. 3 you not create admin sid - in single call toCreateWellKnownSid
you not pass pointer to memory where this sid can be stored. 4 you not close opened handles. 5 you not check any errors– RbMm
Nov 24 '18 at 15:03
6 you not debug self code at all
– RbMm
Nov 24 '18 at 15:11