所有线程上下文结构的正确实现是什么?

What is the proper implementation of all the thread context structs?

很抱歉发布这个,但是,我正在努力实施 GetThreadContextSetThreadContext 因为结构是错误的,它们还导致库抛出 ReflectionTypeLoadException.

这是我对结构的实现:

[StructLayout(LayoutKind.Sequential)]
public struct THREAD_CONTEXT_IA32
{
    public THREAD_CONTEXT_IA32(IA32_CONTEXT_FLAG flags) : this()
    {
        cFlags = flags;
    }

    private IA32_CONTEXT_FLAG cFlags;
    public int dr0;
    public int dr1;
    public int dr2;
    public int dr3;
    public int dr6;
    public int dr7;
    public FLOATING_SAVE_AREA floatSave;
    public int segGs;
    public int segFs;
    public int segEs;
    public int segDs;
    public int edi;
    public int esi;
    public int ebx;
    public int edx;
    public int ecx;
    public int eax;
    public int ebp;
    public int eip;
    public int segCs;
    public int eFlags;
    public int esp;
    public int segSs;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAXIMUM_SUPPORTED_EXTENSION)]
    public byte[] extendedRegisters;
}

[StructLayout(LayoutKind.Explicit, Pack = 16)]
public struct THREAD_CONTEXT_AMD64
{
    public THREAD_CONTEXT_AMD64(AMD64_CONTEXT_FLAG flags) : this()
    {
        cFlags = flags;
    }

    [FieldOffset(0)]
    public long p1Home;
    [FieldOffset(8)]
    public long p2Home;
    [FieldOffset(16)]
    public long p3Home;
    [FieldOffset(24)]
    public long p4Home;
    [FieldOffset(32)]
    public long p5Home;
    [FieldOffset(40)]
    public long p6Home;
    [FieldOffset(48)]
    private AMD64_CONTEXT_FLAG cFlags;
    [FieldOffset(50)]
    public int mxCsr;
    [FieldOffset(54)]
    public short segCs;
    [FieldOffset(56)]
    public short segDs;
    [FieldOffset(58)]
    public short segEs;
    [FieldOffset(60)]
    public short segFs;
    [FieldOffset(62)]
    public short segGs;
    [FieldOffset(64)]
    public short segSs;
    [FieldOffset(66)]
    public int eFlags;
    [FieldOffset(70)]
    public long dr0;
    [FieldOffset(78)]
    public long dr1;
    [FieldOffset(86)]
    public long dr2;
    [FieldOffset(94)]
    public long dr3;
    [FieldOffset(102)]
    public long dr6;
    [FieldOffset(110)]
    public long dr7;
    [FieldOffset(118)]
    public long rax;
    [FieldOffset(126)]
    public long rcx;
    [FieldOffset(132)]
    public long rdx;
    [FieldOffset(140)]
    public long rbx;
    [FieldOffset(148)]
    public long rsp;
    [FieldOffset(156)]
    public long rbp;
    [FieldOffset(174)]
    public long rsi;
    [FieldOffset(182)]
    public long rdi;
    [FieldOffset(190)]
    public long r8;
    [FieldOffset(198)]
    public long r9;
    [FieldOffset(206)]
    public long r10;
    [FieldOffset(214)]
    public long r11;
    [FieldOffset(222)]
    public long r12;
    [FieldOffset(230)]
    public long r13;
    [FieldOffset(238)]
    public long r14;
    [FieldOffset(246)]
    public long r15;
    [FieldOffset(252)]
    public long rip;
    [FieldOffset(260)]
    public XSAVE_FORMAT fltSave;
    [FieldOffset(772)]
    public M128A header0;
    [FieldOffset(788)]
    public M128A header1;
    [FieldOffset(804)]
    public M128A legacy0;
    [FieldOffset(820)]
    public M128A legacy1;
    [FieldOffset(836)]
    public M128A legacy2;
    [FieldOffset(852)]
    public M128A legacy3;
    [FieldOffset(868)]
    public M128A legacy4;
    [FieldOffset(884)]
    public M128A legacy5;
    [FieldOffset(900)]
    public M128A legacy6;
    [FieldOffset(916)]
    public M128A legacy7;
    [FieldOffset(932)]
    public M128A xmm0;
    [FieldOffset(948)]
    public M128A xmm1;
    [FieldOffset(964)]
    public M128A xmm2;
    [FieldOffset(980)]
    public M128A xmm3;
    [FieldOffset(996)]
    public M128A xmm4;
    [FieldOffset(1012)]
    public M128A xmm5;
    [FieldOffset(1028)]
    public M128A xmm6;
    [FieldOffset(1044)]
    public M128A xmm7;
    [FieldOffset(1060)]
    public M128A xmm8;
    [FieldOffset(1076)]
    public M128A xmm9;
    [FieldOffset(1092)]
    public M128A xmm10;
    [FieldOffset(1108)]
    public M128A xmm11;
    [FieldOffset(1124)]
    public M128A xmm12;
    [FieldOffset(1140)]
    public M128A xmm13;
    [FieldOffset(1156)]
    public M128A xmm14;
    [FieldOffset(1172)]
    public M128A xmm15;
    [FieldOffset(1188)]
    public M128A vectorRegister0;
    [FieldOffset(1204)]
    public M128A vectorRegister1;
    [FieldOffset(1220)]
    public M128A vectorRegister2;
    [FieldOffset(1236)]
    public M128A vectorRegister3;
    [FieldOffset(1252)]
    public M128A vectorRegister4;
    [FieldOffset(1268)]
    public M128A vectorRegister5;
    [FieldOffset(1284)]
    public M128A vectorRegister6;
    [FieldOffset(1300)]
    public M128A vectorRegister7;
    [FieldOffset(1316)]
    public M128A vectorRegister8;
    [FieldOffset(1332)]
    public M128A vectorRegister9;
    [FieldOffset(1348)]
    public M128A vectorRegister10;
    [FieldOffset(1364)]
    public M128A vectorRegister11;
    [FieldOffset(1380)]
    public M128A vectorRegister12;
    [FieldOffset(1396)]
    public M128A vectorRegister13;
    [FieldOffset(1412)]
    public M128A vectorRegister14;
    [FieldOffset(1428)]
    public M128A vectorRegister15;
    [FieldOffset(1444)]
    public M128A vectorRegister16;
    [FieldOffset(1460)]
    public M128A vectorRegister17;
    [FieldOffset(1476)]
    public M128A vectorRegister18;
    [FieldOffset(1492)]
    public M128A vectorRegister19;
    [FieldOffset(1508)]
    public M128A vectorRegister20;
    [FieldOffset(1524)]
    public M128A vectorRegister21;
    [FieldOffset(1540)]
    public M128A vectorRegister22;
    [FieldOffset(1556)]
    public M128A vectorRegister23;
    [FieldOffset(1572)]
    public M128A vectorRegister24;
    [FieldOffset(1588)]
    public M128A vectorRegister25;
    [FieldOffset(1604)]
    public long vectorControl;
    [FieldOffset(1612)]
    public long debugControl;
    [FieldOffset(1620)]
    public long lastBranchToRip;
    [FieldOffset(1628)]
    public long lastBranchFromRip;
    [FieldOffset(1636)]
    public long lastExceptionToRip;
    [FieldOffset(1644)]
    public long lastExceptionFromRip;
}

[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct THREAD_CONTEXT_ARM
{
    public THREAD_CONTEXT_ARM(ARM_CONTEXT_FLAG flags) : this()
    {
        cFlags = flags;
    }

    private ARM_CONTEXT_FLAG cFlags;
    public int r0;
    public int r1;
    public int r2;
    public int r3;
    public int r4;
    public int r5;
    public int r6;
    public int r7;
    public int r8;
    public int r9;
    public int r10;
    public int r11;
    public int r12;
    public int sp;
    public int lr;
    public int pc;
    public int cpsr;
    public int fpscr;
    public int padding;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
    public NEON128[] neon;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = ARM_MAX_BREAKPOINTS)]
    public int[] bvr;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = ARM_MAX_BREAKPOINTS)]
    public int[] bcr;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = ARM_MAX_WATCHPOINTS)]
    public int[] wvr;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = ARM_MAX_WATCHPOINTS)]
    public int[] wcr;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
    public int[] padding2;
}

[StructLayout(LayoutKind.Sequential, Pack = 16)]
public struct THREAD_CONTEXT_ARM64
{
    public THREAD_CONTEXT_ARM64(ARM64_CONTEXT_FLAG flags) : this()
    {
        cFlags = flags;
    }

    private ARM64_CONTEXT_FLAG cFlags;
    public int cpsr;
    public long x0;
    public long x1;
    public long x2;
    public long x3;
    public long x4;
    public long x5;
    public long x6;
    public long x7;
    public long x8;
    public long x9;
    public long x10;
    public long x11;
    public long x12;
    public long x13;
    public long x14;
    public long x15;
    public long x16;
    public long x17;
    public long x18;
    public long x19;
    public long x20;
    public long x21;
    public long x22;
    public long x23;
    public long x24;
    public long x25;
    public long x26;
    public long x27;
    public long x28;
    public long fp;
    public long lr;
    public long sp;
    public long pc;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
    public NEON128[] neon;
    public int fpcr;
    public int fpsr;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = ARM64_MAX_BREAKPOINTS)]
    public int[] bcr;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = ARM64_MAX_BREAKPOINTS)]
    public long[] bvr;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = ARM64_MAX_WATCHPOINTS)]
    public int[] wcr;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = ARM64_MAX_WATCHPOINTS)]
    public long[] wvr;
}

[StructLayout(LayoutKind.Sequential)]
public struct THREAD_CONTEXT_WOW64
{
    public THREAD_CONTEXT_WOW64(WOW64_CONTEXT_FLAG flags) : this()
    {
        cFlags = flags;
    }

    private WOW64_CONTEXT_FLAG cFlags;
    public int dr0;
    public int dr1;
    public int dr2;
    public int dr3;
    public int dr6;
    public int dr7;
    public FLOATING_SAVE_AREA floatSave;
    public int segGs;
    public int segFs;
    public int segEs;
    public int segDs;
    public int edi;
    public int esi;
    public int ebx;
    public int edx;
    public int ecx;
    public int eax;
    public int ebp;
    public int eip;
    public int segCs;
    public int eFlags;
    public int esp;
    public int segSs;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAXIMUM_SUPPORTED_EXTENSION)]
    public byte[] extendedRegisters;
}

[StructLayout(LayoutKind.Sequential)]
public struct FLOATING_SAVE_AREA
{
    public int controlWord;
    public int statusWord;
    public int tagWord;
    public int errorOffset;
    public int errorSelector;
    public int dataOffset;
    public int dataSelector;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = SIZE_OF_80387_REGISTERS)]
    public byte[] registerArea;
    public int spare0;
}

[StructLayout(LayoutKind.Sequential, Pack = 16)]
public struct M128A
{
    public M128A(ulong _low, long _high)
    {
        low = _low;

        high = _high;
    }

    public ulong low;
    public long high;
}

[StructLayout(LayoutKind.Sequential)]
public struct NEON128
{
    public NEON128(ulong _low, long _high)
    {
        low = _low;

        high = _high;
    }

    public ulong low;
    public long high;
}

[StructLayout(LayoutKind.Explicit, Pack = 16)]
public struct XSAVE_FORMAT
{
    [FieldOffset(0)]
    public short controlWord;
    [FieldOffset(2)]
    public short statusWord;
    [FieldOffset(4)]
    public byte tagWord;
    [FieldOffset(5)]
    private byte reserved0;
    [FieldOffset(6)]
    public short errorOpcode;
    [FieldOffset(8)]
    public int errorOffset;
    [FieldOffset(12)]
    public short errorSelector;
    [FieldOffset(14)]
    private ushort reserved1;
    [FieldOffset(16)]
    public int dataOffset;
    [FieldOffset(20)]
    public short dataSelector;
    [FieldOffset(22)]
    private ushort reserved2;
    [FieldOffset(24)]
    public int mxCsr;
    [FieldOffset(28)]
    public int mxCsrMask;
    [FieldOffset(32)]
    public M128A floatRegister0;
    [FieldOffset(48)]
    public M128A floatRegister1;
    [FieldOffset(64)]
    public M128A floatRegister2;
    [FieldOffset(80)]
    public M128A floatRegister3;
    [FieldOffset(96)]
    public M128A floatRegister4;
    [FieldOffset(112)]
    public M128A floatRegister5;
    [FieldOffset(128)]
    public M128A floatRegister6;
    [FieldOffset(144)]
    public M128A floatRegister7;
    [FieldOffset(160)]
    public M128A xmmRegister0;
    [FieldOffset(176)]
    public M128A xmmRegister1;
    [FieldOffset(192)]
    public M128A xmmRegister2;
    [FieldOffset(208)]
    public M128A xmmRegister3;
    [FieldOffset(224)]
    public M128A xmmRegister4;
    [FieldOffset(240)]
    public M128A xmmRegister5;
    [FieldOffset(256)]
    public M128A xmmRegister6;
    [FieldOffset(272)]
    public M128A xmmRegister7;
    [FieldOffset(288)]
    public M128A xmmRegister8;
    [FieldOffset(304)]
    public M128A xmmRegister9;
    [FieldOffset(320)]
    public M128A xmmRegister10;
    [FieldOffset(336)]
    public M128A xmmRegister11;
    [FieldOffset(352)]
    public M128A xmmRegister12;
    [FieldOffset(368)]
    public M128A xmmRegister13;
    [FieldOffset(384)]
    public M128A xmmRegister14;
    [FieldOffset(400)]
    public M128A xmmRegister15;
    [FieldOffset(416)]
    private M128A Reserved3_0;
    [FieldOffset(432)]
    private M128A Reserved3_1;
    [FieldOffset(448)]
    private M128A Reserved3_2;
    [FieldOffset(464)]
    private M128A Reserved3_3;
    [FieldOffset(480)]
    private M128A Reserved3_4;
    [FieldOffset(496)]
    private M128A Reserved3_5;
}

如有任何帮助,我们将不胜感激。请注意,所有标志枚举都是 uint。我很确定一个或多个偏移量是错误的但不确定在哪里(已经检查了它们 5 次)

这似乎对我有用(在 Windows 10 64 上的 x86 和 x64 中测试)=>

// Check sizes
// 716
int nSize = Marshal.SizeOf(typeof(CONTEXT));
// 1232
int nSize64 = Marshal.SizeOf(typeof(CONTEXT64));

CONTEXT ctx = new CONTEXT();
// CONTEXT64 ctx = new CONTEXT64();

ctx.ContextFlags = CONTEXT_ALL;                
bool bRet = GetThreadContext(GetCurrentThread(), ref ctx);

与(来自 SDK headers 和 WinDbg):

    [StructLayout(LayoutKind.Explicit, Pack = 16)]
    public struct CONTEXT64
    {
        [FieldOffset(0x000)]
        public ulong P1Home;
        [FieldOffset(0x008)]
        public ulong P2Home;
        [FieldOffset(0x010)]
        public ulong P3Home;
        [FieldOffset(0x018)]
        public ulong P4Home;
        [FieldOffset(0x020)]
        public ulong P5Home;
        [FieldOffset(0x028)]
        public ulong P6Home;
        [FieldOffset(0x030)]
        public int ContextFlags;
        [FieldOffset(0x034)]
        public int MxCsr;
        [FieldOffset(0x038)]
        public ushort SegCs;
        [FieldOffset(0x03a)]
        public ushort SegDs;
        [FieldOffset(0x03c)]
        public ushort SegEs;
        [FieldOffset(0x03e)]
        public ushort SegFs;
        [FieldOffset(0x040)]
        public ushort SegGs;
        [FieldOffset(0x042)]
        public ushort SegSs;
        [FieldOffset(0x044)]
        public int EFlags;

        [FieldOffset(0x048)]
        public ulong Dr0;
        [FieldOffset(0x050)]
        public ulong Dr1;
        [FieldOffset(0x058)]
        public ulong Dr2;
        [FieldOffset(0x060)]
        public ulong Dr3;
        [FieldOffset(0x068)]
        public ulong Dr6;
        [FieldOffset(0x070)]
        public ulong Dr7;
        [FieldOffset(0x078)]
        public ulong Rax;
        [FieldOffset(0x080)]
        public ulong Rcx;
        [FieldOffset(0x088)]
        public ulong Rdx;
        [FieldOffset(0x090)]
        public ulong Rbx;
        [FieldOffset(0x098)]
        public ulong Rsp;
        [FieldOffset(0x0a0)]
        public ulong Rbp;
        [FieldOffset(0x0a8)]
        public ulong Rsi;
        [FieldOffset(0x0b0)]
        public ulong Rdi;

        [FieldOffset(0x0b8)]
        public ulong R8;
        [FieldOffset(0x0c0)]
        public ulong R9;
        [FieldOffset(0x0c8)]
        public ulong R10;
        [FieldOffset(0x0d0)]
        public ulong R11;
        [FieldOffset(0x0d8)]
        public ulong R12;
        [FieldOffset(0x0e0)]
        public ulong R13;
        [FieldOffset(0x0e8)]
        public ulong R14;
        [FieldOffset(0x0f0)]
        public ulong R15;
        [FieldOffset(0x0f8)]
        public ulong Rip;

        [FieldOffset(0x100)]
        //[MarshalAs(UnmanagedType.Struct, SizeConst = 512)]
        public XMM_SAVE_AREA32 FltSave;

        [FieldOffset(0x300)]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 26)]
        public M128A[] VectorRegister;
        [FieldOffset(0x4a0)]
        public ulong VectorControl;
        [FieldOffset(0x4a8)]
        public ulong DebugControl;
        [FieldOffset(0x4b0)]
        public ulong LastBranchToRip;
        [FieldOffset(0x4b8)]
        public ulong LastBranchFromRip;
        [FieldOffset(0x4c0)]
        public ulong LastExceptionToRip;
        [FieldOffset(0x4c8)]
        public ulong LastExceptionFromRip;
    }


    [StructLayout(LayoutKind.Sequential, Pack = 16)]
    public struct XMM_SAVE_AREA32
    {
        public ushort ControlWord;
        public ushort StatusWord;
        public char TagWord;
        public char Reserved1;
        public ushort ErrorOpcode;
        public uint ErrorOffset;
        public ushort ErrorSelector;
        public ushort Reserved2;
        public uint DataOffset;
        public ushort DataSelector;
        public ushort Reserved3;
        public uint MxCsr;
        public uint MxCsrMask;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public M128A[] FloatRegisters;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
        public M128A[] XmmRegisters;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 96)]
        public char[] Reserved4;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct FLOATING_SAVE_AREA
    {
        public int ControlWord;
        public int StatusWord;
        public int TagWord;
        public int ErrorOffset;
        public int ErrorSelector;
        public int DataOffset;
        public int DataSelector;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = SIZE_OF_80387_REGISTERS)]
        public byte[] RegisterArea;
        public int Spare0;
    }

    public const int MAXIMUM_SUPPORTED_EXTENSION = 512;

    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    public struct CONTEXT
    {
        public int ContextFlags;

        public int Dr0;
        public int Dr1;
        public int Dr2;
        public int Dr3;
        public int Dr6;
        public int Dr7;

        public FLOATING_SAVE_AREA FloatSave;

        public int SegGs;
        public int SegFs;
        public int SegEs;
        public int SegDs;

        public int Edi;
        public int Esi;
        public int Ebx;
        public int Edx;
        public int Ecx;
        public int Eax;

        public int Ebp;
        public int Eip;
        public int SegCs;              // MUST BE SANITIZED
        public int EFlags;             // MUST BE SANITIZED
        public int Esp;
        public int SegSs;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAXIMUM_SUPPORTED_EXTENSION)]
        public byte[] ExtendedRegisters;
    }

    [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern IntPtr GetCurrentThread();

    [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool GetThreadContext(IntPtr hThread, ref CONTEXT lpContext);

    [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool GetThreadContext(IntPtr hThread, ref CONTEXT64 lpContext);

    public const int SIZE_OF_80387_REGISTERS = 80;

    public const int CONTEXT_i386 = 0x00010000;    // this assumes that i386 and
    public const int CONTEXT_i486 = 0x00010000;    // i486 have identical context records

    public const int CONTEXT_CONTROL = (CONTEXT_i386 | 0x00000001); // SS:SP, CS:IP, FLAGS, BP
    public const int CONTEXT_INTEGER = (CONTEXT_i386 | 0x00000002); // AX, BX, CX, DX, SI, DI
    public const int CONTEXT_SEGMENTS = (CONTEXT_i386 | 0x00000004); // DS, ES, FS, GS
    public const int CONTEXT_FLOATING_POINT = (CONTEXT_i386 | 0x00000008); // 387 state
    public const int CONTEXT_DEBUG_REGISTERS = (CONTEXT_i386 | 0x00000010); // DB 0-3,6,7
    public const int CONTEXT_EXTENDED_REGISTERS = (CONTEXT_i386 | 0x00000020); // cpu specific extensions

    public const int CONTEXT_FULL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS);

    public const int CONTEXT_ALL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | CONTEXT_EXTENDED_REGISTERS);
    public const int CONTEXT_XSTATE = (CONTEXT_i386 | 0x00000040);

    public const int CONTEXT_EXCEPTION_ACTIVE = 0x08000000;
    public const int CONTEXT_SERVICE_ACTIVE = 0x10000000;
    public const int CONTEXT_EXCEPTION_REQUEST = 0x40000000;
    public const int CONTEXT_EXCEPTION_REPORTING = unchecked((int)0x80000000);