private bool CheckAMD64Contexts(AMD64Context a1, AMD64Context a2) { //CONTEXT_CONTROL contains: SegCs, SegSs, EFlags, Rsp, Rip if ((a1.Flags & ContextFlags.AMD64ContextControl) == ContextFlags.AMD64ContextControl) { if (!CheckContextChunk(a1, a2, (int)AMD64Offsets.SegCs, (int)AMD64Offsets.SegDs) || !CheckContextChunk(a1, a2, (int)AMD64Offsets.SegSs, (int)AMD64Offsets.Dr0) || !CheckContextChunk(a1, a2, (int)AMD64Offsets.Rsp, (int)AMD64Offsets.Rbp) || !CheckContextChunk(a1, a2, (int)AMD64Offsets.Rip, (int)AMD64Offsets.FltSave)) { return(false); } } // CONTEXT_INTEGER contains: Rax, Rcx, Rdx, Rbx, Rbp, Rsi, Rdi, R8-R15 if ((a1.Flags & ContextFlags.AMD64ContextInteger) == ContextFlags.AMD64ContextInteger) { if (!CheckContextChunk(a1, a2, (int)AMD64Offsets.Rax, (int)AMD64Offsets.Rsp) || !CheckContextChunk(a1, a2, (int)AMD64Offsets.Rbp, (int)AMD64Offsets.Rip)) { return(false); } } // CONTEXT_SEGMENTS contains: SegDs, SegEs, SegFs, SegGs if ((a1.Flags & ContextFlags.AMD64ContextSegments) == ContextFlags.AMD64ContextSegments) { if (!CheckContextChunk(a1, a2, (int)AMD64Offsets.SegDs, (int)AMD64Offsets.SegSs)) { return(false); } } //CONTEXT_DEBUG_REGISTERS contains: Dr0-Dr3, Dr6-Dr7 (these are continuous in winnt.h) if ((a1.Flags & ContextFlags.AMD64ContextDebugRegisters) == ContextFlags.AMD64ContextDebugRegisters) { if (!CheckContextChunk(a1, a2, (int)AMD64Offsets.Dr0, (int)AMD64Offsets.Rax)) { return(false); } } //CONTEXT_FLOATING_POINT contains: Mm0/St0-Mm7/St7, Xmm0-Xmm15 if ((a1.Flags & ContextFlags.AMD64ContextFloatingPoint) == ContextFlags.AMD64ContextFloatingPoint) { if (!CheckContextChunk(a1, a2, (int)AMD64Offsets.FltSave, (int)AMD64Offsets.VectorRegister)) { return(false); } } return(true); }
// compare a chuck of the context record contained between the two offsets private bool CheckContextChunk(AMD64Context a1, AMD64Context a2, int startOffset, int endOffset) { using (IContextDirectAccessor c1 = a1.OpenForDirectAccess()) { using (IContextDirectAccessor c2 = a2.OpenForDirectAccess()) { for (int i = startOffset; i < endOffset; i++) { if (Marshal.ReadByte(c1.RawBuffer, i) != Marshal.ReadByte(c2.RawBuffer, i)) { return(false); } } } } return(true); }