Перехват API, неожиданный дескриптор найден в функции TerminateProcess
ПРОБЛЕМА
Я перехватил вызовы TerminateProcess, чтобы определить процесс, который завершается, но я получаю неожиданный указатель от TerminateProcess
это не соответствует реальному дескриптору процесса, который я пытаюсь перехватить.
Я использую библиотеку Deviare, но я думаю, что эту проблему можно решить, просто зная, как TerminateProcess
Функция работает и что мне нужно сделать, чтобы выполнить правильное сравнение дескриптора.
ВОПРОС:
Если я знаю дескриптор процесса, который я хочу идентифицировать его завершение, как я мог бы идентифицировать этот дескриптор из hProcess
параметр TerminateProcess
функционировать?
КОД:
Обратите внимание на часть, где я пытаюсь сравнить ручки:
If Process.GetProcessesByName("notepad").FirstOrDefault.Handle = hProcessValue Then ...
Никогда не будет одинаковых ручек (я тоже пробовал с MainWindowHandle
и идентификатор процесса ID
)
Итак, ценность hProcess
параметр для меня очень неизвестен.
Imports Nektra.Deviare2
Public NotInheritable Class Form1
Public WithEvents SpyMgr As NktSpyMgr
Public Hook As NktHook
ReadOnly libName As String = "kernel32.dll"
ReadOnly funcName As String = "TerminateProcess"
ReadOnly hookFlags As eNktHookFlags = eNktHookFlags.flgOnlyPreCall
' Processes to attach the hook.
ReadOnly processesToAttach As IEnumerable(Of Process) =
Process.GetProcessesByName("taskmgr")
Private Sub Test() Handles MyBase.Load
If Me.processesToAttach.Count = 0 Then
MsgBox("Any process found.")
Else
Me.SpyMgr = New NktSpyMgr()
Me.SpyMgr.Initialize()
Me.Hook = SpyMgr.CreateHook(String.Format("{0}!{1}", libName, funcName), hookFlags)
Me.Hook.Hook(sync:=True)
For Each proc As Process In processesToAttach
Debug.WriteLine("Attaching to: " & proc.ProcessName)
Me.Hook.Attach(procOrId:=proc.Id, sync:=True)
Next proc
End If
End Sub
<MTAThread>
Private Sub OnTerminateProcess_Called(ByVal hook As NktHook,
ByVal proc As NktProcess,
ByVal callInfo As NktHookCallInfo) Handles SpyMgr.OnFunctionCalled
' Function params.
Dim hProcessParam As NktParam = DirectCast(callInfo.Params(0), NktParam)
Dim uExitCodeParam As NktParam = DirectCast(callInfo.Params(1), NktParam)
' Param values.
Dim hProcessValue As IntPtr = New IntPtr(CInt(hProcessParam.Value))
Dim uExitCodeValue As UInteger = CUInt(uExitCodeParam.Value)
' Debuf info.
Trace.WriteLine(String.Format("hProcess : '{0}'", hProcessValue))
Trace.WriteLine(String.Format("uExitCode: '{0}'", uExitCodeValue))
' Handle Comparison
If Process.GetProcessesByName("notepad").FirstOrDefault.Handle = hProcessValue Then
' Skip precall to avoid process termination.
If callInfo.IsPreCall Then
callInfo.Result.Value = 1
callInfo.SkipCall()
End If
End If
End Sub
End Class
ИССЛЕДОВАНИЕ:
Я читал документ MSDN TerminateProcess.
Обратите внимание на части, где написано:
Дескриптор должен иметь право доступа PROCESS_TERMINATE
Я не уверен, что я что-то упустил, чтобы сравнить ручки.
Также я читал здесь, но я не взял ничего в чистом виде:
Перехват TerminateProcess и получение информации от Handle It
Я также разработал этот Enum, если это может потребоваться для хорошего сравнения дескрипторов:
Public Enum ProcessAccessFlags As UInteger
All = &H1F0FFF
Terminate = &H1
CreateThread = &H2
VirtualMemoryOperation = &H8
VirtualMemoryRead = &H10
VirtualMemoryWrite = &H20
DuplicateHandle = &H40
CreateProcess = &H80
SetQuota = &H100
SetInformation = &H200
QueryInformation = &H400
QueryLimitedInformation = &H1000
Synchronize = &H100000
End Enum
1 ответ
Ваш код предполагает, что для каждого процесса существует только один дескриптор. Это неправильно. Для каждого процесса существует один идентификатор процесса. Но каждый раз, когда кто-то запрашивает дескриптор процесса, например, с OpenProcess(..., ..., procid)
он получает новый дескриптор процесса (который также зависит от желаемого доступа).
Таким образом, вы не можете сравнить дескрипторы, вы должны проверить имя модуля или идентификатор процесса.