AdjustTokenPrivileges fails with error code 1300

Viewed 226

I trying to terminate a SYSTEM process, but my attempts to kill it fail.

The first error occurs when I call AdjustTokenPrivileges.

GetLastError returns 1300 which means ERROR_NOT_ALL_ASSIGNED.

What do I need to change make it work?

I want to complete this task with as little previleges as possible. I want to avoid triggering UAC.

Also, my application does not require admin rights, and I would like to keep that.

Thank you!

enter image description here

Here is my entire code:

Option Explicit

Private Type Luid
   UsedPart As Long
   IgnoredForNowHigh32BitPart As Long
End Type


Const TH32CS_SNAPHEAPLIST = &H1
Const TH32CS_SNAPPROCESS = &H2
Const TH32CS_SNAPTHREAD = &H4
Const TH32CS_SNAPMODULE = &H8
Private Const TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST Or TH32CS_SNAPPROCESS Or TH32CS_SNAPTHREAD Or TH32CS_SNAPMODULE)
Const TH32CS_INHERIT = &H80000000
Const MAX_PATH As Integer = 260

Private Const PROCESS_QUERY_LIMITED_INFORMATION = &H1000
Private Const PROCESS_QUERY_INFORMATION = &H400
Private Const STATUS_PENDING = &H103&

Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

Private Type PROCESSENTRY32
   dwSize As Long
   cntUsage As Long
   th32ProcessID As Long
   th32DefaultHeapID As Long
   th32BookID As Long
   cntThreads As Long
   th32ParentProcessID As Long
   pcPriClassBase As Long
   dwFlags As Long
   szExeFile As String * 260
End Type

Private Declare Function CreateToolhelp32Snapshot Lib "kernel32" (ByVal dwFlags As Long, ByVal th32ProcessID As Long) As Long
Private Declare Function Process32First Lib "kernel32" (ByVal hSnapshot As Long, lppe As PROCESSENTRY32) As Long
Private Declare Function Process32Next Lib "kernel32" (ByVal hSnapshot As Long, lppe As PROCESSENTRY32) As Long

Private Declare Function OpenProcessToken Lib "advapi32.dll" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
Private Declare Function AdjustTokenPrivileges Lib "advapi32.dll" (ByVal TokenHandle As Long, ByVal DisableAllPrivileges As Long, NewState As TOKEN_PRIVILEGES, ByVal BufferLength As Long, PreviousState As TOKEN_PRIVILEGES, ReturnLength As Long) As Long
Private Declare Function LookupPrivilegeValue Lib "advapi32.dll" Alias "LookupPrivilegeValueA" (ByVal lpSystemName As String, ByVal lpName As String, lpLuid As Luid) As Long

Private Const ANYSIZE_ARRAY = 1
Private Const TOKEN_ADJUST_PRIVILEGES = &H20
Private Const TOKEN_QUERY = &H8
Private Const SE_PRIVILEGE_ENABLED = &H2
Private Const PROCESS_TERMINATE = &H1

Private Declare Function TerminateProcess Lib "kernel32" (ByVal ApphProcess As Long, ByVal uExitCode As Long) As Long
Private Declare Function OpenProcess Lib "Kernel32.dll" (ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long
Private Declare Function EnumProcesses Lib "psapi.dll" (ByRef lpidProcess As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long
Private Declare Function EnumProcessModules Lib "psapi.dll" (ByVal hProcess As Long, ByRef lphModule As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long

Private Const SYNCHRONIZE = &H100000
Private Const PROCESS_ALL_ACCESS = &H1F0FFF

Private Type LUID_AND_ATTRIBUTES
   pLuid As Luid
   Attributes As Long
End Type

Private Type TOKEN_PRIVILEGES
    PrivilegeCount As Long
    Privileges(ANYSIZE_ARRAY) As LUID_AND_ATTRIBUTES
End Type

Private Const SE_DEBUG_NAME = "SeDebugPrivilege"
        
Private Sub cmd1_Click()

    TerminateProcessByName "AnyDesk.exe"

End Sub

Private Sub TerminateProcessByName(ByVal u As String)
    
    Dim sName As String
    Dim PList As String
    Dim ret As Long
    Dim hSnap As Long
    Dim proc As PROCESSENTRY32
    
    hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0)
    If hSnap = 0 Then
        Exit Sub
    End If
    
    proc.dwSize = LenB(proc)

    Dim f As Long
    f = Process32First(hSnap, proc)
    Do
        sName = proc.szExeFile
        sName = Left(sName, InStr(sName, Chr(0)) - 1)
        If sName = u Then
            KillProcess proc.th32ProcessID
        End If
        f = Process32Next(hSnap, proc)
    Loop While f = 1
    
    ret = CloseHandle(hSnap)

End Sub

Private Function SetPrivilege(hToken As Long, Privilege As String, bSetFlag As Boolean) As Boolean

   Dim TP As TOKEN_PRIVILEGES          ' Used in getting the current
                                       ' token privileges
   Dim TPPrevious As TOKEN_PRIVILEGES  ' Used in setting the new
                                       ' token privileges
   Dim Luid As Luid                    ' Stores the Local Unique
                                       ' Identifier - refer to MSDN
   Dim cbPrevious As Long              ' Previous size of the
                                       ' TOKEN_PRIVILEGES structure
   Dim lResult As Long                 ' Result of various API calls

   ' Grab the size of the TOKEN_PRIVILEGES structure,
   ' used in making the API calls.
   cbPrevious = Len(TP)

   ' Grab the LUID for the request privilege.
   lResult = LookupPrivilegeValue("", Privilege, Luid)

   ' If LoopupPrivilegeValue fails, the return result will be zero.
   ' Test to make sure that the call succeeded.
   If (lResult = 0) Then
        Debug.Assert False
      SetPrivilege = False
   End If

   ' Set up basic information for a call.
   ' You want to retrieve the current privileges
   ' of the token under concern before you can modify them.
   TP.PrivilegeCount = 1
   TP.Privileges(0).pLuid = Luid
   TP.Privileges(0).Attributes = 0
   SetPrivilege = lResult

   ' You need to acquire the current privileges first
   lResult = AdjustTokenPrivileges(hToken, -1, TP, Len(TP), _
                                  TPPrevious, cbPrevious)

   ' If AdjustTokenPrivileges fails, the return result is zero,
   ' test for success.
   If (lResult = 0) Then
      SetPrivilege = False
   End If

    lResult = Err.LastDllError
    If lResult <> 0 Then
        Debug.Assert False
        SetPrivilege = False
        Exit Function
    End If

   ' Now you can set the token privilege information
   ' to what the user is requesting.
   TPPrevious.PrivilegeCount = 1
   TPPrevious.Privileges(0).pLuid = Luid

   ' either enable or disable the privilege,
   ' depending on what the user wants.
   Select Case bSetFlag
      Case True: TPPrevious.Privileges(0).Attributes = TPPrevious.Privileges(0).Attributes Or (SE_PRIVILEGE_ENABLED)
      Case False: TPPrevious.Privileges(0).Attributes = TPPrevious.Privileges(0).Attributes Xor (SE_PRIVILEGE_ENABLED And TPPrevious.Privileges(0).Attributes)
   End Select

   ' Call adjust the token privilege information.
   lResult = AdjustTokenPrivileges(hToken, -1, TPPrevious, cbPrevious, TP, cbPrevious)

   ' Determine your final result of this function.
   If (lResult = 0) Then
      ' You were not able to set the privilege on this token.
      SetPrivilege = False
   Else
   
        lResult = Err.LastDllError
        If lResult <> 0 Then
            Debug.Assert False
            SetPrivilege = False
            Exit Function
        End If

      ' You managed to modify the token privilege
      SetPrivilege = True
   End If

End Function
Private Sub KillProcess(ByVal uIDOfProcessToKill As Long)

    Dim hProcessID As Long         ' Handle to your sample
                                   ' process you are going to
                                   ' terminate.
    Dim hProcess As Long           ' Handle to your current process
                                
    Dim hToken As Long             ' Handle to your process token.
    Dim lPrivilege As Long         ' Privilege to enable/disable
    Dim iPrivilegeflag As Boolean  ' Flag whether to enable/disable
                                   ' the privilege of concern.
    Dim lResult As Long            ' Result call of various APIs.

    ' set the incoming PID to our internal variable
    hProcessID = uIDOfProcessToKill

    ' get our current process handle
    hProcess = GetCurrentProcess

    ' open the tokens for this our own app
    lResult = OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES Or _
                              TOKEN_QUERY, hToken)

    If (lResult = 0) Then
         Debug.Assert False
        MsgBox "Error:  Unable To Open Process Token: " & Err.LastDllError
       CloseHandle (hToken)
       Exit Sub
    End If

    ' Now that you have the token for this process, you want to set
    ' the SE_DEBUG_NAME privilege.
    lResult = SetPrivilege(hToken, SE_DEBUG_NAME, True)

    ' Make sure you could set the privilege on this token.
    If (lResult = False) Then
        MsgBox "Error : Could Not Set SeDebug Privilege on Token Handle"
        Debug.Assert False
        CloseHandle (hToken)
        Exit Sub
    End If

    ' Now that you have changed the privileges on the token,
    ' have some fun. You can now get a process handle to the
    ' process ID that you passed into this program, and
    ' demand whatever access you want on it!

    hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, hProcessID)

    ' Make sure you opened the process so you can do stuff with it
    If (hProcess = 0) Then
         Debug.Assert False
        MsgBox "Error : Unable To Open Process : " & Err.LastDllError 'error 5
        CloseHandle (hToken)
        Exit Sub
    End If

    ' Now turn the SE_DEBUG_PRIV back off,
    lResult = SetPrivilege(hToken, SE_DEBUG_NAME, False)

    ' Make sure you succeeded in reversing the privilege!
    If (lResult = False) Then
        Debug.Assert False
        MsgBox "Error : Unable To Disable SeDebug Privilege On Token Handle"
        CloseHandle (hProcess)
        CloseHandle (hToken)
       Exit Sub
    End If

    ' Now you want to kill the application, which you can do since
    ' your process handle to the application includes full access to
    ' romp and roam - you got the process handle when you had the
    ' SE_DEBUG_NAME privilege enabled!
    lResult = TerminateProcess(hProcess, 0)

    ' Let's see the result, and go from there.
    If (lResult = 0) Then
        lResult = Err.LastDllError '6=ERROR_INVALID_HANDLE
        Debug.Assert False

        CloseHandle (hProcess)
        CloseHandle (hToken)
        Exit Sub
    End If

    ' Close our handles and get out of here.
    CloseHandle (hProcess)
    CloseHandle (hToken)

End Sub
0 Answers
Related