Windows線程的上下文結構體(線程本質)

Windows線程的上下文結構體,struct _CONTEXT結構是與CPU有關的,特定的CPU對應着特定的CONTEXT結構。ide

線程上下文結構體

x86類型CPU對應的CONTEXT結構文檔以下:線程

typedef struct _CONTEXT {
    DWORD ContextFlags; //在查詢的時候須要設置該字段,表示查詢哪些其餘的CONTEXT結構字段。

    //調試寄存器組
    DWORD   Dr0;
    DWORD   Dr1;
    DWORD   Dr2;
    DWORD   Dr3;
    DWORD   Dr6;
    DWORD   Dr7;

    FLOATING_SAVE_AREA FloatSave; //浮點寄存器

    //段寄存器組
    DWORD   SegGs;
    DWORD   SegFs;
    DWORD   SegEs;
    DWORD   SegDs;

    //通用數據寄存器(整型寄存器)組
    DWORD   Edi;
    DWORD   Esi;
    DWORD   Ebx;
    DWORD   Edx;
    DWORD   Ecx;
    DWORD   Eax;

    //控制寄存器組——好比CS、BP、SP之類的保存基址指針和堆棧指針、程序計數器
    DWORD   Ebp;
    DWORD   Eip;
    DWORD   SegCs;              // MUST BE SANITIZED
    DWORD   EFlags;             // MUST BE SANITIZED
    DWORD   Esp;
    DWORD   SegSs;

    BYTE    ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION]; //擴展寄存器組
} CONTEXT;

獲取和設置線程上下文結構體

獲取CONTEXT,必須先掛起線程(使用API:SuspendThread),不然取到的CONTEXT無心義。而後經過API:GetThreadContext獲取線程CONTEXT。指針

代碼片斷:
CONTEXT Context;
SuspendThread(hThread);//掛起線程
Context.ContextFlags = CONTEXT_CONTROL;
GetThreadContext(hThread, &Context);//獲取線程Context
Context.Eip = 0x00010000;//修改EIP,也就是修改了當前執行的代碼,後續線程激活後,會在這個地址繼續執行(這個地址是爲了演示隨意填寫的,因爲這個地址問題,程序可能會崩潰)  
Context.ContextFlags = CONTEXT_CONTROL;     
SetThreadContext(hThread, &Context);//設置線程Context    
ResumeThread(hThread);//恢復線程運行,此時程序從0x00010000地址處開始運行,程序會異常

線程本質解析

  • 經過這裏咱們就知道,線程的本質也是一個結構體,只是在高2g的內存中(內核空間中),咱們沒法直接訪問,可是能夠經過系統調用訪問。調試

  • 那麼線程調度,本質就是修改線程CONTEXT的EIP,也就是eip,當20毫秒的時間片用完時,切換到其它線程
相關文章
相關標籤/搜索