GetThreadContext (kernel32)
Last changed: -186.136.223.176

.
Summary

C# Signature:

[DllImport("kernel32.dll")]
static extern bool GetThreadContext(IntPtr hThread, ref CONTEXT lpContext);

User-Defined Types:

Here are the structures and enums used by GetThreadContext:

public enum CONTEXT_FLAGS : uint
{
   CONTEXT_i386 = 0x10000,
   CONTEXT_i486 = 0x10000,   //  same as i386
   CONTEXT_CONTROL = CONTEXT_i386 | 0x01, // SS:SP, CS:IP, FLAGS, BP
   CONTEXT_INTEGER = CONTEXT_i386 | 0x02, // AX, BX, CX, DX, SI, DI
   CONTEXT_SEGMENTS = CONTEXT_i386 | 0x04, // DS, ES, FS, GS
   CONTEXT_FLOATING_POINT = CONTEXT_i386 | 0x08, // 387 state
   CONTEXT_DEBUG_REGISTERS = CONTEXT_i386 | 0x10, // DB 0-3,6,7
   CONTEXT_EXTENDED_REGISTERS = CONTEXT_i386 | 0x20, // cpu specific extensions
   CONTEXT_FULL = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS,
   CONTEXT_ALL = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS |  CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS |  CONTEXT_EXTENDED_REGISTERS
}


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

[StructLayout(LayoutKind.Sequential)]
public struct CONTEXT
{
     public uint ContextFlags; //set this to an appropriate value
     // Retrieved by CONTEXT_DEBUG_REGISTERS
     public uint Dr0;  
     public uint Dr1;
     public uint Dr2;
     public uint Dr3;
     public uint Dr6;
     public uint Dr7;
     // Retrieved by CONTEXT_FLOATING_POINT
     public FLOATING_SAVE_AREA FloatSave;
     // Retrieved by CONTEXT_SEGMENTS
     public uint SegGs;
     public uint SegFs;
     public uint SegEs;
     public uint SegDs;
     // Retrieved by CONTEXT_INTEGER
     public uint Edi;
     public uint Esi;
     public uint Ebx;
     public uint Edx;
     public uint Ecx;
     public uint Eax;
     // Retrieved by CONTEXT_CONTROL
     public uint Ebp;
     public uint Eip;
     public uint SegCs;
     public uint EFlags;
     public uint Esp;
     public uint SegSs;
     // Retrieved by CONTEXT_EXTENDED_REGISTERS
     [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
     public byte[] ExtendedRegisters;
}

Notes:

None.

Tips & Tricks:

Please add some!

Sample Code:

class Program

{

     [DllImport("kernel32.dll", SetLastError = true)]
     static extern IntPtr OpenThread(uint dwDesiredAccess, bool bInheritHandle,
     uint dwThreadId);

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

     [DllImport("kernel32.dll", SetLastError=true)]
     static extern bool CloseHandle(IntPtr hObject);

     const uint GET_CONTEXT = 0x08;

     static uint threadId;

     static void Main()
     {
     CONTEXT context = new CONTEXT();
     context.ContextFlags = (uint)CONTEXT_FLAGS.CONTEXT_CONTROL;
     Thread t = new Thread(new ThreadStart(MyMethod));
     t.Start();
     t.Suspend();
     IntPtr hThread = OpenThread(GET_CONTEXT, false, threadId);
     if (GetThreadContext(hThread, ref context))
     {
        Console.WriteLine("Ebp    : {0}", context.Ebp);
        Console.WriteLine("Eip    : {0}", context.Eip);
        Console.WriteLine("SegCs  : {0}", context.SegCs);
        Console.WriteLine("EFlags : {0}", context.EFlags);
        Console.WriteLine("Esp    : {0}", context.Esp);
        Console.WriteLine("SegSs  : {0}", context.SegSs);
     }
     else
     {
        Console.WriteLine("A problem occurred");
     }
     CloseHandle(hThread);
     t.Resume();
     Console.WriteLine("\nPress any key to end program\n");
     Console.ReadKey();
     }

     static void MyMethod()  
     {
     threadId = (uint)AppDomain.GetCurrentThreadId();
     Thread.Sleep(1000);
     }

}

Alternative Managed API:

Do you know one? Please contribute it!

Documentation