C# 为PInvoke(Windows x64)声明上下文结构

C# 为PInvoke(Windows x64)声明上下文结构,c#,winapi,struct,64-bit,interop,C#,Winapi,Struct,64 Bit,Interop,我正在尝试使用IDEBUG高级ClrMd接口从x64进程获取上下文。 但我得到了一些胡言乱语的价值观。 例如: {WinNativeApi.WinNT.CONTEXT_AMD64} ContextFlags: 1048607 DebugControl: 0 Dr0: 0 Dr1: 0 Dr2: 0 Dr3: 0 Dr6: 0 Dr7: 0 EFlags: 2818091 LastBranchFromRip: 0

我正在尝试使用IDEBUG高级ClrMd接口从x64进程获取上下文。 但我得到了一些胡言乱语的价值观。 例如:

{WinNativeApi.WinNT.CONTEXT_AMD64}
    ContextFlags: 1048607
    DebugControl: 0
    Dr0: 0
    Dr1: 0
    Dr2: 0
    Dr3: 0
    Dr6: 0
    Dr7: 0
    EFlags: 2818091
    LastBranchFromRip: 0
    LastBranchToRip: 0
    LastExceptionFromRip: 0
    LastExceptionToRip: 0
    MxCsr: 8096
    P1Home: 1035103895583
    P2Home: 2239468740072
    P3Home: 2237682024510
    P4Home: 1039055965440
    P5Home: 24488718114619459
    P6Home: 31244151918821481
    R10: 2747550605264
    R11: 2747522160368
    R12: 1
    R13: 512
    R14: 922054817240
    R15: 4294901760
    R8: 0
    R9: 2747522160368
    Rax: 2747550600488
    Rbp: 922054817584
    Rbx: 0
    Rcx: 2747550600488
    Rdi: 696
    Rdx: 2747550600488
    Rip: 140706165903700
    Rsi: 20000
    Rsp: 922054817192
    SegCs: 51
    SegDs: 0
    SegEs: 43
    SegFs: 0
    SegGs: 43
    SegSs: 0
    VectorControl: 0
    VectorRegister: 0x0000000000000000
    dummyUnion: {WinNativeApi.WinNT.DUMMYUNIONNAME}
有人能告诉我我的C#声明是否正确吗

C++WinNt.h声明:

typedef struct DECLSPEC_ALIGN(16) _CONTEXT {

    //
    // Register parameter home addresses.
    //
    // N.B. These fields are for convience - they could be used to extend the
    //      context record in the future.
    //

    DWORD64 P1Home;
    DWORD64 P2Home;
    DWORD64 P3Home;
    DWORD64 P4Home;
    DWORD64 P5Home;
    DWORD64 P6Home;

    //
    // Control flags.
    //

    DWORD ContextFlags;
    DWORD MxCsr;

    //
    // Segment Registers and processor flags.
    //

    WORD   SegCs;
    WORD   SegDs;
    WORD   SegEs;
    WORD   SegFs;
    WORD   SegGs;
    WORD   SegSs;
    DWORD EFlags;

    //
    // Debug registers
    //

    DWORD64 Dr0;
    DWORD64 Dr1;
    DWORD64 Dr2;
    DWORD64 Dr3;
    DWORD64 Dr6;
    DWORD64 Dr7;

    //
    // Integer registers.
    //

    DWORD64 Rax;
    DWORD64 Rcx;
    DWORD64 Rdx;
    DWORD64 Rbx;
    DWORD64 Rsp;
    DWORD64 Rbp;
    DWORD64 Rsi;
    DWORD64 Rdi;
    DWORD64 R8;
    DWORD64 R9;
    DWORD64 R10;
    DWORD64 R11;
    DWORD64 R12;
    DWORD64 R13;
    DWORD64 R14;
    DWORD64 R15;

    //
    // Program counter.
    //

    DWORD64 Rip;

    //
    // Floating point state.
    //

    union {
        XMM_SAVE_AREA32 FltSave;
        struct {
            M128A Header[2];
            M128A Legacy[8];
            M128A Xmm0;
            M128A Xmm1;
            M128A Xmm2;
            M128A Xmm3;
            M128A Xmm4;
            M128A Xmm5;
            M128A Xmm6;
            M128A Xmm7;
            M128A Xmm8;
            M128A Xmm9;
            M128A Xmm10;
            M128A Xmm11;
            M128A Xmm12;
            M128A Xmm13;
            M128A Xmm14;
            M128A Xmm15;
        } DUMMYSTRUCTNAME;
    } DUMMYUNIONNAME;

    //
    // Vector registers.
    //

    M128A VectorRegister[26];
    DWORD64 VectorControl;

    //
    // Special debug control registers.
    //

    DWORD64 DebugControl;
    DWORD64 LastBranchToRip;
    DWORD64 LastBranchFromRip;
    DWORD64 LastExceptionToRip;
    DWORD64 LastExceptionFromRip;
} CONTEXT, *PCONTEXT;
using DWORD64 = System.UInt64;
using DWORD = System.Int32;
using WORD = System.SByte;
using ULONGLONG = System.UInt64;
using LONGLONG = System.Int64;

  [StructLayout(LayoutKind.Sequential, Pack = 16)]
    public unsafe struct CONTEXT_AMD64
    {
        //
        // Register parameter home addresses.
        //
        // N.B. These fields are for convience - they could be used to extend the
        //      context record in the future.
        //

        public DWORD64 P1Home;
        public DWORD64 P2Home;
        public DWORD64 P3Home;
        public DWORD64 P4Home;
        public DWORD64 P5Home;
        public DWORD64 P6Home;

        //
        // Control flags.
        //
        public DWORD ContextFlags;
        public DWORD MxCsr;

        //
        // Segment Registers and processor flags.
        //
        public WORD SegCs;
        public WORD SegDs;
        public WORD SegEs;
        public WORD SegFs;
        public WORD SegGs;
        public WORD SegSs;
        public DWORD EFlags;

        //
        // Debug registers
        //
        public DWORD64 Dr0;
        public DWORD64 Dr1;
        public DWORD64 Dr2;
        public DWORD64 Dr3;
        public DWORD64 Dr6;
        public DWORD64 Dr7;

        //
        // Integer registers.
        //
        public DWORD64 Rax;
        public DWORD64 Rcx;
        public DWORD64 Rdx;
        public DWORD64 Rbx;
        public DWORD64 Rsp;
        public DWORD64 Rbp;
        public DWORD64 Rsi;
        public DWORD64 Rdi;
        public DWORD64 R8;
        public DWORD64 R9;
        public DWORD64 R10;
        public DWORD64 R11;
        public DWORD64 R12;
        public DWORD64 R13;
        public DWORD64 R14;
        public DWORD64 R15;

        //
        // Program counter.
        //
        public DWORD64 Rip;

        //
        // Floating point state.
        //
        public DUMMYUNIONNAME dummyUnion;

        //
        // Vector registers.
        //
        M128A* VectorRegister;
        public DWORD64 VectorControl;

        //
        // Special debug control registers.
        //
        public DWORD64 DebugControl;
        public DWORD64 LastBranchToRip;
        public DWORD64 LastBranchFromRip;
        public DWORD64 LastExceptionToRip;
        public DWORD64 LastExceptionFromRip;
    }

    struct XMM_SAVE_AREA32
    {

    }

    public unsafe struct DUMMY
    {
        M128A* Header;
        M128A* Legacy;
        M128A Xmm0;
        M128A Xmm1;
        M128A Xmm2;
        M128A Xmm3;
        M128A Xmm4;
        M128A Xmm5;
        M128A Xmm6;
        M128A Xmm7;
        M128A Xmm8;
        M128A Xmm9;
        M128A Xmm10;
        M128A Xmm11;
        M128A Xmm12;
        M128A Xmm13;
        M128A Xmm14;
        M128A Xmm15;
    }

    [StructLayout(LayoutKind.Explicit)]
    public struct DUMMYUNIONNAME
    {
        [FieldOffset(0)]
        XMM_SAVE_AREA32 FltSave;
        [FieldOffset(1)]
        DUMMY Dummy;
    }

    struct M128A
    {
        ULONGLONG Low;
        LONGLONG High;
    };
我的托管结构:

typedef struct DECLSPEC_ALIGN(16) _CONTEXT {

    //
    // Register parameter home addresses.
    //
    // N.B. These fields are for convience - they could be used to extend the
    //      context record in the future.
    //

    DWORD64 P1Home;
    DWORD64 P2Home;
    DWORD64 P3Home;
    DWORD64 P4Home;
    DWORD64 P5Home;
    DWORD64 P6Home;

    //
    // Control flags.
    //

    DWORD ContextFlags;
    DWORD MxCsr;

    //
    // Segment Registers and processor flags.
    //

    WORD   SegCs;
    WORD   SegDs;
    WORD   SegEs;
    WORD   SegFs;
    WORD   SegGs;
    WORD   SegSs;
    DWORD EFlags;

    //
    // Debug registers
    //

    DWORD64 Dr0;
    DWORD64 Dr1;
    DWORD64 Dr2;
    DWORD64 Dr3;
    DWORD64 Dr6;
    DWORD64 Dr7;

    //
    // Integer registers.
    //

    DWORD64 Rax;
    DWORD64 Rcx;
    DWORD64 Rdx;
    DWORD64 Rbx;
    DWORD64 Rsp;
    DWORD64 Rbp;
    DWORD64 Rsi;
    DWORD64 Rdi;
    DWORD64 R8;
    DWORD64 R9;
    DWORD64 R10;
    DWORD64 R11;
    DWORD64 R12;
    DWORD64 R13;
    DWORD64 R14;
    DWORD64 R15;

    //
    // Program counter.
    //

    DWORD64 Rip;

    //
    // Floating point state.
    //

    union {
        XMM_SAVE_AREA32 FltSave;
        struct {
            M128A Header[2];
            M128A Legacy[8];
            M128A Xmm0;
            M128A Xmm1;
            M128A Xmm2;
            M128A Xmm3;
            M128A Xmm4;
            M128A Xmm5;
            M128A Xmm6;
            M128A Xmm7;
            M128A Xmm8;
            M128A Xmm9;
            M128A Xmm10;
            M128A Xmm11;
            M128A Xmm12;
            M128A Xmm13;
            M128A Xmm14;
            M128A Xmm15;
        } DUMMYSTRUCTNAME;
    } DUMMYUNIONNAME;

    //
    // Vector registers.
    //

    M128A VectorRegister[26];
    DWORD64 VectorControl;

    //
    // Special debug control registers.
    //

    DWORD64 DebugControl;
    DWORD64 LastBranchToRip;
    DWORD64 LastBranchFromRip;
    DWORD64 LastExceptionToRip;
    DWORD64 LastExceptionFromRip;
} CONTEXT, *PCONTEXT;
using DWORD64 = System.UInt64;
using DWORD = System.Int32;
using WORD = System.SByte;
using ULONGLONG = System.UInt64;
using LONGLONG = System.Int64;

  [StructLayout(LayoutKind.Sequential, Pack = 16)]
    public unsafe struct CONTEXT_AMD64
    {
        //
        // Register parameter home addresses.
        //
        // N.B. These fields are for convience - they could be used to extend the
        //      context record in the future.
        //

        public DWORD64 P1Home;
        public DWORD64 P2Home;
        public DWORD64 P3Home;
        public DWORD64 P4Home;
        public DWORD64 P5Home;
        public DWORD64 P6Home;

        //
        // Control flags.
        //
        public DWORD ContextFlags;
        public DWORD MxCsr;

        //
        // Segment Registers and processor flags.
        //
        public WORD SegCs;
        public WORD SegDs;
        public WORD SegEs;
        public WORD SegFs;
        public WORD SegGs;
        public WORD SegSs;
        public DWORD EFlags;

        //
        // Debug registers
        //
        public DWORD64 Dr0;
        public DWORD64 Dr1;
        public DWORD64 Dr2;
        public DWORD64 Dr3;
        public DWORD64 Dr6;
        public DWORD64 Dr7;

        //
        // Integer registers.
        //
        public DWORD64 Rax;
        public DWORD64 Rcx;
        public DWORD64 Rdx;
        public DWORD64 Rbx;
        public DWORD64 Rsp;
        public DWORD64 Rbp;
        public DWORD64 Rsi;
        public DWORD64 Rdi;
        public DWORD64 R8;
        public DWORD64 R9;
        public DWORD64 R10;
        public DWORD64 R11;
        public DWORD64 R12;
        public DWORD64 R13;
        public DWORD64 R14;
        public DWORD64 R15;

        //
        // Program counter.
        //
        public DWORD64 Rip;

        //
        // Floating point state.
        //
        public DUMMYUNIONNAME dummyUnion;

        //
        // Vector registers.
        //
        M128A* VectorRegister;
        public DWORD64 VectorControl;

        //
        // Special debug control registers.
        //
        public DWORD64 DebugControl;
        public DWORD64 LastBranchToRip;
        public DWORD64 LastBranchFromRip;
        public DWORD64 LastExceptionToRip;
        public DWORD64 LastExceptionFromRip;
    }

    struct XMM_SAVE_AREA32
    {

    }

    public unsafe struct DUMMY
    {
        M128A* Header;
        M128A* Legacy;
        M128A Xmm0;
        M128A Xmm1;
        M128A Xmm2;
        M128A Xmm3;
        M128A Xmm4;
        M128A Xmm5;
        M128A Xmm6;
        M128A Xmm7;
        M128A Xmm8;
        M128A Xmm9;
        M128A Xmm10;
        M128A Xmm11;
        M128A Xmm12;
        M128A Xmm13;
        M128A Xmm14;
        M128A Xmm15;
    }

    [StructLayout(LayoutKind.Explicit)]
    public struct DUMMYUNIONNAME
    {
        [FieldOffset(0)]
        XMM_SAVE_AREA32 FltSave;
        [FieldOffset(1)]
        DUMMY Dummy;
    }

    struct M128A
    {
        ULONGLONG Low;
        LONGLONG High;
    };

提前感谢:

首先,
WORD
是一种16位类型(
无符号短字符
),而不是
无符号字符

第二,一个小的C++抓取控制台应用程序可以给你整个结构布局,它的大小是使用的所有数据类型的大小。

Struct CONTEXT Total Size: 1232

Data Types:
-----------
DWORD64: 8 bytes
DWORD: 4 bytes
WORD: 2 bytes
ULONGLONG: 8 bytes
LONGLONG: 8 bytes
M128A: 16 bytes
XMM_SAVE_AREA32: 512 bytes

Member Offsets:
---------------
P1Home: 0
P2Home: 8
P3Home: 16
P4Home: 24
P5Home: 32
P6Home: 40
ContextFlags: 48
MxCsr: 52
SegCs: 56
SegDs: 58
SegEs: 60
SegFs: 62
SegGs: 64
SegSs: 66
EFlags: 68
Dr0: 72
Dr1: 80
Dr2: 88
Dr3: 96
Dr6: 104
Dr7: 112
Rax: 120
Rcx: 128
Rdx: 136
Rbx: 144
Rsp: 152
Rbp: 160
Rsi: 168
Rdi: 176
R8: 184
R9: 192
R10: 200
R11: 208
R12: 216
R13: 224
R14: 232
R15: 240
Rip: 248
FltSave: 256
Header: 256
Legacy: 288
Xmm0: 416
Xmm1: 432
Xmm2: 448
Xmm3: 464
Xmm4: 480
Xmm5: 496
Xmm6: 512
Xmm7: 528
Xmm8: 544
Xmm9: 560
Xmm10: 576
Xmm11: 592
Xmm12: 608
Xmm13: 624
Xmm14: 640
Xmm15: 656
VectorRegister: 768
VectorControl: 1184
DebugControl: 1192
LastBranchToRip: 1200
LastBranchFromRip: 1208
LastExceptionToRip: 1216
LastExceptionFromRip: 1224

以上是由一个简单的C++控制台应用程序生成的,下面的代码<主代码()>代码>函数:

#define PRINTMBR(m) cout << #m": " << offsetof(CONTEXT, m) << endl;
cout << "Struct CONTEXT Total Size: " << sizeof(CONTEXT) << endl << endl;

cout << "Data Types:" << endl;
cout << "-----------" << endl;
cout << "DWORD64: " << sizeof(DWORD64) << " bytes" << endl;
cout << "DWORD: " << sizeof(DWORD) << " bytes" << endl;
cout << "WORD: " << sizeof(WORD) << " bytes" << endl;
cout << "ULONGLONG: " << sizeof(ULONGLONG) << " bytes" << endl;
cout << "LONGLONG: " << sizeof(LONGLONG) << " bytes" << endl;
cout << "M128A: " << sizeof(M128A) << " bytes" << endl;
cout << "XMM_SAVE_AREA32: " << sizeof(XMM_SAVE_AREA32) << " bytes" << endl;

cout << endl;
cout << "Member Offsets:" << endl;
cout << "---------------" << endl;

PRINTMBR(P1Home);
PRINTMBR(P2Home);
PRINTMBR(P3Home);
PRINTMBR(P4Home);
PRINTMBR(P5Home);
PRINTMBR(P6Home);
PRINTMBR(ContextFlags);
// snipped the rest so this post isn't 50 pages long

#定义PRINTMBR(m)cout首先,
是16位类型(
无符号短字符
),而不是
无符号字符

第二,一个小的C++抓取控制台应用程序可以给你整个结构布局,它的大小是使用的所有数据类型的大小。

Struct CONTEXT Total Size: 1232

Data Types:
-----------
DWORD64: 8 bytes
DWORD: 4 bytes
WORD: 2 bytes
ULONGLONG: 8 bytes
LONGLONG: 8 bytes
M128A: 16 bytes
XMM_SAVE_AREA32: 512 bytes

Member Offsets:
---------------
P1Home: 0
P2Home: 8
P3Home: 16
P4Home: 24
P5Home: 32
P6Home: 40
ContextFlags: 48
MxCsr: 52
SegCs: 56
SegDs: 58
SegEs: 60
SegFs: 62
SegGs: 64
SegSs: 66
EFlags: 68
Dr0: 72
Dr1: 80
Dr2: 88
Dr3: 96
Dr6: 104
Dr7: 112
Rax: 120
Rcx: 128
Rdx: 136
Rbx: 144
Rsp: 152
Rbp: 160
Rsi: 168
Rdi: 176
R8: 184
R9: 192
R10: 200
R11: 208
R12: 216
R13: 224
R14: 232
R15: 240
Rip: 248
FltSave: 256
Header: 256
Legacy: 288
Xmm0: 416
Xmm1: 432
Xmm2: 448
Xmm3: 464
Xmm4: 480
Xmm5: 496
Xmm6: 512
Xmm7: 528
Xmm8: 544
Xmm9: 560
Xmm10: 576
Xmm11: 592
Xmm12: 608
Xmm13: 624
Xmm14: 640
Xmm15: 656
VectorRegister: 768
VectorControl: 1184
DebugControl: 1192
LastBranchToRip: 1200
LastBranchFromRip: 1208
LastExceptionToRip: 1216
LastExceptionFromRip: 1224

以上是由一个简单的C++控制台应用程序生成的,下面的代码<主代码()>代码>函数:

#define PRINTMBR(m) cout << #m": " << offsetof(CONTEXT, m) << endl;
cout << "Struct CONTEXT Total Size: " << sizeof(CONTEXT) << endl << endl;

cout << "Data Types:" << endl;
cout << "-----------" << endl;
cout << "DWORD64: " << sizeof(DWORD64) << " bytes" << endl;
cout << "DWORD: " << sizeof(DWORD) << " bytes" << endl;
cout << "WORD: " << sizeof(WORD) << " bytes" << endl;
cout << "ULONGLONG: " << sizeof(ULONGLONG) << " bytes" << endl;
cout << "LONGLONG: " << sizeof(LONGLONG) << " bytes" << endl;
cout << "M128A: " << sizeof(M128A) << " bytes" << endl;
cout << "XMM_SAVE_AREA32: " << sizeof(XMM_SAVE_AREA32) << " bytes" << endl;

cout << endl;
cout << "Member Offsets:" << endl;
cout << "---------------" << endl;

PRINTMBR(P1Home);
PRINTMBR(P2Home);
PRINTMBR(P3Home);
PRINTMBR(P4Home);
PRINTMBR(P5Home);
PRINTMBR(P6Home);
PRINTMBR(ContextFlags);
// snipped the rest so this post isn't 50 pages long

#define PRINTMBR(m)cout我最近发现,您可以使用WinDbgdt命令,例如,如果您想获得\RTL\u CRITICAL\u SECTION结构布局,您可以简单地键入:

0:000> dt ntdll!_RTL_CRITICAL_SECTION
输出:

   +0x000 DebugInfo        : Ptr32 _RTL_CRITICAL_SECTION_DEBUG
   +0x004 LockCount        : Int4B
   +0x008 RecursionCount   : Int4B
   +0x00c OwningThread     : Ptr32 Void
   +0x010 LockSemaphore    : Ptr32 Void
   +0x014 SpinCount        : Uint4B

我最近发现,您可以使用WinDbgdt命令,例如,如果您想获得\u RTL\u CRITICAL\u SECTION结构布局,您只需键入:

0:000> dt ntdll!_RTL_CRITICAL_SECTION
输出:

   +0x000 DebugInfo        : Ptr32 _RTL_CRITICAL_SECTION_DEBUG
   +0x004 LockCount        : Int4B
   +0x008 RecursionCount   : Int4B
   +0x00c OwningThread     : Ptr32 Void
   +0x010 LockSemaphore    : Ptr32 Void
   +0x014 SpinCount        : Uint4B

做一些调试。首先比较结构的大小(本机版本和托管版本)。然后通过比较偏移量来深入挖掘。这就是互操作101。WORD是一个16位的值,所以您需要
使用WORD=System.UInt16进行一些调试。首先比较结构的大小(本机版本和托管版本)。然后通过比较偏移量来深入挖掘。这就是互操作101。WORD是一个16位的值,所以您需要
使用WORD=System.UInt16非常感谢您!没问题。对于编组结构,编写一个快速的C++控制台应用程序几乎是最容易的。而且你不需要知道更多的C++,而不是上面的内容。(即-
sizeof
offsetof
,以及用于将其打印到控制台的
iostream
内容)宏只需节省复制/粘贴的复杂性。这是非常有用的提示:)!再次感谢,非常感谢!没问题。对于编组结构,编写一个快速的C++控制台应用程序几乎是最容易的。而且你不需要知道更多的C++,而不是上面的内容。(即-
sizeof
offsetof
,以及用于将其打印到控制台的
iostream
内容)宏只需节省复制/粘贴的复杂性。这是非常有用的提示:)!再次感谢