Enable Privilege
bool EnableDebugPrivilege()
{
HANDLE hToken;
LUID sedebugnameValue;
TOKEN_PRIVILEGES tkp;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
return FALSE;
}
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue))
{
CloseHandle(hToken);
return false;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = sedebugnameValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL))
{
CloseHandle(hToken);
return false;
}
return true;
}
以上是进程提权的常见方法。此外可以直接调用未公开的api更方便
NTSTATUS
RtlAdjustPrivilege(
ULONG Privilege,
BOOLEAN Enable,
BOOLEAN Client,
PBOOLEAN WasEnabled
)
/*++
Routine Description:
This procedure enables or disables a privilege process-wide.
Arguments:
Privilege - The lower 32-bits of the privilege ID to be enabled or
disabled. The upper 32-bits is assumed to be zero.
Enable - A boolean indicating whether the privilege is to be enabled
or disabled. TRUE indicates the privilege is to be enabled.
FALSE indicates the privilege is to be disabled.
Client - A boolean indicating whether the privilege should be adjusted
in a client token or the process's own token. TRUE indicates
the client's token should be used (and an error returned if there
is no client token). FALSE indicates the process's token should
be used.
WasEnabled - points to a boolean to receive an indication of whether
the privilege was previously enabled or disabled. TRUE indicates
the privilege was previously enabled. FALSE indicates the privilege
was previously disabled. This value is useful for returning the
privilege to its original state after using it.
Return Value:
STATUS_SUCCESS - The privilege has been successfully enabled or disabled.
STATUS_PRIVILEGE_NOT_HELD - The privilege is not held by the specified context.
Other status values as may be returned by:
NtOpenProcessToken()
NtAdjustPrivilegesToken()
--*/
{
NTSTATUS
Status,
TmpStatus;
HANDLE
Token;
LUID
LuidPrivilege;
PTOKEN_PRIVILEGES
NewPrivileges,
OldPrivileges;
ULONG
Length;
UCHAR
Buffer1[sizeof(TOKEN_PRIVILEGES)+
((1-ANYSIZE_ARRAY)*sizeof(LUID_AND_ATTRIBUTES))],
Buffer2[sizeof(TOKEN_PRIVILEGES)+
((1-ANYSIZE_ARRAY)*sizeof(LUID_AND_ATTRIBUTES))];
RTL_PAGED_CODE();
NewPrivileges = (PTOKEN_PRIVILEGES)Buffer1;
OldPrivileges = (PTOKEN_PRIVILEGES)Buffer2;
//
// Open the appropriate token...
//
if (Client == TRUE) {
Status = NtOpenThreadToken(
NtCurrentThread(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
FALSE,
&Token
);
} else {
Status = NtOpenProcessToken(
NtCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&Token
);
}
if (!NT_SUCCESS(Status)) {
return(Status);
}
//
// Initialize the privilege adjustment structure
//
LuidPrivilege = RtlConvertUlongToLuid(Privilege);
NewPrivileges->PrivilegeCount = 1;
NewPrivileges->Privileges[0].Luid = LuidPrivilege;
NewPrivileges->Privileges[0].Attributes = Enable ? SE_PRIVILEGE_ENABLED : 0;
//
// Adjust the privilege
//
Status = NtAdjustPrivilegesToken(
Token, // TokenHandle
FALSE, // DisableAllPrivileges
NewPrivileges, // NewPrivileges
sizeof(Buffer1), // BufferLength
OldPrivileges, // PreviousState (OPTIONAL)
&Length // ReturnLength
);
TmpStatus = NtClose(Token);
ASSERT(NT_SUCCESS(TmpStatus));
//
// Map the success code NOT_ALL_ASSIGNED to an appropriate error
// since we're only trying to adjust the one privilege.
//
if (Status == STATUS_NOT_ALL_ASSIGNED) {
Status = STATUS_PRIVILEGE_NOT_HELD;
}
if (NT_SUCCESS(Status)) {
//
// If there are no privileges in the previous state, there were
// no changes made. The previous state of the privilege
// is whatever we tried to change it to.
//
if (OldPrivileges->PrivilegeCount == 0) {
(*WasEnabled) = Enable;
} else {
(*WasEnabled) =
(OldPrivileges->Privileges[0].Attributes & SE_PRIVILEGE_ENABLED)
? TRUE : FALSE;
}
}
return(Status);
}
浙公网安备 33010602011771号