我正在尝试使用 API 挂钩嗅探命名管道消息。我正在使用以下 C# 代码。当我使用命名管道流进行通信时,我没有看到任何命名管道消息。如有任何帮助,我们将不胜感激。
using System;
using System.Diagnostics;
using System.IO;
using System.IO.Pipes;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
public class PipeMonitor
{
private const string KERNEL32_DLL = "kernel32.dll";
private const string NTDLL_DLL = "ntdll.dll";
private delegate bool ConnectNamedPipeDelegate(IntPtr hNamedPipe, IntPtr lpOverlapped);
private static ConnectNamedPipeDelegate originalConnectNamedPipe;
private static ConnectNamedPipeDelegate hookConnectNamedPipe;
[DllImport("kernel32.dll")]
private static extern bool GetNamedPipeHandleState(IntPtr hNamedPipe, out int lpState, IntPtr lpCurInstances, IntPtr lpMaxCollectionCount, IntPtr lpCollectDataTimeout, IntPtr lpUserName, uint nMaxUserNameSize);
private static class PipeState
{
public const int PIPE_CONNECTED_STATE = 2;
}
private static bool HookConnectNamedPipe(IntPtr hNamedPipe, IntPtr lpOverlapped)
{
bool result = originalConnectNamedPipe(hNamedPipe, lpOverlapped);
if (result)
{
string pipeName = GetPipeNameFromHandle(hNamedPipe);
Console.WriteLine($"Message received on pipe '{pipeName}'");
}
return result;
}
private static string GetPipeNameFromHandle(IntPtr hNamedPipe)
{
StringBuilder pipeName = new StringBuilder(256);
IntPtr hWnd = new IntPtr(Convert.ToInt32(pipeName));
int state;
if (GetNamedPipeHandleState(hNamedPipe, out state, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, 0))
{
if (state != PipeState.PIPE_CONNECTED_STATE)
{
return null;
}
if (GetNamedPipeHandleState(hNamedPipe, out state, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, hWnd, 256))
{
return pipeName.ToString();
}
}
return true ? pipeName.ToString() : null;
}
private static void HookConnectNamedPipe()
{
IntPtr kernel32ModuleHandle = NativeMethods.GetModuleHandle(KERNEL32_DLL);
IntPtr connectNamedPipeAddress = NativeMethods.GetProcAddress(kernel32ModuleHandle, "ConnectNamedPipe");
originalConnectNamedPipe = Marshal.GetDelegateForFunctionPointer<ConnectNamedPipeDelegate>(connectNamedPipeAddress);
hookConnectNamedPipe = HookConnectNamedPipe;
uint oldProtect;
NativeMethods.VirtualProtect(connectNamedPipeAddress, (UIntPtr)5, 0x40, out oldProtect);
IntPtr hookPointer = Marshal.GetFunctionPointerForDelegate(hookConnectNamedPipe);
Marshal.WriteByte(connectNamedPipeAddress, 0xE9);
Marshal.WriteInt32(connectNamedPipeAddress + 1, (int)(hookPointer.ToInt64() - connectNamedPipeAddress.ToInt64() - 5));
}
private static class NativeMethods
{
[DllImport(KERNEL32_DLL, SetLastError = true)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport(KERNEL32_DLL, SetLastError = true)]
public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
[DllImport(KERNEL32_DLL, SetLastError = true)]
public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
[DllImport(KERNEL32_DLL, SetLastError = true)]
public static extern bool GetNamedPipeHandleState(IntPtr hNamedPipe, IntPtr lpState, IntPtr lpCurInstances, IntPtr lpMaxCollectionCount, IntPtr lpCollectDataTimeout, StringBuilder lpUserName, int nMaxUserNameSize);
}
public static void Main(string[] args)
{
HookConnectNamedPipe();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
我不确定我的 API hooking 方式是否正确。它没有向我显示任何消息。有人可以确认我进行 API hooking 的方式是否正确以及为什么吗
你在当前进程中hook ConnectNamedPipe,但是hook后程序并没有调用ConnectNamedPipe。