public static extern bool GetThreadContext(IntPtr hThread, ref CONTEXT64 lpContext);
private static void Main(string[] args) { if (args.Length != 1) { Console.WriteLine($"Usage: {AppDomain.CurrentDomain.FriendlyName} pid|name"); return; } Console.WriteLine($"Waiting for process by name or pid {args.First()} ..."); Process process; do { process = Process.GetProcesses().FirstOrDefault(proc => Matches(proc, args.First())); Thread.Sleep(50); } while (process == null); Console.CursorVisible = false; var lastReport = string.Empty; var thisReport = new StringBuilder(); while (!process.HasExited) { thisReport.AppendLine($"Watching process {process.ProcessName} ({process.Id} | {process.Id:X})"); foreach (ProcessThread thread in process.Threads) { thisReport.AppendLine($"Thread {thread.Id:X}"); var threadHandle = NativeFunctions.OpenThread(ThreadAccess.GET_CONTEXT, false, (uint)thread.Id); if (threadHandle == IntPtr.Zero) { thisReport.AppendLine("- Access denied"); continue; } try { var context = new CONTEXT64 { ContextFlags = (CONTEXT_FLAGS)0x10 }; if (!NativeFunctions.GetThreadContext(threadHandle, ref context)) { thisReport.AppendLine("- Context protected"); continue; } thisReport.AppendLine($"- Dr0: {context.Dr0,16:X} {ParseDr7(context.Dr7, 0)}"); thisReport.AppendLine($"- Dr1: {context.Dr1,16:X} {ParseDr7(context.Dr7, 1)}"); thisReport.AppendLine($"- Dr2: {context.Dr2,16:X} {ParseDr7(context.Dr7, 2)}"); thisReport.AppendLine($"- Dr3: {context.Dr3,16:X} {ParseDr7(context.Dr7, 3)}"); thisReport.AppendLine($"- Dr6: {context.Dr6,16:X}"); thisReport.AppendLine($"- Dr7: {context.Dr7,16:X}"); } finally { NativeFunctions.CloseHandle(threadHandle); } } var reportString = thisReport.ToString(); thisReport.Clear(); if (reportString != lastReport) { Console.Clear(); Console.Write(reportString); lastReport = reportString; } Thread.Sleep(0); } }