日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

浅议APC

發布時間:2023/12/15 综合教程 34 生活家
生活随笔 收集整理的這篇文章主要介紹了 浅议APC 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

0x01 APC中斷請求級別

   在Intel x86體系結構中,外部硬件中斷是通過處理器上的"中斷管腳"或者一個稱為"本地APIC(local APIC)"的內置模塊來發生的。本地APIC可以接收的中斷源包括:  

  

    1處理器管腳(LINT0和LINT1)

    2本地APIC定時器(timer)

    3性能監視計數器中斷

    4熱傳感器中斷

    5 APIC內部錯誤中斷

  

  APIC這個硬件中斷設備是有優先級的,它使用了一個可編程陣列硬件來實現,并且在系統初始化的時候就完成了,Intel x86定義了256個中斷向量號(Interrupt Vector Number),也稱為中斷向量,從0~255。這就對應了IDT中斷描述符表,IDT的表項數目就是256,也就是說,APIC定義的是IDT中的中斷例程的優先級

  對于一個處理器,它一旦被中斷(可能來自內部,可能來自外部,可能是硬中斷,可能是軟中斷),則某個預設的"中斷服務例程"便被執行。而系統軟件(操作系統)要做的事情就是,提供這些例程,并將它們設定到處理器的硬件中斷向量表(即IDT)中。

  然而盡管APIC中斷控制器已經提供了中斷優先級支持,windows還是自己定義了一套優先級方案,稱為"中斷請求級別(IRPL Interrupt Request Level)"。在Intel x86系統中,windows使用了0~31來表示優先級,數值越大,優先級越高。內核為軟件中斷定義了一組標準的IRQL,而HAL則將硬件中斷號映射為IRQL。

  IRQL的宏定義:

#define PASSIVE_LEVEL 0        //Passive release level(被動級別)
#define LOW_LEVEL 0        //Lowest interrupt level
#define APC_LEVEL 1        //APC interrupt level
#define DISPATCH_LEVEL 2    //Dispatcher level
#define PROFILE_LEVEL 27    //Timer used for profiling
#define CLOCK1_LEVEL 28        //Interval clock 1 level
#define CLOCK2_LEVEL 28        //Interval clock 2 level
#define IPI_LEVEL 29        //Interprocessor interrupt level
#define POWER_LEVEL 30        //Power failure level
#define HIGH_LEVEL 31        //Highest interrupt level

  對于IRQL,PASSIVE_LEVEL(被動級別)代表了最低的IRQL,那既然你最低,運行在PASSIVE_LEVEL的線程可以被任何更高的IRQL(從LOW_LEVEL開始都可以)的事情打斷,所有的的用戶模式代碼都運行在PASSIVE_LEVEL(被動模式)上。而APC_LEVEL(APC級別)比PASSIVE_LEVEL高,這也正是在一個線程中插入一個APC可以打斷該線程(如果被插入的這個線程正在PASSIVE_LEVEL上運行)的原因(APC注入的原理)。

  

  

  APC_LEVEL位于PASSIVE_LEVEL和DISPATCH_LEVEL之間,這是"專門"為另一種稱為APC(異步過程調用 Asynchronous Procedure Call)的"軟件中斷"而保留的IRQL。每個APC都是在特定的線程環境中執行的,從而也一定在特定的進程環境中執行。APC是針對線程的,每個線程都有自己特有的APC鏈表。同一個線程的APC也是被排隊執行的(思考線程的IRP對清隊列,我們的IO請求要被排隊執行,APC作為IRP請求的一種也不例外)。

  由于APC的IRQL高于PASSIVE_LEVEL,所以,它優先于普通的"線程代碼"。當一個線程獲得控制時,它的APC進程會立刻被執行(即執行APC隊列中的IRP請求)。這一特性使得APC非常適合于實現各種異步通知事件。例如,I/O完成通知可以用APC來實現。

  (詳細內容見《windows內核原理與實現》第5章2.6節)

0x02 APC結構

  APC是與線程相關的,在描述線程的結構KTHREAD中,可以看到很多帶APC字眼的成員。

win7   32:

kd> dt _kthread
dtx is unsupported for this scenario.  It only recognizes dtx [<type>] [<address>] with -a, -h, and -r.  Reverting to dt.
ntdll!_KTHREAD
   +0x000 Header           : _DISPATCHER_HEADER
   +0x010 CycleTime        : Uint8B
   +0x018 HighCycleTime    : Uint4B
   +0x020 QuantumTarget    : Uint8B
   +0x028 InitialStack     : Ptr32 Void
   +0x02c StackLimit       : Ptr32 Void
   +0x030 KernelStack      : Ptr32 Void
   +0x034 ThreadLock       : Uint4B
   +0x038 WaitRegister     : _KWAIT_STATUS_REGISTER
   +0x039 Running          : UChar
   +0x03a Alerted          : [2] UChar
   +0x03c KernelStackResident : Pos 0, 1 Bit
   +0x03c ReadyTransition  : Pos 1, 1 Bit
   +0x03c ProcessReadyQueue : Pos 2, 1 Bit
   +0x03c WaitNext         : Pos 3, 1 Bit
   +0x03c SystemAffinityActive : Pos 4, 1 Bit
   +0x03c Alertable        : Pos 5, 1 Bit
 ……
   +0x040 ApcState         : _KAPC_STATE
……
   +0x168 ApcStatePointer  : [2] Ptr32 _KAPC_STATE
   +0x170 SavedApcState    : _KAPC_STATE
    ……

  可以看到在win7的32位下,與kthread偏移為0x40和0x170處,有兩個成員:ApcState和SavedApcState,這兩個成員指向兩個不同的_KAPC_STATE結構:

typedef struct _KAPC_STATE {
        LIST_ENTRY ApcListHead[MaximumMode];       //線程的apc鏈表 只有兩個 內核態和用戶態
        struct _KPROCESS *Process;                 //當前線程的進程體   PsGetCurrentProcess()
        BOOLEAN KernelApcInProgress;              //內核APC正在執行
        BOOLEAN KernelApcPending;                 //內核APC正在等待執行
        BOOLEAN UserApcPending;                  //用戶APC正在等待執行
} KAPC_STATE, *PKAPC_STATE, *PRKAPC_STATE;

  在_KAPC_STATE結構中,第一個成員為ApcListHead[2],第一個成員指向一個用戶模式APC鏈表,而第二個成員指向內核模式APC鏈表。如果注意觀察,可以看出特殊內核模式APC都排在普通內核模式APC之前。

  (圖片源自危險漫步:http://www.weixianmanbu.com/article/33.html)

  

  APC結構:

//win7 32
kd> dt _kapc
dtx is unsupported for this scenario.  It only recognizes dtx [<type>] [<address>] with -a, -h, and -r.  Reverting to dt.
ntdll!_KAPC
   +0x000 Type             : UChar
   +0x001 SpareByte0       : UChar
   +0x002 Size             : UChar
   +0x003 SpareByte1       : UChar
   +0x004 SpareLong0       : Uint4B
   +0x008 Thread           : Ptr64 _KTHREAD
   +0x010 ApcListEntry     : _LIST_ENTRY
   +0x020 KernelRoutine    : Ptr64     void 
   +0x028 RundownRoutine   : Ptr64     void 
   +0x030 NormalRoutine    : Ptr64     void 
   +0x038 NormalContext    : Ptr64 Void
   +0x040 SystemArgument1  : Ptr64 Void
   +0x048 SystemArgument2  : Ptr64 Void
   +0x050 ApcStateIndex    : Char
   +0x051 ApcMode          : Char
   +0x052 Inserted         : UChar

  

  在 KAPC 結 構 中 , Type 域 應 為 KOBJECTS 枚 舉 類 型 的 ApcObJect; Size 域 等 于 KAPC結 構 的 大 小 ; Thread 域 指 向 此 APC 對 象 所 在 的 線 程 KTHREAD 對 象 ; ApcListEntry 域 是APC 對 象 被 加 人 到 線 程 APC 鏈 表 中 的 節 點 對 象 ; KernelRoutine 域 是 一 個函 數 指 針 , 該 函數 將 在 內 核 模 式 的 APC-LEVEL 上 被 執 行 ; RundownRoutine 域 也 是 一 個 函 數 指 針 , 當 一個 線 程 終 止 時 如 果 它 的 APC 鏈 表 中 還 有 APC 對 象 , 那 么 , 若 成 員 非 空 ,則 調 用 它 所 指 的 函 數 。 № rmalRoutine 域 指 向 一 個 在 PASSIVE-LEVEL 上 執 行 的 函 數 。 在

這 三 個 函 數 指 針 成 員 中 , 只 有 KernelRoutine 是 必 需 的 , RundownRoutine 和 NormalRoutine都 是 可 選 的 。 而 且 , 如 果 NormalRoutine 為 空 的 話 , 則 其 后 的 Norma ℃ ontext 和 ApcMode域 也 將 被 忽 略 , 本 節 稍 后 會 解 釋 這 三 個 域 的 關 系 。 SystemArgumentl 和 SystemArgument2是 兩 個 提 供 給 KernelRoutine 或 NormalRoutine 函 數 的 參 數 。 ApcStateIndex 域 說 明 了 APC對 象 的 環 境 狀 態 , 它 是 KAPC ENVIRONMENT 枚 舉 類 型 的 成 員 , 一 旦 APC 對 象 被 插 人到 線 程 的 APC 鏈 表 中 , 則 ApcStatelndex 域 指 示 了 它 位 于 線 程 KTHREAD 對 象 的 哪 個 APC鏈 表 中 。 最 后 , 布 爾 類 型 Inserted 域 指 示 該 APC 對 象 是 否 已 被 插 人 到 線 程 的 APC 鏈 表 中。

  提煉幾點關鍵:

  1.如果mode為UserMode,但是NormalRoutine為NULL,那么實際的模式變為Kernelmode,因為沒有用戶空間的APC例程可以使用;

  2.每種APC都有內核模式的例程;

  3.特殊的內核模式APC與普通的內核模式APC區別在于Normalroutine是否為空;

  4.當普通的內核模式APC例程被執行時,先執行KernelRoutine例程,再執行NormalRoutine例程(除非執行過KernelRoutine例程后,NormalRoutine例程被清除為NULL)。

  APC可以分成三種:用戶模式APC、普通的內核模式APC,特殊的內核模式APC

  (圖片源自危險漫步:http://www.weixianmanbu.com/article/33.html)

  

總結

以上是生活随笔為你收集整理的浅议APC的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。