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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

5.用户APC执行过程

發布時間:2025/3/20 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 5.用户APC执行过程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

當產生系統調用、中斷或者異常,線程在返回用戶空間前都會調用, _KiServiceExit函數,在_KiServiceExit會判斷是否有要執行的用戶APC,如果有則調用KiDeliverApc函數(第一個參數為1)進行處理。

執行用戶APC時的堆棧操作

處理用戶APC要比內核APC復雜的多,因為,用戶APC函數要在用戶空間執行的,這里涉及到大量換棧的操作:

當線程從用戶層進入內核層時,要保留原來的運行環境,比如各種寄存 囚器,棧的位置等等(_Trap_Frame),然后切換成內核的堆棧,如果正常返回, 您恢復堆棧環境即可。

但如果有用戶APC要執行的話,就意味著線程要提前返回到用戶空間去,執行,而且返回的位置不是線程進入內核時的位置,而是返回到其他的位置,每處理一個用戶APC都會涉及到:
內核->用戶空間->再回到內核空間

堆棧的操作比較復雜,如果不了解堆棧的操作細節不可能理解用戶APC是如何執行!

KiDeliverApc函數分析
無論是內核APC還是用戶APC首先執行的都是這個函數

  • 判斷用戶APC鏈表是否為空
  • 判斷第一個參數是為1
  • 判斷ApcState.UserApcPending是否為1
  • 將ApcState.UserApcPending設置為0
  • 鏈表操作將當前APC從用戶隊列中拆除
  • 調用函數(KAPC.KernelRoutine)釋放KAPC結構體內存空間
  • 調用KilnitializeUserApc函數

  • 取完內核APC后取用戶APC,然后判斷你用戶APC是不是空的,不為空就跳轉。

    KilnitializeUserApc函數分析:備份CONTEXT

    線程進0環時,原來的運行環境(寄存器棧頂等)保存到Trap_Frame結構體中,如果要提前返回3環去處理用戶APC,就必須要修改Trap _Frame結構體:

    比如:進0環時的位置存儲在EIP中,現在要提前返回,而且返回的并不,是原來的位置,那就意味著必須要修改EIP為新的返回位置。還有堆棧ESP也要修改為處理APC需要的堆棧。那原來的值怎么辦呢?處理完APC后該如何返回原來的, 位置呢?

    KilnitializeUserApc要做的第一件事就是備份:

    將原來Trap Frame的值備份到一個新的結構體中(CONTEXT),這個功能由其子函數KeContextFromKframes來完成。

    kd> dt _CONTEXT nt!_CONTEXT+0x000 ContextFlags : Uint4B+0x004 Dr0 : Uint4B+0x008 Dr1 : Uint4B+0x00c Dr2 : Uint4B+0x010 Dr3 : Uint4B+0x014 Dr6 : Uint4B+0x018 Dr7 : Uint4B+0x01c FloatSave : _FLOATING_SAVE_AREA+0x08c SegGs : Uint4B+0x090 SegFs : Uint4B+0x094 SegEs : Uint4B+0x098 SegDs : Uint4B+0x09c Edi : Uint4B+0x0a0 Esi : Uint4B+0x0a4 Ebx : Uint4B+0x0a8 Edx : Uint4B+0x0ac Ecx : Uint4B+0x0b0 Eax : Uint4B+0x0b4 Ebp : Uint4B+0x0b8 Eip : Uint4B+0x0bc SegCs : Uint4B+0x0c0 EFlags : Uint4B+0x0c4 Esp : Uint4B+0x0c8 SegSs : Uint4B+0x0cc ExtendedRegisters : [512] UChar

    0環備份的CONTEXT復制到3環堆棧

    APC要執行的4個值放到圖上面堆棧中



    1

    2.3.4



    ntdll.KiUserApcDispatcher分析

    1、當用戶在3環調用QueueUserAPC函數來插入APC時,不需要提供 NormalRoutine,這個參數是在QueueUserAPC內部指定的:
    BaseDispatchAPC

    2、 ZwContinue函數的意義:

  • 返回內核,如果還有用戶APC,重復上面的執行過程。
  • 如果沒有需要執行的用戶APC,會將CONTEXT賦值給Trap
    Frame結構體。就像從來沒有修改過一樣。ZwContinue后面的代碼不會執行,線程從哪里進0環仍然會從哪里回去。
  • 總結

  • 內核APC在線程切換時執行,不需要換棧,比較簡單,一個循環執行完畢。
  • 用戶APC在系統調用、中斷或異常返回3環前會進行判斷,如果有要執行的用戶APC,再執行。
  • 用戶APC執行前會先執行內核APC
  • 總結

    以上是生活随笔為你收集整理的5.用户APC执行过程的全部內容,希望文章能夠幫你解決所遇到的問題。

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