private void ExceptionDebugEvent(Win32Thread thread, ref WinApi.EXCEPTION_DEBUG_INFO info) { Console.WriteLine($"IP = {WinApi.GetInstructionPointer(WMainThread)}"); if (info.dwFirstChance == 0) { // It's not the first time we encountered this exception, it's an error // TODO: Error Console.WriteLine("already encountered exception"); return; } // First time encounter if (info.ExceptionRecord.ExceptionCode == WinApi.EXCEPTION_BREAKPOINT) { // A breakpoint was hit Console.WriteLine("Breakpoint"); SuspendThread(thread); } else if (info.ExceptionRecord.ExceptionCode == WinApi.EXCEPTION_SINGLE_STEP) { // Trap flag was set Console.WriteLine("Single step"); SuspendThread(thread); } else { // Some other exception like avvess violation or division by zero Console.WriteLine($"Exception: {info.ExceptionRecord.ExceptionCode}"); // TODO: What to do here? } }
private void OutputStringDebugEvent(Win32Thread thread, ref WinApi.OUTPUT_DEBUG_STRING_INFO info) { Console.WriteLine($"IP = {WinApi.GetInstructionPointer(WMainThread)}"); var message = info.GetMessage(Handle); Console.WriteLine($"output string: {message}"); // Trivially continuable, handled WinApi.ContinueDebugThread(thread, true); }
internal static Win32Thread MakeThreadObject(IntPtr threadHandle) { var threadId = GetThreadId(threadHandle); ErrorOnFalse((Int32)threadId); var thread = new Win32Thread(threadHandle, threadId); return(thread); }
internal static void ContinueDebugThread(Win32Thread thread, bool handled) { unsafe { Int32 success = ContinueDebugEvent( ((Win32Process)thread.Process).Id, thread.Id, handled ? DBG_CONTINUE : DBG_EXCEPTION_NOT_HANDLED); ErrorOnFalse(success); } }
internal static nuint GetInstructionPointer(Win32Thread thread) { var arch = RuntimeInformation.ProcessArchitecture; unsafe { if (arch == Architecture.X86) { var context = new CONTEXT_X86(); context.ContextFlags = CONTEXT_CONTROL; var success = GetThreadContext_X86(thread.Handle, &context); ErrorOnFalse(success); return(context.Eip); } else { throw new NotImplementedException($"Architecture {arch} does not support thread context querying"); } } }
public void AddThread(Win32Thread thread) { Debug.Assert(thread.Win32Process == null); WThreads.Add(thread); thread.Win32Process = this; }
private void RipDebugEvent(Win32Thread thread, ref WinApi.RIP_INFO info) { Console.WriteLine("RIP"); // TODO: What to do here? }
private void SuspendThread(Win32Thread thread) { Debug.Assert(suspendedThread == null); State = Win32ProcessState.Suspended; suspendedThread = thread; }
private void UnloadDllDebugEvent(Win32Thread thread, ref WinApi.UNLOAD_DLL_DEBUG_INFO info) { Console.WriteLine("unload dll"); // Trivially continuable, handled WinApi.ContinueDebugThread(thread, true); }
private void ExitThreadDebugEvent(Win32Thread thread, ref WinApi.EXIT_THREAD_DEBUG_INFO info) { Console.WriteLine($"exit thread (code {info.dwExitCode})"); // Trivially continuable, handled WinApi.ContinueDebugThread(thread, true); }
internal static void SetTrapFlag(Win32Thread thread, bool on) => ModifyThreadContext(thread.Handle, null, on);
internal static void OffsetInstructionPointer(Win32Thread thread, int offset) => ModifyThreadContext(thread.Handle, offset, null);