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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

Windows APC学习笔记(一)—— APC的本质备用APC队列

發布時間:2025/3/21 windows 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windows APC学习笔记(一)—— APC的本质备用APC队列 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Windows APC學習筆記(一)—— APC的本質&備用APC隊列

    • 基礎知識
    • APC的本質
      • APC隊列
      • APC結構
      • 分析 KiServiceExit
      • 總結
    • 備用APC隊列
      • 掛靠環境下ApcState的意義
      • ApcStatePointer
      • ApcStateIndex
      • 組合尋址
      • ApcQueueable

基礎知識

  • 線程是不能被“殺掉”、“掛起”、“恢復”的,線程在執行的時候自己占據著CPU,別人不能控制它
  • 舉個極端的例子:如果不調用API屏蔽中斷并保證代碼不出現異常,線程將永久占用CPU
  • 所以說線程如果想“死”,一定是自己執行代碼把自己殺死,不存在“他殺”的情況
  • 思考:那如果想改變一個線程的行為該怎么辦
    答案:可以給他提供一個函數,讓它自己去調用:APC(Asyncroneus Procedure Call,異步過程調用)

    APC的本質

    APC隊列

    在Windbg中查看


    ApcListHead:

  • 由兩個雙向鏈表組成,共占16個字節
  • 提供的APC函數可能是用戶函數,也可能是系統函數(簡單的區分方法就是判斷函數地址是否大于0x80000000
  • Process:指向線程所屬或者掛靠進程
    KernelApcInProgress:內核Apc是否正在執行
    KernelApcPending:是否存在等待狀態的內核APC,存在則置1
    UserApcPending:是否存在等待狀態的用戶APC,存在則置1

    APC結構

    在WinDbg中查看

    NormalRoutine:找到提供的APC函數,并不完全等于APC函數的地址,后續將重點學習

    分析 KiServiceExit

    總結

    如果我們想要改變一個線程,可以先提供一個APC,然后通過 _KAPC.NormalRoutine 指向我們提供的APC在哪里,再將APC存到 _KTHREAD.ApcState.ApcListHead 的第一個成員中

    思考:當前線程什么時候將會執行提供的APC
    答案

  • KiServiceExit 函數(系統調用異常中斷返回用戶控件的必經之路)
  • KiDeliverApc 函數(負責執行APC函數)
  • 備用APC隊列

    描述

  • _KTHREAD+0x14c 位置處,同樣也存在一個 _KAPC_STATE 結構體,叫做 SavedApcState
  • 線程APC隊列中的APC函數都是與進程相關聯的,具體點說:A進程的T線程中的所有APC函數,要訪問的內存地址都是A進程的
  • 但線程是可以掛靠到其他的進程:比如A進程的線程T,通過修改Cr3(改為B進程的頁目錄基址),就可以訪問B進程地址空間,即所謂“進程掛靠”
  • 當T線程掛靠B進程后,APC隊列中存儲的卻仍然是原來的APC。具體點說,比如某個APC函數要讀取一個地址為0x12345678的數據,如果此時進行讀取,讀到的將是B進程的地址空間,這樣邏輯就錯誤了
  • 為了避免混亂,在T線程掛靠B進程時,會將ApcState中的值暫時存儲到SavedApcState中,等回到原進程A時,再將APC隊列恢復。
  • 因此,SavedApcState又稱為備用APC隊列
  • 掛靠環境下ApcState的意義

    在掛靠的環境下,也是可以先線程APC隊列插入APC的

    A進程的T線程掛靠B進程 A是T的所屬進程 B是T的掛靠進程 ApcState B進程相關的APC函數 SavedApcState A進程相關的APC函數

    在正常情況下,當前進程就是所屬進程A,如果是掛靠情況下,當前進程就是掛靠進程B

    ApcStatePointer

    描述:為了操作方便,_KTHREAD 結構體中定義了一個指針數組 ApcStatePointer ,長度為2,位于 _KTHREAD+0x138

    正常情況下

    ApcStatePointer[0] 指向 ApcState
    ApcStatePointer[1] 指向 SavedApcState

    掛靠情況下

    ApcStatePointer[0] 指向 SavedApcState
    ApcStatePointer[1] 指向 ApcState

    ApcStateIndex

    描述ApcStateIndex 用來標識當前線程處于什么狀態,位于 _KTHREAD+0x165

    0:正常狀態
    1:掛靠狀態

    組合尋址

    正常情況下,向ApcState隊列中插入APC時:

    ApcStatePointer[0] 指向 ApcState,此時 ApcStateIndex 的值為 0
    ApcStatePointer[ApcStateIndex] 指向 ApcState

    掛靠情況下,向ApcState隊列中插入APC時:

    ApcStatePointer[1] 指向 ApcState,此時 ApcStateIndex 的值為 1
    ApcStatePointer[ApcStateIndex] 指向 ApcState

    總結

    無論什么環境下,ApcStatePointer[ApcStateIndex] 指向的都是 ApcState
    ApcState 總是表示線程當前使用的apc狀態

    ApcQueueable

    描述

  • 位于 _KTHREAD+0x166,表示是否可以向線程的APC隊列中插入APC
  • 當線程正在執行退出的代碼時,會將這個值設置為0 ,如果此時執行插入APC的代碼(KeInsertQueueApc),在插入函數中會判斷這個值的狀態,如果為0,則插入失敗
  • 總結

    以上是生活随笔為你收集整理的Windows APC学习笔记(一)—— APC的本质备用APC队列的全部內容,希望文章能夠幫你解決所遇到的問題。

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