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!
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
