命名管道监视器

问题描述 投票:0回答:1

我正在尝试使用 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 的方式是否正确以及为什么吗

c# named-pipes
1个回答
0
投票

你在当前进程中hook ConnectNamedPipe,但是hook后程序并没有调用ConnectNamedPipe。

© www.soinside.com 2019 - 2024. All rights reserved.