WindowsのAPCの研究ノート() - APC&APCバックアップキューの性質

序文

まず、から学ぶ滴水编程达人中級コース、官网:https://bcdaren.com
2、ハイトン教師岩!

基本

  1. スレッドが「することはできません殺した」、「一時停止」、「履歴書」、自分自身の実装でスレッドがCPUを占有し、他の人が行う方法を制御することは可能でしょうか?
  2. 極端な例を与えるために:あなたがいる場合API呼び出すことはありませんマスカブル割り込みをそしてコードが異常な表示されないことを保証するために、スレッドがします恒久的に CPUを占有するので、それが何を制御していますか?
  3. ですから、「死んだ」スレッドにしたい自分を殺すためにコードを実行されていなければならない場合、状況は「殺人」であるが存在しません

思考:あなたがそれを行う方法のスレッドの動作を変更したい場合はどう?
答えは:あなたは彼に機能を提供することができる、それがコールを手放すAPC(Asyncroneusプロシージャ・コール、非同期プロシージャコール)

APCの自然

APCキュー

Windbgの中で確認してください
ここに画像を挿入説明
ここに画像を挿入説明
ApcListHead

  1. 16バイトの総数を表す2つの二重にリンクされたリストから構成される
  2. APC機能によって提供されているユーザ機能は、とすることができるシステムの機能(シンプル区別関数はアドレスよりも大きいか否かを判断することでは0x80000000

Process:スレッドがポイントまたは提携プロセスを所属
KernelApcInProgress:のApcカーネルが実行している
KernelApcPending:の待機状態があり、カーネルAPCが、そこには、その後、1に設定されている
UserApcPending:の待機状態あり、ユーザAPCは、セットがあります

APC構造

WinDbgをチェックイン
ここに画像を挿入説明
NormalRoutineAPC、APCが提供する検索機能が正確に関数のアドレスに等しくない、フォローアップは、学習に焦点を当てます

分析KiServiceExit

ここに画像を挿入説明

概要

我々はスレッドを変更したい場合は、APCを提供し、それまでにすることができ_KAPC.NormalRoutine、我々はAPC、APCを提供どこを指して、その後に保存_KTHREAD.ApcState.ApcListHeadの最初のメンバー

思考:APCが提供された場合、現在のスレッドが実行されます
答えを

  1. KiServiceExit機能(システムコール例外割り込みを返すユーザーコントロールの唯一の方法)
  2. KiDeliverApc(責任機能の実装 APC機能)

APCバックアップキュー

説明

  1. _KTHREAD +の0x14cの位置も存在_KAPC_STATEの構造と呼ばれるSavedApcState
  2. キューにAPC APC機能をスレッドが、プロセスに関連付けられている、ことを特定ポイント:すべてのAPC機能Tをアクセスするプロセスのメモリアドレスをスレッド処理であります
  3. しかし、スレッドが他のプロセスにリンクすることができます。たとえば、プロセスAスレッドTは、のCr3(読み取りページディレクトリベースBプロセス)を変更することによって、あなたは、プロセスのアドレス空間Bにアクセスすることができ、いわゆる「プロセスは、アンカー」
  4. 当T线程挂靠B进程后,APC队列中存储的却仍然是原来的APC。具体点说,比如某个APC函数要读取一个地址为0x12345678的数据,如果此时进行读取,读到的将是B进程的地址空间,这样逻辑就错误了
  5. 为了避免混乱,在T线程挂靠B进程时,会将ApcState中的值暂时存储到SavedApcState中,等回到原进程A时,再将APC队列恢复。
  6. 因此,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

描述

  1. 位于 _KTHREAD+0x166,表示是否可以向线程的APC队列中插入APC
  2. コードは、スレッドが終了を実行しているとき、このタイムコード挿入APC(であれば、この値は、0に設定されKeInsertQueueApcが0である場合)、挿入機能は、状態の値を決定し、挿入が失敗しました
公開された45元の記事 ウォンの賞賛2 ビュー1807

おすすめ

転載: blog.csdn.net/qq_41988448/article/details/103609068