Перехват 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) он получает новый дескриптор процесса (который также зависит от желаемого доступа).

Таким образом, вы не можете сравнить дескрипторы, вы должны проверить имя модуля или идентификатор процесса.

Другие вопросы по тегам