public static void Get(SafeObjectHandle threadHandle, ref Win32ThreadContext context) { var raw = Marshal.AllocHGlobal(Marshal.SizeOf <Win32ThreadContext>() + 8); try { var aligned = new IntPtr(16 * (((long)raw + 15) / 16)); Marshal.StructureToPtr(context, aligned, fDeleteOld: true); if (!GetThreadContext(threadHandle, aligned)) { throw new Win32Exception(); } context = Marshal.PtrToStructure <Win32ThreadContext>(aligned); } finally { Marshal.FreeHGlobal(raw); } }
static int th(IntPtr lpParameter) { if (lpParameter == IntPtr.Zero) { throw new ArgumentNullException(nameof(lpParameter)); } var breakpoint = (Win32HardwareBreakpoint)GCHandle.FromIntPtr(lpParameter).Target; int threadOpResult = SuspendThread(breakpoint.ThreadHandle); GetLastError().ThrowOnError(); var ct = new Win32ThreadContext { ContextFlags = ContextFlags.DebugRegisters, }; Win32ThreadContext.Get(breakpoint.ThreadHandle, ref ct); GetLastError().ThrowOnError(); int FlagBit = 0; bool Dr0Busy = false; bool Dr1Busy = false; bool Dr2Busy = false; bool Dr3Busy = false; if (((ulong)ct.Dr7 & 1) != 0) { Dr0Busy = true; } if (((ulong)ct.Dr7 & 4) != 0) { Dr1Busy = true; } if (((ulong)ct.Dr7 & 16) != 0) { Dr2Busy = true; } if (((ulong)ct.Dr7 & 64) != 0) { Dr3Busy = true; } if (breakpoint.Op == Operation.Remove) { // Remove if (breakpoint.iReg == 0) { FlagBit = 0; ct.Dr0 = IntPtr.Zero; Dr0Busy = false; } if (breakpoint.iReg == 1) { FlagBit = 2; ct.Dr1 = IntPtr.Zero;; Dr1Busy = false; } if (breakpoint.iReg == 2) { FlagBit = 4; ct.Dr2 = IntPtr.Zero;; Dr2Busy = false; } if (breakpoint.iReg == 3) { FlagBit = 6; ct.Dr3 = IntPtr.Zero;; Dr3Busy = false; } if (IntPtr.Size == 8) { ulong v = (ulong)ct.Dr7; v &= ~(1ul << FlagBit); ct.Dr7 = (IntPtr)v; } } else { if (!Dr0Busy) { breakpoint.iReg = 0; ct.Dr0 = breakpoint.Address; Dr0Busy = true; } else if (!Dr1Busy) { breakpoint.iReg = 1; ct.Dr1 = breakpoint.Address; Dr1Busy = true; } else if (!Dr2Busy) { breakpoint.iReg = 2; ct.Dr2 = breakpoint.Address; Dr2Busy = true; } else if (!Dr3Busy) { breakpoint.iReg = 3; ct.Dr3 = breakpoint.Address; Dr3Busy = true; } else { breakpoint.SUCC = false; threadOpResult = ResumeThread(breakpoint.ThreadHandle); GetLastError().ThrowOnError(); Win32Event.SetEvent(breakpoint.CompletionEvent); return(0); } ct.Dr6 = IntPtr.Zero; int st = 0; if (breakpoint.Type == HardwareBreakpointType.Code) { st = 0; } if (breakpoint.Type == HardwareBreakpointType.ReadWrite) { st = 3; } if (breakpoint.Type == HardwareBreakpointType.Write) { st = 1; } int le = 0; if (breakpoint.Size == HardwareBreakpointSize.Size1) { le = 0; } if (breakpoint.Size == HardwareBreakpointSize.Size2) { le = 1; } if (breakpoint.Size == HardwareBreakpointSize.Size4) { le = 3; } if (breakpoint.Size == HardwareBreakpointSize.Size8) { le = 2; } SetBits(ref ct.Dr7, 16 + breakpoint.iReg * 4, 2, st); SetBits(ref ct.Dr7, 18 + breakpoint.iReg * 4, 2, le); SetBits(ref ct.Dr7, breakpoint.iReg * 2, 1, 1); } ct.ContextFlags = ContextFlags.DebugRegisters; ct.Set(breakpoint.ThreadHandle); ct = new Win32ThreadContext { ContextFlags = ContextFlags.DebugRegisters }; Win32ThreadContext.Get(breakpoint.ThreadHandle, ref ct); threadOpResult = ResumeThread(breakpoint.ThreadHandle); GetLastError().ThrowOnError(); breakpoint.SUCC = true; Win32Event.SetEvent(breakpoint.CompletionEvent); return(0); }