using System; using System.Runtime.InteropServices; using Vanara.Extensions; using Vanara.InteropServices; namespace Vanara.PInvoke { public static partial class Kernel32 { /// A pointer to the starting address of the thread. /// /// A pointer to a variable to be passed as the lpParameter parameter to the function pointed to by the lpCallbackAddress parameter. /// /// Zero if successful. Otherwise, returns an error code. public delegate uint ThreadProc(IntPtr lpThreadParameter); /// A pointer to the starting address of the thread. /// /// A pointer to a variable to be passed as the lpParameter parameter to the function pointed to by the lpCallbackAddress parameter. /// /// Zero if successful. Otherwise, returns an error code. public unsafe delegate uint ThreadProcUnsafe(void* lpThreadParameter); /// The options to continue the thread that reported the debugging event. public enum DEBUG_CONTINUE : uint { /// /// If the thread specified by the dwThreadId parameter previously reported an EXCEPTION_DEBUG_EVENT debugging event, the /// function stops all exception processing and continues the thread and the exception is marked as handled. For any other /// debugging event, this flag simply continues the thread. /// DBG_CONTINUE = 0x00010002, /// /// If the thread specified by dwThreadId previously reported an EXCEPTION_DEBUG_EVENT debugging event, the function continues /// exception processing. If this is a first-chance exception event, the search and dispatch logic of the structured exception /// handler is used; otherwise, the process is terminated. For any other debugging event, this flag simply continues the thread. /// DBG_EXCEPTION_NOT_HANDLED = 0x80010001, /// /// Supported in Windows 10, version 1507 or above, this flag causes dwThreadId to replay the existing breaking event after the /// target continues. By calling the SuspendThread API against dwThreadId, a debugger can resume other threads in the process and /// later return to the breaking. /// DBG_REPLY_LATER = 0x40010001, } /// The code that identifies the type of debugging event. public enum DEBUG_EVENT_CODE : uint { /// /// Reports a create-process debugging event. The value of u.CreateProcessInfo specifies a CREATE_PROCESS_DEBUG_INFO structure. /// CREATE_PROCESS_DEBUG_EVENT = 3, /// Reports a create-thread debugging event. The value of u.CreateThread specifies a CREATE_THREAD_DEBUG_INFO structure. CREATE_THREAD_DEBUG_EVENT = 2, /// Reports an exception debugging event. The value of u.Exception specifies an EXCEPTION_DEBUG_INFO structure. EXCEPTION_DEBUG_EVENT = 1, /// Reports an exit-process debugging event. The value of u.ExitProcess specifies an EXIT_PROCESS_DEBUG_INFO structure. EXIT_PROCESS_DEBUG_EVENT = 5, /// Reports an exit-thread debugging event. The value of u.ExitThread specifies an EXIT_THREAD_DEBUG_INFO structure. EXIT_THREAD_DEBUG_EVENT = 4, /// /// Reports a load-dynamic-link-library (DLL) debugging event. The value of u.LoadDll specifies a LOAD_DLL_DEBUG_INFO structure. /// LOAD_DLL_DEBUG_EVENT = 6, /// /// Reports an output-debugging-string debugging event. The value of u.DebugString specifies an OUTPUT_DEBUG_STRING_INFO structure. /// OUTPUT_DEBUG_STRING_EVENT = 8, /// Reports a RIP-debugging event (system debugging error). The value of u.RipInfo specifies a RIP_INFO structure. RIP_EVENT = 9, /// Reports an unload-DLL debugging event. The value of u.UnloadDll specifies an UNLOAD_DLL_DEBUG_INFO structure. UNLOAD_DLL_DEBUG_EVENT = 7, } /// Determines whether the specified process is being debugged. /// A handle to the process. /// /// A pointer to a variable that the function sets to TRUE if the specified process is being debugged, or FALSE otherwise. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI CheckRemoteDebuggerPresent( _In_ HANDLE hProcess, _Inout_ PBOOL pbDebuggerPresent); https://msdn.microsoft.com/en-us/library/windows/desktop/ms679280(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms679280")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CheckRemoteDebuggerPresent([In] HPROCESS hProcess, [MarshalAs(UnmanagedType.Bool)] out bool pbDebuggerPresent); /// Enables a debugger to continue a thread that previously reported a debugging event. /// The process identifier of the process to continue. /// /// The thread identifier of the thread to continue. The combination of process identifier and thread identifier must identify a /// thread that has previously reported a debugging event. /// /// /// The options to continue the thread that reported the debugging event. /// /// /// /// Value /// Meaning /// /// /// DBG_CONTINUE0x00010002L /// /// If the thread specified by the dwThreadId parameter previously reported an EXCEPTION_DEBUG_EVENT debugging event, the function /// stops all exception processing and continues the thread and the exception is marked as handled. For any other debugging event, /// this flag simply continues the thread. /// /// /// /// DBG_EXCEPTION_NOT_HANDLED0x80010001L /// /// If the thread specified by dwThreadId previously reported an EXCEPTION_DEBUG_EVENT debugging event, the function continues /// exception processing. If this is a first-chance exception event, the search and dispatch logic of the structured exception /// handler is used; otherwise, the process is terminated. For any other debugging event, this flag simply continues the thread. /// /// /// /// DBG_REPLY_LATER0x40010001L /// /// Supported in Windows 10, version 1507 or above, this flag causes dwThreadId to replay the existing breaking event after the /// target continues. By calling the SuspendThread API against dwThreadId, a debugger can resume other threads in the process and /// later return to the breaking. /// /// /// /// /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI ContinueDebugEvent( _In_ DWORD dwProcessId, _In_ DWORD dwThreadId, _In_ DWORD dwContinueStatus); https://msdn.microsoft.com/en-us/library/windows/desktop/ms679285(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms679285")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool ContinueDebugEvent(uint dwProcessId, uint dwThreadId, DEBUG_CONTINUE dwContinueStatus); /// Enables a debugger to attach to an active process and debug it. /// /// The identifier for the process to be debugged. The debugger is granted debugging access to the process as if it created the /// process with the DEBUG_ONLY_THIS_PROCESS flag. For more information, see the Remarks section of this topic. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is 0 (zero). To get extended error information, call GetLastError. /// // BOOL WINAPI DebugActiveProcess( _In_ DWORD dwProcessId); https://msdn.microsoft.com/en-us/library/windows/desktop/ms679295(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms679295")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool DebugActiveProcess(uint dwProcessId); /// Stops the debugger from debugging the specified process. /// The identifier of the process to stop debugging. /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI DebugActiveProcessStop( _In_ DWORD dwProcessId); https://msdn.microsoft.com/en-us/library/windows/desktop/ms679296(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms679296")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool DebugActiveProcessStop(uint dwProcessId); /// /// /// Causes a breakpoint exception to occur in the current process. This allows the calling thread to signal the debugger to handle /// the exception. /// /// To cause a breakpoint exception in another process, use the DebugBreakProcess function. /// /// This function does not return a value. // void WINAPI DebugBreak(void); https://msdn.microsoft.com/en-us/library/windows/desktop/ms679297(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms679297")] public static extern void DebugBreak(); /// Determines whether the calling process is being debugged by a user-mode debugger. /// /// If the current process is running in the context of a debugger, the return value is nonzero. /// If the current process is not running in the context of a debugger, the return value is zero. /// // BOOL WINAPI IsDebuggerPresent(void); https://msdn.microsoft.com/en-us/library/windows/desktop/ms680345(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms680345")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool IsDebuggerPresent(); /// Sends a string to the debugger for display. /// The null-terminated string to be displayed. /// This function does not return a value. // void WINAPI OutputDebugString( _In_opt_ LPCTSTR lpOutputString); https://msdn.microsoft.com/en-us/library/windows/desktop/aa363362(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("WinBase.h", MSDNShortId = "aa363362")] public static extern void OutputDebugString(string lpOutputString); /// Waits for a debugging event to occur in a process being debugged. /// A pointer to a DEBUG_EVENT structure that receives information about the debugging event. /// /// The number of milliseconds to wait for a debugging event. If this parameter is zero, the function tests for a debugging event and /// returns immediately. If the parameter is INFINITE, the function does not return until a debugging event has occurred. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI WaitForDebugEvent( _Out_ LPDEBUG_EVENT lpDebugEvent, _In_ DWORD dwMilliseconds); https://msdn.microsoft.com/en-us/library/windows/desktop/ms681423(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms681423")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool WaitForDebugEvent(out DEBUG_EVENT lpDebugEvent, uint dwMilliseconds); /// /// /// [Some information relates to pre-released product which may be substantially modified before it's commercially released. /// Microsoft makes no warranties, express or implied, with respect to the information provided here.] /// /// Waits for a debugging event to occur in a process being debugged. /// /// A pointer to a DEBUG_EVENT structure that receives information about the debugging event. /// /// The number of milliseconds to wait for a debugging event. If this parameter is zero, the function tests for a debugging event and /// returns immediately. If the parameter is INFINITE, the function does not return until a debugging event has occurred. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // BOOL WINAPI WaitForDebugEventEx( _Out_ LPDEBUG_EVENT lpDebugEvent, _In_ DWORD dwMilliseconds); https://msdn.microsoft.com/en-us/library/windows/desktop/mt171594(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "mt171594")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool WaitForDebugEventEx(out DEBUG_EVENT lpDebugEvent, uint dwMilliseconds); /// Describes a debugging event. // typedef struct _DEBUG_EVENT { DWORD dwDebugEventCode; DWORD dwProcessId; DWORD dwThreadId; union { EXCEPTION_DEBUG_INFO Exception; // CREATE_THREAD_DEBUG_INFO CreateThread; CREATE_PROCESS_DEBUG_INFO CreateProcessInfo; EXIT_THREAD_DEBUG_INFO ExitThread; // EXIT_PROCESS_DEBUG_INFO ExitProcess; LOAD_DLL_DEBUG_INFO LoadDll; UNLOAD_DLL_DEBUG_INFO UnloadDll; OUTPUT_DEBUG_STRING_INFO // DebugString; RIP_INFO RipInfo; } u;} DEBUG_EVENT, // *LPDEBUG_EVENT;// https://msdn.microsoft.com/en-us/library/windows/desktop/ms679308(v=vs.85).aspx [PInvokeData("WinBase.h", MSDNShortId = "ms679308")] [StructLayout(LayoutKind.Sequential)] public struct DEBUG_EVENT { /// /// Type: DWORD /// The code that identifies the type of debugging event. This member can be one of the following values. /// /// /// /// Value /// Meaning /// /// /// CREATE_PROCESS_DEBUG_EVENT3 /// Reports a create-process debugging event. The value of u.CreateProcessInfo specifies a CREATE_PROCESS_DEBUG_INFO structure. /// /// /// CREATE_THREAD_DEBUG_EVENT2 /// Reports a create-thread debugging event. The value of u.CreateThread specifies a CREATE_THREAD_DEBUG_INFO structure. /// /// /// EXCEPTION_DEBUG_EVENT1 /// Reports an exception debugging event. The value of u.Exception specifies an EXCEPTION_DEBUG_INFO structure. /// /// /// EXIT_PROCESS_DEBUG_EVENT5 /// Reports an exit-process debugging event. The value of u.ExitProcess specifies an EXIT_PROCESS_DEBUG_INFO structure. /// /// /// EXIT_THREAD_DEBUG_EVENT4 /// Reports an exit-thread debugging event. The value of u.ExitThread specifies an EXIT_THREAD_DEBUG_INFO structure. /// /// /// LOAD_DLL_DEBUG_EVENT6 /// /// Reports a load-dynamic-link-library (DLL) debugging event. The value of u.LoadDll specifies a LOAD_DLL_DEBUG_INFO structure. /// /// /// /// OUTPUT_DEBUG_STRING_EVENT8 /// /// Reports an output-debugging-string debugging event. The value of u.DebugString specifies an OUTPUT_DEBUG_STRING_INFO structure. /// /// /// /// RIP_EVENT9 /// Reports a RIP-debugging event (system debugging error). The value of u.RipInfo specifies a RIP_INFO structure. /// /// /// UNLOAD_DLL_DEBUG_EVENT7 /// Reports an unload-DLL debugging event. The value of u.UnloadDll specifies an UNLOAD_DLL_DEBUG_INFO structure. /// /// /// /// public DEBUG_EVENT_CODE dwDebugEventCode; /// /// Type: DWORD /// /// The identifier of the process in which the debugging event occurred. A debugger uses this value to locate the debugger's /// per-process structure. These values are not necessarily small integers that can be used as table indices. /// /// public uint dwProcessId; // This is used to ensure the union structure EXCEPTION_INFO falls at offset 12 in 32-bit and 16 on 64-bit private IntPtr padding3264hack; /// /// Type: DWORD /// /// The identifier of the thread in which the debugging event occurred. A debugger uses this value to locate the debugger's /// per-thread structure. These values are not necessarily small integers that can be used as table indices. /// /// public uint dwThreadId { get => (uint)padding3264hack.ToInt32(); set => padding3264hack = (IntPtr)dwThreadId; } /// /// Any additional information relating to the debugging event. This union takes on the type and value appropriate to the type of /// debugging event, as described in the dwDebugEventCode member. /// public EXCEPTION_INFO u; /// /// This union takes on the type and value appropriate to the type of debugging event, as described in the /// dwDebugEventCode member. /// [PInvokeData("WinBase.h", MSDNShortId = "ms679308")] [StructLayout(LayoutKind.Explicit)] public struct EXCEPTION_INFO { /// If the dwDebugEventCode is EXCEPTION_DEBUG_EVENT (1), u.Exception specifies an EXCEPTION_DEBUG_INFO structure. [FieldOffset(0)] public EXCEPTION_DEBUG_INFO Exception; /// /// If the dwDebugEventCode is CREATE_THREAD_DEBUG_EVENT (2), u.CreateThread specifies an CREATE_THREAD_DEBUG_INFO structure. /// [FieldOffset(0)] public CREATE_THREAD_DEBUG_INFO CreateThread; /// /// If the dwDebugEventCode is CREATE_PROCESS_DEBUG_EVENT (3), u.CreateProcessInfo specifies an CREATE_PROCESS_DEBUG_INFO structure. /// [FieldOffset(0)] public CREATE_PROCESS_DEBUG_INFO CreateProcessInfo; /// /// If the dwDebugEventCode is EXIT_THREAD_DEBUG_EVENT (4), u.ExitThread specifies an EXIT_THREAD_DEBUG_INFO structure. /// [FieldOffset(0)] public EXIT_THREAD_DEBUG_INFO ExitThread; /// /// If the dwDebugEventCode is EXIT_PROCESS_DEBUG_EVENT (5), u.ExitProcess specifies an EXIT_PROCESS_DEBUG_INFO structure. /// [FieldOffset(0)] public EXIT_PROCESS_DEBUG_INFO ExitProcess; /// If the dwDebugEventCode is LOAD_DLL_DEBUG_EVENT (6), u.LoadDll specifies an LOAD_DLL_DEBUG_INFO structure. [FieldOffset(0)] public LOAD_DLL_DEBUG_INFO LoadDll; /// If the dwDebugEventCode is UNLOAD_DLL_DEBUG_EVENT (7), u.UnloadDll specifies an UNLOAD_DLL_DEBUG_INFO structure. [FieldOffset(0)] public UNLOAD_DLL_DEBUG_INFO UnloadDll; /// /// If the dwDebugEventCode is OUTPUT_DEBUG_STRING_EVENT (8), u.DebugString specifies an OUTPUT_DEBUG_STRING_INFO structure. /// [FieldOffset(0)] public OUTPUT_DEBUG_STRING_INFO DebugString; /// If the dwDebugEventCode is RIP_EVENT (9), u.RipInfo specifies an RIP_INFO structure. [FieldOffset(0)] public RIP_INFO RipInfo; } /// Contains exception information that can be used by a debugger. // typedef struct _EXCEPTION_DEBUG_INFO { EXCEPTION_RECORD ExceptionRecord; DWORD dwFirstChance;} EXCEPTION_DEBUG_INFO, // *LPEXCEPTION_DEBUG_INFO; https://msdn.microsoft.com/en-us/library/windows/desktop/ms679326(v=vs.85).aspx [PInvokeData("WinBase.h", MSDNShortId = "ms679326")] [StructLayout(LayoutKind.Sequential)] public struct EXCEPTION_DEBUG_INFO { /// /// An EXCEPTION_RECORD structure with information specific to the exception. This includes the exception code, /// flags, address, a pointer to a related exception, extra parameters, and so on. /// public EXCEPTION_RECORD ExceptionRecord; /// /// A value that indicates whether the debugger has previously encountered the exception specified by the /// ExceptionRecord member. If the dwFirstChance member is nonzero, this is the first time the debugger has /// encountered the exception. Debuggers typically handle breakpoint and single-step exceptions when they are first /// encountered. If this member is zero, the debugger has previously encountered the exception. This occurs only if, /// during the search for structured exception handlers, either no handler was found or the exception was continued. /// public uint dwFirstChance; } /// Contains thread-creation information that can be used by a debugger. // typedef struct _CREATE_THREAD_DEBUG_INFO { HANDLE hThread; LPVOID lpThreadLocalBase; LPTHREAD_START_ROUTINE // lpStartAddress;} CREATE_THREAD_DEBUG_INFO, // *LPCREATE_THREAD_DEBUG_INFO; https://msdn.microsoft.com/en-us/library/windows/desktop/ms679287(v=vs.85).aspx [PInvokeData("WinBase.h", MSDNShortId = "ms679287")] [StructLayout(LayoutKind.Sequential)] public struct CREATE_THREAD_DEBUG_INFO { /// /// A handle to the thread whose creation caused the debugging event. If this member is NULL, the handle is not /// valid. Otherwise, the debugger has THREAD_GET_CONTEXT, THREAD_SET_CONTEXT, and THREAD_SUSPEND_RESUME access to the /// thread, allowing the debugger to read from and write to the registers of the thread and control execution of the thread. /// public HTHREAD hThread; /// /// A pointer to a block of data. At offset 0x2C into this block is another pointer, called ThreadLocalStoragePointer, /// that points to an array of per-module thread local storage blocks. This gives a debugger access to per-thread data in /// the threads of the process being debugged using the same algorithms that a compiler would use. /// public IntPtr lpThreadLocalBase; /// /// A pointer to the starting address of the thread. This value may only be an approximation of the thread's starting /// address, because any application with appropriate access to the thread can change the thread's context by using the /// SetThreadContext function. /// //[MarshalAs(UnmanagedType.FunctionPtr)] //public PTHREAD_START_ROUTINE lpStartAddress; public IntPtr lpStartAddress; } /// Contains process creation information that can be used by a debugger. // typedef struct _CREATE_PROCESS_DEBUG_INFO { HANDLE hFile; HANDLE hProcess; HANDLE hThread; LPVOID lpBaseOfImage; DWORD // dwDebugInfoFileOffset; DWORD nDebugInfoSize; LPVOID lpThreadLocalBase; LPTHREAD_START_ROUTINE lpStartAddress; LPVOID // lpImageName; WORD fUnicode;} CREATE_PROCESS_DEBUG_INFO, *LPCREATE_PROCESS_DEBUG_INFO; [PInvokeData("WinBase.h", MSDNShortId = "ms679286")] [StructLayout(LayoutKind.Sequential)] public struct CREATE_PROCESS_DEBUG_INFO { /// /// /// A handle to the process's image file. If this member is NULL, the handle is not valid. Otherwise, the debugger /// can use the member to read from and write to the image file. /// /// When the debugger is finished with this file, it should close the handle using the CloseHandle function. /// public HFILE hFile; /// /// A handle to the process. If this member is NULL, the handle is not valid. Otherwise, the debugger can use the /// member to read from and write to the process's memory. /// public HPROCESS hProcess; /// /// A handle to the initial thread of the process identified by the hProcess member. If hThread param is /// NULL, the handle is not valid. Otherwise, the debugger has THREAD_GET_CONTEXT, /// THREAD_SET_CONTEXT, and THREAD_SUSPEND_RESUME access to the thread, allowing the debugger to read from /// and write to the registers of the thread and to control execution of the thread. /// public HTHREAD hThread; /// The base address of the executable image that the process is running. public IntPtr lpBaseOfImage; /// The offset to the debugging information in the file identified by the hFile member. public uint dwDebugInfoFileOffset; /// /// The size of the debugging information in the file, in bytes. If this value is zero, there is no debugging information. /// public uint nDebugInfoSize; /// /// A pointer to a block of data. At offset 0x2C into this block is another pointer, called , that points to an array of /// per-module thread local storage blocks. This gives a debugger access to per-thread data in the threads of the process /// being debugged using the same algorithms that a compiler would use. /// public IntPtr lpThreadLocalBase; /// /// A pointer to the starting address of the thread. This value may only be an approximation of the thread's starting /// address, because any application with appropriate access to the thread can change the thread's context by using the /// SetThreadContext function. /// //[MarshalAs(UnmanagedType.FunctionPtr)] //public PTHREAD_START_ROUTINE lpStartAddress; public IntPtr lpStartAddress; /// /// /// A pointer to the file name associated with the hFile member. This parameter may be NULL, or it may /// contain the address of a string pointer in the address space of the process being debugged. That address may, in /// turn, either be NULL or point to the actual filename. If fUnicode is a nonzero value, the name string /// is Unicode; otherwise, it is ANSI. /// /// /// This member is strictly optional. Debuggers must be prepared to handle the case where lpImageName is /// NULL or * lpImageName (in the address space of the process being debugged) is NULL. /// Specifically, the system does not provide an image name for a create process event, and will not likely pass an image /// name for the first DLL event. The system also does not provide this information in the case of debug events that /// originate from a call to the DebugActiveProcess function. /// /// public IntPtr lpImageName; /// /// A value that indicates whether a file name specified by the lpImageName member is Unicode or ANSI. A nonzero /// value indicates Unicode; zero indicates ANSI. /// public ushort fUnicode; } /// Contains the exit code for a terminating process. // typedef struct _EXIT_PROCESS_DEBUG_INFO { DWORD dwExitCode;} EXIT_PROCESS_DEBUG_INFO, *LPEXIT_PROCESS_DEBUG_INFO; https://msdn.microsoft.com/en-us/library/windows/desktop/ms679334(v=vs.85).aspx [PInvokeData("WinBase.h", MSDNShortId = "ms679334")] [StructLayout(LayoutKind.Sequential)] public struct EXIT_PROCESS_DEBUG_INFO { /// The exit code for the process. public uint dwExitCode; } /// Contains the exit code for a terminating thread. // typedef struct _EXIT_THREAD_DEBUG_INFO { DWORD dwExitCode;} EXIT_THREAD_DEBUG_INFO, *LPEXIT_THREAD_DEBUG_INFO; https://msdn.microsoft.com/en-us/library/windows/desktop/ms679335(v=vs.85).aspx [PInvokeData("WinBase.h", MSDNShortId = "ms679335")] [StructLayout(LayoutKind.Sequential)] public struct EXIT_THREAD_DEBUG_INFO { /// The exit code for the thread. public uint dwExitCode; } /// Contains information about a dynamic-link library (DLL) that has just been loaded. // typedef struct _LOAD_DLL_DEBUG_INFO { HANDLE hFile; LPVOID lpBaseOfDll; DWORD dwDebugInfoFileOffset; DWORD nDebugInfoSize; // LPVOID lpImageName; WORD fUnicode;} LOAD_DLL_DEBUG_INFO, *LPLOAD_DLL_DEBUG_INFO; https://msdn.microsoft.com/en-us/library/windows/desktop/ms680351(v=vs.85).aspx [PInvokeData("WinBase.h", MSDNShortId = "ms680351")] [StructLayout(LayoutKind.Sequential)] public struct LOAD_DLL_DEBUG_INFO { /// /// /// A handle to the loaded DLL. If this member is NULL, the handle is not valid. Otherwise, the member is opened /// for reading and read-sharing in the context of the debugger. /// /// When the debugger is finished with this file, it should close the handle using the CloseHandle function. /// public HFILE hFile; /// A pointer to the base address of the DLL in the address space of the process loading the DLL. public IntPtr lpBaseOfDll; /// /// The offset to the debugging information in the file identified by the hFile member, in bytes. The system /// expects the debugging information to be in CodeView 4.0 format. This format is currently a derivative of Common /// Object File Format (COFF). /// public uint dwDebugInfoFileOffset; /// /// The size of the debugging information in the file, in bytes. If this member is zero, there is no debugging information. /// public uint nDebugInfoSize; /// /// /// A pointer to the file name associated with hFile. This member may be NULL, or it may contain the /// address of a string pointer in the address space of the process being debugged. That address may, in turn, either be /// NULL or point to the actual filename. If fUnicode is a nonzero value, the name string is Unicode; /// otherwise, it is ANSI. /// /// /// This member is strictly optional. Debuggers must be prepared to handle the case where lpImageName is /// NULL or * lpImageName (in the address space of the process being debugged) is NULL. /// Specifically, the system will never provide an image name for a create process event, and it will not likely pass an /// image name for the first DLL event. The system will also never provide this information in the case of debugging /// events that originate from a call to the DebugActiveProcess function. /// /// public IntPtr lpImageName; /// /// A value that indicates whether a filename specified by lpImageName is Unicode or ANSI. A nonzero value for /// this member indicates Unicode; zero indicates ANSI. /// public ushort fUnicode; } /// Contains information about a dynamic-link library (DLL) that has just been unloaded. // typedef struct _UNLOAD_DLL_DEBUG_INFO { LPVOID lpBaseOfDll;} UNLOAD_DLL_DEBUG_INFO, *LPUNLOAD_DLL_DEBUG_INFO; https://msdn.microsoft.com/en-us/library/windows/desktop/ms681403(v=vs.85).aspx [PInvokeData("WinBase.h", MSDNShortId = "ms681403")] [StructLayout(LayoutKind.Sequential)] public struct UNLOAD_DLL_DEBUG_INFO { /// A pointer to the base address of the DLL in the address space of the process unloading the DLL. public IntPtr lpBaseOfDll; } /// Contains the address, format, and length, in bytes, of a debugging string. // typedef struct _OUTPUT_DEBUG_STRING_INFO { LPSTR lpDebugStringData; WORD fUnicode; WORD nDebugStringLength;} OUTPUT_DEBUG_STRING_INFO, // *LPOUTPUT_DEBUG_STRING_INFO;// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680545(v=vs.85).aspx [PInvokeData("WinBase.h", MSDNShortId = "ms680545")] [StructLayout(LayoutKind.Sequential)] public struct OUTPUT_DEBUG_STRING_INFO { /// /// The debugging string in the calling process's address space. The debugger can use the ReadProcessMemory /// function to retrieve the value of the string. /// public IntPtr lpDebugStringData; /// /// The format of the debugging string. If this member is zero, the debugging string is ANSI; if it is nonzero, the /// string is Unicode. /// public ushort fUnicode; /// The size of the debugging string, in characters. The length includes the string's terminating null character. public ushort nDebugStringLength; /// Gets the debugging string in the calling process's address space. public string DebugString => ReadString(lpDebugStringData, fUnicode, nDebugStringLength); } /// Contains the error that caused the RIP debug event. // typedef struct _RIP_INFO { DWORD dwError; DWORD dwType;} RIP_INFO, *LPRIP_INFO; https://msdn.microsoft.com/en-us/library/windows/desktop/ms680587(v=vs.85).aspx [PInvokeData("WinBase.h", MSDNShortId = "ms680587")] [StructLayout(LayoutKind.Sequential)] public struct RIP_INFO { /// The error that caused the RIP debug event. For more information, see Error Handling. public uint dwError; /// /// /// Any additional information about the type of error that caused the RIP debug event. This member can be one of the /// following values. /// /// /// /// /// Value /// Meaning /// /// /// SLE_ERROR = 0x00000001 /// Indicates that invalid data was passed to the function that failed. This caused the application to fail. /// /// /// SLE_MINORERROR = 0x00000002 /// /// Indicates that invalid data was passed to the function, but the error probably will not cause the application to fail. /// /// /// /// SLE_WARNING = 0x00000003 /// Indicates that potentially invalid data was passed to the function, but the function completed processing. /// /// /// 0 /// Indicates that only dwError was set. /// /// /// /// public uint dwType; } } private static string ReadString(IntPtr data, ushort fUni, ushort len) { return StringHelper.GetString(data, fUni != 0 ? CharSet.Unicode : CharSet.Ansi, len); } } }