API 挂钩,在 TerminateProcess 函数上发现意外句柄
API Hooking, unexpected handle found on TerminateProcess function
问题
我已经挂钩了 TerminateProcess 调用来识别正在终止的进程,但是我从 TerminateProcess
得到了一个意外的句柄,它与我的真实进程句柄不匹配尝试拦截。
我正在使用 Deviare 库,但我认为只要知道 TerminateProcess
函数的工作原理以及我需要做什么才能正确执行此操作,这个问题就可以解决处理比较。
问题:
如果我知道要识别其终止的进程的句柄,我如何从 TerminateProcess
函数的 hProcess
参数中识别该句柄?
代码:
请注意我尝试比较句柄的部分:
If Process.GetProcessesByName("notepad").FirstOrDefault.Handle = hProcessValue Then ...
它永远不会是相同的句柄(我也尝试使用 MainWindowHandle
和 进程 ID 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
研究:
我一直在阅读 TerminateProcess 的 MSDN 文档。
注意它说的部分:
The handle must have the PROCESS_TERMINATE access right
我不确定我是否遗漏了一些比较手柄的东西。
我也一直在读这里,但我没有看清楚:
Hooking TerminateProcess & Getting Info From The Handle It Supplies
如果有必要进行良好的句柄比较,我还设计了这个枚举:
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
您的代码假设每个进程只有一个句柄。这是不对的。每个进程有一个进程 ID。但是每次有人请求进程的句柄时,例如 OpenProcess(..., ..., procid)
他都会得到一个新的进程句柄(这也取决于所需的访问权限)。
所以你不能比较句柄,你应该检查模块名称或进程ID。
问题
我已经挂钩了 TerminateProcess 调用来识别正在终止的进程,但是我从 TerminateProcess
得到了一个意外的句柄,它与我的真实进程句柄不匹配尝试拦截。
我正在使用 Deviare 库,但我认为只要知道 TerminateProcess
函数的工作原理以及我需要做什么才能正确执行此操作,这个问题就可以解决处理比较。
问题:
如果我知道要识别其终止的进程的句柄,我如何从 TerminateProcess
函数的 hProcess
参数中识别该句柄?
代码:
请注意我尝试比较句柄的部分:
If Process.GetProcessesByName("notepad").FirstOrDefault.Handle = hProcessValue Then ...
它永远不会是相同的句柄(我也尝试使用 MainWindowHandle
和 进程 ID 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
研究:
我一直在阅读 TerminateProcess 的 MSDN 文档。
注意它说的部分:
The handle must have the PROCESS_TERMINATE access right
我不确定我是否遗漏了一些比较手柄的东西。
我也一直在读这里,但我没有看清楚:
Hooking TerminateProcess & Getting Info From The Handle It Supplies
如果有必要进行良好的句柄比较,我还设计了这个枚举:
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
您的代码假设每个进程只有一个句柄。这是不对的。每个进程有一个进程 ID。但是每次有人请求进程的句柄时,例如 OpenProcess(..., ..., procid)
他都会得到一个新的进程句柄(这也取决于所需的访问权限)。
所以你不能比较句柄,你应该检查模块名称或进程ID。