2017-04-20 79 views

回答

0

APC只能从非分页池进行分配,因为APC可以插入(由KeInsertQueueAPC)在主题列表在DPC水平 - 因此,如果您例如分配KAPC从分页池,插入,然后有人尝试插入另一APC DPC水平 - 你的分页APC数据可分配(当插入到链表)和作为结果BSOD

的INI tialize KAPC使用KeInitializeApc。如果免费APC需要完全调用ExFreePool并没有什么可以使用0作为RundownRoutine。否则你必须提供自己的RundownRoutine进行正确的清理。 KernelRoutine总是必须设置,因为几乎总是指向驱动程序中的某些功能 - 驱动程序不能卸载,直到APC将不会执行。后KernelRoutineRundownRoutine通常需要调用ObfReferenceObject驾驶员对象插入APC之前KeInsertQueueAPCObfDereferenceObject将被执行(或KeInsertQueueAPC返回false)。但你不能“正常途径”呼ObfDereferenceObject - 这是毫无意义的(如果最后一个引用驾驶员保持 - 会当ObfDereferenceObject返回驱动程序代码,你需要汇编语言编写的代理从KernelRoutine崩溃和RundownRoutine。其中呼吁他们的C/C++实现,并在退出做JMP(但不呼叫 !!)指令ObfDereferenceObject和纸张都必须特别重建的后ObfDereferenceObject呼叫RET - 代码将返回到内核合作德,其调用你的驱动程序回调例程(内核或破败) - 所以跳过驱动程序代码执行后ObfDereferenceObject

更多细节 - 阅读Inside NT's Asynchronous Procedure Call - 尽管这已经是很老的文章 - 没有从这个时间和最新变化赢得10 - 全都一样