1.APC机制
線程是不能被“殺掉”、“掛起”、“恢復”的,線程在執行的時候自己占據著CPU,別人怎么可能控制它呢?
舉個極端的例子:如果不調用API,屏蔽中斷,并保證代碼不出現異常,線程將永久占用CPU,何談控制呢?所以說線程如果想“死",一定是自己執行代碼把自己殺死,不存在“他殺”這種情況!
那如果想改變一個線程的行為該怎么辦呢?
可以給他提供一個函數,讓它自己去調用,這個函數就是APC (Asyncroneus Procedure Call),即異步過程調用。
APC隊列
kd> dt KTHREADnt! KTHREAD...+0x034 ApcState _KAPC_STATE... kd> dt _kapc_state nt!_KAPC_STATE+0x000 ApcListHead //2個APC隊列用戶APC和內核APC+0x010 Process //線程所屬或者所掛靠的進程_KPROCESS+0x014 KernelApcInProgress //內核APC是否正在執行+0x015 KernelApcPending //是否有正在等待執行的內核APC 1=有+0x016 UserApcPending //是否有正在等待執行的用戶APC 1=有用戶APC: APC函數地址位于用戶空間,在用戶空間執行
內核APC: APC函數地址位于內核空間,在內核空間執行
+0x01c NormalRoutine 可以找到你提供APC函數在哪,并不完全等于APC函數的地址
如果我想改變一個線程:
當前的線程什么時候會執行我們提供的這些APC函數?
判斷是否有APC要執行
如果有APC
處理apc函數KiDeliverApc,這里我門發現只有用戶的apc,其實內核的apc是一定會處理的它會先處理內核apc在處理用戶的apc。
KiServiceExit函數:
這個函數是系統調用、異常或中斷返回用戶空間的必經之路。
KiDeliverApc函數:
負責執行APC函數
總結
- 上一篇: 13.跨进程读写内存
- 下一篇: 2.备用APC队列