内核篇-----备用APC

备用APC队列

Kd>dt _KTHREAD
Nt!_KTHREAD
+0x034 ApcState		:_KAPC_STATE
+0x138 ApcStatePointer:[2]Ptr32_KAPC_STATE
+0x14c SavedApcState	:_KAPC_STATE
+0x165 ApcStateIndex	:UChar
+0x166 ApcQueueable	:UChar
..

1.SavedApcState的意义:
A进程中的T线程中的所有APC函数,要访问的内存地址都是A进程的;
但是线程可以挂靠到其他进程,通过修改Cr3(该位B进程的页目录基址),就可以访问B进程地址空间,就是进程挂靠;
当T线程挂靠到B进程时,现在的APC队列任然是原来的APC,现在读取到的是B进程的地址空间;
为了避免麻烦,但T线程挂靠到B进程时,会将ApcState中的值暂时存储到SavedApcState中,等到放回A进程时,在恢复APC队列;
2.挂靠环境下ApcState的意义:在挂靠环境下插入Apc线程,插入位置还是ApcState,因为原来的APC已经备份到SavedApcState里了
3. ApcStatePoirter
这个函数是一个指针数组,长度为2;为了寻址方便;
正常情况下:

ApcStatePoirter[0]ApcState
ApcStatePoirter[1]SavedApcState
挂靠情况下:
ApcStatePoirter[0] SavedApcState
ApcStatePoirter [1] ApcState

4. ApcStateInder
用来标识当前线程处于什么状态
0 正常状态 1 挂靠状态
5.ApcStatePoired和ApcStateInder组合寻址
正常情况下,向ApcState里插入Apc
ApcStatePointer[0]ApcState ApcStateInder=0
挂靠情况下,向ApcState插入Apc
ApcStatePointer [1]ApcState ApcStateInder=1
总结
无论什么环境下,ApcStatePointer[ApcStateInder]都指向ApcState,ApcState则总表示线程当前使用的apc状态
6. ApcQueueable
用于表示是否可以向线程的APC队列插入APC
如果当前线程正在执行退出的代码时,会将这个值设置为0;如果执行插入APC代码(KeInserQueueApc),如果值为0,则插入失败;
Alertable属性说明(是否运行被APC吵醒)

kd>dt _KTHREAD
ntdll!_KTHREAD
	+0x164 Alertable	:UCher

当调用普通的SleepEx或者WaitForSingleObjectEx时,是不会修改Alertable的; 只有当Alertable是1时,才能使UserApcPenging=1,在唤醒APC;
那什么时候才会是1呢?
是只有当时用户层导致的等待状态
内核APC
执行点:1,线程切换时; 2,系统调用,中断,或者异常时由0环返回3环时
注2:只有存在用户APC要执行时,才能执行内核APC;
当要执行用户APC时,要先执行内核APC;
KiDeliverApc函数
无论要执行用户APC函数内核APC,都会执行这个函数;
执行流程:

总结:内核APC在线程切换时就会执行,只要插入内核APC就会立即执行;
在执行用户APC之前会先执行内核APC;
内核APC在内核空间执行,不需要换栈;

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Aaronpack

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值