WindowsのAPCの研究ノート() - APC&APCバックアップキューの性質
序文
まず、から学ぶ
滴水编程达人
中級コース、官网:https://bcdaren.com
2、ハイトン教師岩!
基本
- スレッドが「することはできません殺した」、「一時停止」、「履歴書」、自分自身の実装でスレッドがCPUを占有し、他の人が行う方法を制御することは可能でしょうか?
- 極端な例を与えるために:あなたがいる場合API呼び出すことはありません、マスカブル割り込みを、そしてコードが異常な表示されないことを保証するために、スレッドがします恒久的に CPUを占有するので、それが何を制御していますか?
- ですから、「死んだ」スレッドにしたい自分を殺すためにコードを実行されていなければならない場合、状況は「殺人」であるが存在しません
思考:あなたがそれを行う方法のスレッドの動作を変更したい場合はどう?
答えは:あなたは彼に機能を提供することができる、それがコールを手放すAPC(Asyncroneusプロシージャ・コール、非同期プロシージャコール)
APCの自然
APCキュー
Windbgの中で確認してください:
ApcListHead
:
- 16バイトの総数を表す2つの二重にリンクされたリストから構成される
- APC機能によって提供されているユーザ機能は、とすることができるシステムの機能(シンプル区別関数はアドレスよりも大きいか否かを判断することでは0x80000000)
Process
:スレッドがポイントまたは提携プロセスを所属
KernelApcInProgress
:のApcカーネルが実行している
KernelApcPending
:の待機状態があり、カーネルAPCが、そこには、その後、1に設定されている
UserApcPending
:の待機状態あり、ユーザAPCは、セットがあります
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機能をスレッドが、プロセスに関連付けられている、ことを特定ポイント:すべてのAPC機能Tをアクセスするプロセスのメモリアドレスをスレッド処理であります
- しかし、スレッドが他のプロセスにリンクすることができます。たとえば、プロセス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
- コードは、スレッドが終了を実行しているとき、このタイムコード挿入APC(であれば、この値は、0に設定されKeInsertQueueApcが0である場合)、挿入機能は、状態の値を決定し、挿入が失敗しました