Each thread Kernel Object maintains a context structure, which stores the running state of the thread, so that the CPU can remember where the thread was last run and where it started to run, how is the internal data of this thread.
Information about the context structure is recorded in the Platform SDK documentation. This structure is related to the CPU. A specific CPU corresponds to a specific context structure.
The context structure document for x86 CPUs is as follows:
Typedef struct _ context {
//
// The flag values within this flag control the contents
// A context record.
//
// If the context record is used as an input parameter, then
// For each portion of the context record controlled by a flag
// Whose value is set, it is assumed that portion of
// Context record contains valid context. If the context record
// Is being used to modify a thread's context, only that
// Portion of the thread's context will be modified.
//
// If the context record is used as an in out parameter to capture
// The context of a thread, only those portions of the thread's
// Context corresponding to set flags will be returned.
//
// The context record is never used as an out only parameter.
//
DWORD contextflags;
//
// This section is specified/returned if context_debug_registers is
// Set in contextflags. Note that context_debug_registers is not
// Encoded ded in context_full.
//
DWORD dr0;
DWORD DR1;
DWORD DR2;
DWORD dr3;
DWORD dr6;
DWORD dr7;
//
// This section is specified/returned if
// Contextflags word contains the flag context_floating_point.
//
Floating_save_area floatsave;
//
// This section is specified/returned if
// Contextflags word contains the flag context_segments.
//
DWORD seggs;
DWORD segfs;
DWORD seges;
DWORD segds;
//
// This section is specified/returned if
// Contextflags word contains the flag context_integer.
//
Dword edi;
Dword esi;
Dword ebx;
DWORD edX;
DWORD ECx;
DWORD eax;
//
// This section is specified/returned if
// Contextflags word contains the flag context_control.
//
Dword ebp;
Dword eip;
DWORD segcs; // must be sanitized
DWORD eflags; // must be sanitized
Dword esp;
DWORD segss;
//
// This section is specified/returned if the contextflags word
// Contains the flag context_extended_registers.
// The format and contexts are processor specific
//
Byte extendedregisters [maximum_supported_extension];
} Context;
It can be seen that the context structure stores CPU-related information directly:
1. contextflags: this field needs to be set during query to indicate which other context structure fields are queried.
2. debug register group
3. floating_save_area floatsave -- floating point register
4. segment register
5. General Data Register (integer register) Group
6. control register group-storing base address pointers, stack pointers, and program counters such as CS, BP, and sp.
7. byte extendedregisters [maximum_supported_extension] -- display register group
Of course, you can query the content in the context structure. As described above, you can set the contextflags Field in the context to select the content to be queried:
1. context_debug_registers: query the mode register.
2. context_floating_point: Query floating point registers.
3. context_segments: Query segment registers
4. context_integer: Query common data registers
5. context_control: Query control register group
6. context_extended_registers, extended register group
After setting the contextflag field, you can call the getthreadcontext function to query related content in the context:
Bool getthreadcontext (
Handle hthread, // thread handle
Pcontext); // Context Structure pointer
Before querying, call the suspendthread function to pause the execution of a thread, and then call the getthreadcontext function to obtain the relevant content in the context structure.
The following code queries the control register group information of a thread:
Suspendthread (htherad); // The thread must be paused first
Context context;
Context. contextflags = context_control;
Getthreadcontext (hthread, & context );
You can call the setthreadcontext function to set the context structure of a thread.
Bool setthreadcontext (handle hthread, const context * pcontext );
Before calling this function, call the suspendthread function and set the contextflags field in context. However, setthreadcontext may cause memory access violations.
The following code demonstrates the basic steps for using setthreadcontext:
Context context;
Suspendthread (hthread); // The thread must be paused first.
Context. contextflags = context_control;
Getthreadcontext (hthread, & context); // obtain the context structure content first.
Context. EIP = 0x00010000; // set the address pointed to by the instruction pointer to 0x00010000
Context. contextflags = context_control; // reset contextflags
Setthreadcontext (hthread, & context); // you can specify the context structure.
Resumethread (hthread); // resume the thread running, which runs from the address 0x00010000