C# 在.NET-全局Win32调试挂钩中复制DebugView的功能?

C# 在.NET-全局Win32调试挂钩中复制DebugView的功能?,c#,.net,debugging,winapi,C#,.net,Debugging,Winapi,我感兴趣的是,以DebugView的方式在系统范围内捕获Win32调试跟踪的可能性有多大。谢天谢地,我对内核消息不感兴趣,所以我不需要任何帮助。这需要使用C#,但如果必要,我很乐意使用非托管/不安全 有没有什么全球性的勾当我可以得到,或者我正在走一条艰难的道路 我真的不确定从哪里开始这个问题最好。我将从类开始,尽管我不确定是否可以使用它来捕获Win32调试跟踪。我终于做到了。这需要一些认真的谷歌搜索,但我发现一篇文章,这有助于 所有的荣誉都归于克雷蒂安·比克尔,因为他相当出色的代码项目 代码非常

我感兴趣的是,以DebugView的方式在系统范围内捕获Win32调试跟踪的可能性有多大。谢天谢地,我对内核消息不感兴趣,所以我不需要任何帮助。这需要使用C#,但如果必要,我很乐意使用非托管/不安全

有没有什么全球性的勾当我可以得到,或者我正在走一条艰难的道路


我真的不确定从哪里开始这个问题最好。

我将从类开始,尽管我不确定是否可以使用它来捕获Win32调试跟踪。

我终于做到了。这需要一些认真的谷歌搜索,但我发现一篇文章,这有助于

所有的荣誉都归于克雷蒂安·比克尔,因为他相当出色的代码项目

代码非常繁重,但这里是:

using System;
using System.Threading;
using System.Runtime.InteropServices;

public delegate void OnOutputDebugStringHandler(int pid, string text);


public sealed class DebugMonitor
{

    private DebugMonitor()
    {
        ;
    }

    #region Win32 API Imports

    [StructLayout(LayoutKind.Sequential)]
    private struct SECURITY_DESCRIPTOR
    {
        public byte revision;
        public byte size;
        public short control;
        public IntPtr owner;
        public IntPtr group;
        public IntPtr sacl;
        public IntPtr dacl;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct SECURITY_ATTRIBUTES
    {
        public int nLength;
        public IntPtr lpSecurityDescriptor;
        public int bInheritHandle;
    }

    [Flags]
    private enum PageProtection : uint
    {
        NoAccess = 0x01,
        Readonly = 0x02,
        ReadWrite = 0x04,
        WriteCopy = 0x08,
        Execute = 0x10,
        ExecuteRead = 0x20,
        ExecuteReadWrite = 0x40,
        ExecuteWriteCopy = 0x80,
        Guard = 0x100,
        NoCache = 0x200,
        WriteCombine = 0x400,
    }


    private const int WAIT_OBJECT_0 = 0;
    private const uint INFINITE = 0xFFFFFFFF;
    private const int ERROR_ALREADY_EXISTS = 183;

    private const uint SECURITY_DESCRIPTOR_REVISION = 1;

    private const uint SECTION_MAP_READ = 0x0004;

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject, uint
        dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow,
        uint dwNumberOfBytesToMap);

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool UnmapViewOfFile(IntPtr lpBaseAddress);

    [DllImport("advapi32.dll", SetLastError = true)]
    private static extern bool InitializeSecurityDescriptor(ref SECURITY_DESCRIPTOR sd, uint dwRevision);

    [DllImport("advapi32.dll", SetLastError = true)]
    private static extern bool SetSecurityDescriptorDacl(ref SECURITY_DESCRIPTOR sd, bool daclPresent, IntPtr dacl, bool daclDefaulted);

    [DllImport("kernel32.dll")]
    private static extern IntPtr CreateEvent(ref SECURITY_ATTRIBUTES sa, bool bManualReset, bool bInitialState, string lpName);

    [DllImport("kernel32.dll")]
    private static extern bool PulseEvent(IntPtr hEvent);

    [DllImport("kernel32.dll")]
    private static extern bool SetEvent(IntPtr hEvent);

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr CreateFileMapping(IntPtr hFile,
        ref SECURITY_ATTRIBUTES lpFileMappingAttributes, PageProtection flProtect, uint dwMaximumSizeHigh,
        uint dwMaximumSizeLow, string lpName);

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool CloseHandle(IntPtr hHandle);

    [DllImport("kernel32", SetLastError = true, ExactSpelling = true)]
    private static extern Int32 WaitForSingleObject(IntPtr handle, uint milliseconds);
    #endregion


    public static event OnOutputDebugStringHandler OnOutputDebugString;

    private static IntPtr m_AckEvent = IntPtr.Zero;

    private static IntPtr m_ReadyEvent = IntPtr.Zero;

    private static IntPtr m_SharedFile = IntPtr.Zero;

    private static IntPtr m_SharedMem = IntPtr.Zero;

    private static Thread m_Capturer = null;

    private static object m_SyncRoot = new object();

    private static Mutex m_Mutex = null;


    public static void Start()
    {
        lock (m_SyncRoot)
        {
            if (m_Capturer != null)
                throw new ApplicationException("This DebugMonitor is already started.");

            if (Environment.OSVersion.ToString().IndexOf("Microsoft") == -1)
                throw new NotSupportedException("This DebugMonitor is only supported on Microsoft operating systems.");

            bool createdNew = false;
            m_Mutex = new Mutex(false, typeof(DebugMonitor).Namespace, out createdNew);
            if (!createdNew)
                throw new ApplicationException("There is already an instance of 'DbMon.NET' running.");

            SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR();

            if (!InitializeSecurityDescriptor(ref sd, SECURITY_DESCRIPTOR_REVISION))
            {
                throw CreateApplicationException("Failed to initializes the security descriptor.");
            }

            if (!SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false))
            {
                throw CreateApplicationException("Failed to initializes the security descriptor");
            }

            SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();

            m_AckEvent = CreateEvent(ref sa, false, false, "DBWIN_BUFFER_READY");
            if (m_AckEvent == IntPtr.Zero)
            {
                throw CreateApplicationException("Failed to create event 'DBWIN_BUFFER_READY'");
            }

            m_ReadyEvent = CreateEvent(ref sa, false, false, "DBWIN_DATA_READY");
            if (m_ReadyEvent == IntPtr.Zero)
            {
                throw CreateApplicationException("Failed to create event 'DBWIN_DATA_READY'");
            }

            m_SharedFile = CreateFileMapping(new IntPtr(-1), ref sa, PageProtection.ReadWrite, 0, 4096, "DBWIN_BUFFER");
            if (m_SharedFile == IntPtr.Zero)
            {
                throw CreateApplicationException("Failed to create a file mapping to slot 'DBWIN_BUFFER'");
            }

            m_SharedMem = MapViewOfFile(m_SharedFile, SECTION_MAP_READ, 0, 0, 512);
            if (m_SharedMem == IntPtr.Zero)
            {
                throw CreateApplicationException("Failed to create a mapping view for slot 'DBWIN_BUFFER'");
            }

            m_Capturer = new Thread(new ThreadStart(Capture));
            m_Capturer.Start();
        }
    }

    private static void Capture()
    {
        try
        {
            IntPtr pString = new IntPtr(
                m_SharedMem.ToInt32() + Marshal.SizeOf(typeof(int))
            );

            while (true)
            {
                SetEvent(m_AckEvent);

                int ret = WaitForSingleObject(m_ReadyEvent, INFINITE);

                if (m_Capturer == null)
                    break;

                if (ret == WAIT_OBJECT_0)
                {
                    FireOnOutputDebugString(
                        Marshal.ReadInt32(m_SharedMem),
                            Marshal.PtrToStringAnsi(pString));
                }
            }
        }
        catch
        {
            throw;

        }
        finally
        {
            Dispose();
        }
    }

    private static void FireOnOutputDebugString(int pid, string text)
    {
        if (OnOutputDebugString == null)
            return;

        #if !DEBUG
            try
            {
        #endif

                OnOutputDebugString(pid, text);

        #if !DEBUG
            }
            catch (Exception ex)
            {
                Console.WriteLine("An 'OnOutputDebugString' handler failed to execute: " + ex.ToString());
            }
        #endif
    }


    private static void Dispose()
    {
        if (m_AckEvent != IntPtr.Zero)
        {
            if (!CloseHandle(m_AckEvent))
            {
                throw CreateApplicationException("Failed to close handle for 'AckEvent'");
            }
            m_AckEvent = IntPtr.Zero;
        }

        if (m_ReadyEvent != IntPtr.Zero)
        {
            if (!CloseHandle(m_ReadyEvent))
            {
                throw CreateApplicationException("Failed to close handle for 'ReadyEvent'");
            }
            m_ReadyEvent = IntPtr.Zero;
        }

        if (m_SharedFile != IntPtr.Zero)
        {
            if (!CloseHandle(m_SharedFile))
            {
                throw CreateApplicationException("Failed to close handle for 'SharedFile'");
            }
            m_SharedFile = IntPtr.Zero;
        }


        if (m_SharedMem != IntPtr.Zero)
        {
            if (!UnmapViewOfFile(m_SharedMem))
            {
                throw CreateApplicationException("Failed to unmap view for slot 'DBWIN_BUFFER'");
            }
            m_SharedMem = IntPtr.Zero;
        }

        if (m_Mutex != null)
        {
            m_Mutex.Close();
            m_Mutex = null;
        }
    }

    public static void Stop()
    {
        lock (m_SyncRoot)
        {
            if (m_Capturer == null)
                throw new ObjectDisposedException("DebugMonitor", "This DebugMonitor is not running.");
            m_Capturer = null;
            PulseEvent(m_ReadyEvent);
            while (m_AckEvent != IntPtr.Zero)
                ;
        }
    }

    private static ApplicationException CreateApplicationException(string text)
    {
        if (text == null || text.Length < 1)
            throw new ArgumentNullException("text", "'text' may not be empty or null.");

        return new ApplicationException(string.Format("{0}. Last Win32 Error was {1}",
            text, Marshal.GetLastWin32Error()));
    }
}
使用系统;
使用系统线程;
使用System.Runtime.InteropServices;
公共委托void OnOutputDebugStringHandler(int-pid,字符串文本);
公共密封类调试监视器
{
专用调试监视器()
{
;
}
#区域Win32 API导入
[StructLayout(LayoutKind.Sequential)]
私有结构安全描述符
{
公共字节修改;
公共字节大小;
公共短期控制;
公共IntPtr所有者;
公共IntPtr组;
公共IntPtr sacl;
公共IntPtr dacl;
}
[StructLayout(LayoutKind.Sequential)]
私有结构安全属性
{
公共国际长度;
公共IntPtr lpSecurityDescriptor;
宾利山公共区;
}
[旗帜]
私有枚举页面保护:uint
{
NoAccess=0x01,
只读=0x02,
读写=0x04,
WriteCopy=0x08,
Execute=0x10,
ExecuteRead=0x20,
ExecuteReadWrite=0x40,
ExecuteWriteCopy=0x80,
防护装置=0x100,
NoCache=0x200,
WriteCombine=0x400,
}
私有常量int WAIT_OBJECT_0=0;
私有常量无限=0xFFFFFFFF;
private const int ERROR_已存在=183;
私人建筑安全描述符修订版=1;
专用施工段地图读数=0x0004;
[DllImport(“kernel32.dll”,SetLastError=true)]
私有静态外部IntPtr MapViewOfFile(IntPtr hFileMappingObject,uint
dwDesiredAccess、uint dwFileOffsetHigh、uint dwFileOffsetLow、,
uint dwNumberOfBytesToMap);
[DllImport(“kernel32.dll”,SetLastError=true)]
私有静态外部bool unmpviewoffile(IntPtr lpBaseAddress);
[DllImport(“advapi32.dll”,SetLastError=true)]
私有静态外部布尔初始化安全描述符(参考安全描述符sd,uint dwRevision);
[DllImport(“advapi32.dll”,SetLastError=true)]
私有静态外部bool SetSecurityDescriptorDacl(ref SECURITY_描述符sd,bool daclPresent,IntPtr dacl,bool dacledefaulted);
[DllImport(“kernel32.dll”)]
私有静态外部IntPtr CreateEvent(参考安全属性sa、bool bManualReset、bool bInitialState、字符串lpName);
[DllImport(“kernel32.dll”)]
专用静态外部布尔脉冲事件(IntPtr hEvent);
[DllImport(“kernel32.dll”)]
私有静态外部布尔设置事件(IntPtr hEvent);
[DllImport(“kernel32.dll”,SetLastError=true)]
私有静态外部IntPtr CreateFileMapping(IntPtr hFile,
ref SECURITY_ATTRIBUTES lpFileMappingAttributes、PageProtection flProtect、uint dwMaximumSizeHigh、,
uint dwMaximumSizeLow,字符串lpName);
[DllImport(“kernel32.dll”,SetLastError=true)]
专用静态外部布尔闭合手柄(IntPtr hHandle);
[DllImport(“内核32”,SetLastError=true,ExactSpelling=true)]
私有静态外部Int32 WaitForSingleObject(IntPtr句柄,uint毫秒);
#端区
公共静态事件OnOutputDebugStringHandler OnOutputDebugString;
私有静态IntPtr m_AckEvent=IntPtr.Zero;
私有静态IntPtr m_ReadyEvent=IntPtr.Zero;
私有静态IntPtr m_SharedFile=IntPtr.Zero;
私有静态IntPtr m_SharedMem=IntPtr.Zero;
私有静态线程m_Capturer=null;
私有静态对象m_SyncRoot=新对象();
私有静态互斥m_Mutex=null;
公共静态void Start()
{
锁定(m_SyncRoot)
{
if(m_Capturer!=null)
抛出新的ApplicationException(“此DebugMonitor已启动。”);
if(Environment.OSVersion.ToString().IndexOf(“Microsoft”)=-1)
抛出新的NotSupportedException(“此DebugMonitor仅在Microsoft操作系统上受支持。”);
bool createdNew=false;
m_Mutex=新的互斥(false,typeof(DebugMonitor).Namespace,out createdNew);
如果(!createdNew)
抛出新的ApplicationException(“已经有一个“DbMon.NET”实例正在运行。”);
安全描述符sd=新的安全描述符();
if(!InitializeSecurityDescriptor(参考sd,安全描述符修订版))
{
抛出CreateApplicationException(“未能初始化安全描述符”);
}
if(!SetSecurityDescriptorDacl(参考sd、true、IntPtr.Zero、false))
{
抛出CreateApplicationException(“未能初始化安全描述符”);
}
安全属性sa=新的安全属性();
m_AckEvent=CreateEvent(参考sa,false,false,“DBWIN_BUFFER_READY”);
if(m_AckEvent==IntPtr.Zero)
{
抛出CreateApplicationException(“未能创建事件'DBWIN\u BUFFER\u READY'”;
}
m_ReadyEvent=CreateEvent(参考sa,false,false,“DBWIN_数据准备就绪”);
如果(m_ReadyEvent==IntPtr.Zero)
{
抛出CreateApplicationException(“未能创建事件‘DBWIN_DATA_READY’”);
}
m_SharedFile=CreateFileMapping(新的IntPtr(-1),r