c# - 为 PInvoke 声明 CONTEXT 结构 (Windows x64)

标签 c# winapi struct 64-bit interop

我正在尝试使用 IDebugAdvanced ClrMd 接口(interface)从 x64 进程获取 CONTEXT。 但是我在其中得到了一些乱码。 示例:

{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;
    };

提前致谢:

最佳答案

首先,WORD 是一个 16 位类型(unsigned short),而不是 unsigned char

其次,一个小的 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++ 控制台应用程序生成的,在 main() 函数中包含以下内容:

#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

根据这些信息,您应该可以毫无困难地在兼容的托管代码中构建结构。

关于c# - 为 PInvoke 声明 CONTEXT 结构 (Windows x64),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37656523/

相关文章:

c# - 是否可以使用带符号的 REST url 参数?

c# - Ninject 依赖解析器

c++ - 从外部源向 Windows 调试器发送调试事件

c - 结构数组读取函数将所有数组值更改为最新输入 - C

arrays - 按特定参数对 c 中的结构体数组进行排序

c# - Discord OAuth 代码使用

c# - 重构我的 C# 代码 : if-else statement and code repetition

java - 从 Java 调用 Win32 API 方法

windows - Hook Win32 API 事件以在桌面完全加载时收到通知

c++ - C 中的空结构与 C++ 中的空结构