简体   繁体   English

API挂钩,在TerminateProcess函数上找到意外的句柄

[英]API Hooking, unexpected handle found on TerminateProcess function

PROBLEM 问题

I've hooked the TerminateProcess calls to identify the process which is being terminated, but I'm getting an unexpected handle from TerminateProcess that does not match with the real process handle that I try to intercept. 我已经挂钩了TerminateProcess调用以识别正在终止的进程,但是我从TerminateProcess获得了一个意外的句柄,它与我试图拦截的实际进程句柄不匹配。

I'm using Deviare library but I think this issue could be solved just knowing how the TerminateProcess function works and what I need to do to perform a proper handle comparison. 我正在使用Deviare库但我认为只要知道TerminateProcess函数如何工作以及我需要做什么来执行正确的句柄比较就可以解决这个问题。

QUESTION: 题:

If I know the handle of a process which I want to identify its termination, how I could identify that handle from hProcess param of TerminateProcess function? 如果我知道我想要识别其终止的进程的句柄,我如何从TerminateProcess函数的hProcess参数中识别该句柄?

CODE: 码:

Note the part where I try to compare the handles: 请注意我尝试比较句柄的部分:

If Process.GetProcessesByName("notepad").FirstOrDefault.Handle = hProcessValue Then ...

It will never be the same handles (I also tried with MainWindowHandle and the Process ID ID ) 它永远不会是相同的句柄(我也试过MainWindowHandle进程ID ID

So, the value of hProcess parameter is very unknown for me. 因此, 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

RESEARCH: 研究:

I've been reading the MSDN doc of TerminateProcess . 我一直在阅读TerminateProcess的MSDN文档。

Note the parts where it says: 注意它所说的部分:

The handle must have the PROCESS_TERMINATE access right 句柄必须具有PROCESS_TERMINATE访问权限

I'm not sure whether I'm missed something to compare the handles. 我不确定我是否错过了比较手柄的东西。

Also I've been reading here but I didn't take any in clear: 我也一直在这里读书,但我没有明白:

Hooking TerminateProcess & Getting Info From The Handle It Supplies Hooking TerminateProcess和从Handle It Supplies获取信息

I also designed this Enum if it could be necessary to perform a good handle comparison: 如果可能需要执行良好的句柄比较,我还设计了这个枚举:

    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

Your code is assuming that there is only one handle per process. 您的代码假设每个进程只有一个句柄。 This is not right. 这是不对的。 There is one process ID per process. 每个进程有一个进程ID。 But every time someone requests a handle for a process, for example with OpenProcess(..., ..., procid) he gets a new process handle (which also depends on the desired access). 但每当有人请求进程的句柄时,例如使用OpenProcess(..., ..., procid)他就会获得一个新的进程句柄(这也取决于所需的访问权限)。

So you cannot compare the handles, you should check the module name or the process id. 因此您无法比较句柄,您应该检查模块名称或进程ID。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM