糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > Windows APC学习笔记(一)—— APC的本质备用APC队列

Windows APC学习笔记(一)—— APC的本质备用APC队列

时间:2023-03-26 06:57:26

相关推荐

Windows APC学习笔记(一)—— APC的本质备用APC队列

Windows APC学习笔记(一)—— APC的本质&备用APC队列

基础知识APC的本质APC队列APC结构分析 KiServiceExit总结备用APC队列挂靠环境下ApcState的意义ApcStatePointerApcStateIndex组合寻址ApcQueueable

基础知识

线程是不能被“杀掉”、“挂起”、“恢复”的,线程在执行的时候自己占据着CPU,别人不能控制它举个极端的例子:如果不调用API屏蔽中断并保证代码不出现异常,线程将永久占用CPU所以说线程如果想“死”,一定是自己执行代码把自己杀死,不存在“他杀”的情况

思考:那如果想改变一个线程的行为该怎么办

答案:可以给他提供一个函数,让它自己去调用:APC(Asyncroneus Procedure Call,异步过程调用)

APC的本质

APC队列

在Windbg中查看

ApcListHead

由两个双向链表组成,共占16个字节提供的APC函数可能是用户函数,也可能是系统函数(简单的区分方法就是判断函数地址是否大于0x80000000

Process:指向线程所属或者挂靠进程

KernelApcInProgress:内核Apc是否正在执行

KernelApcPending:是否存在等待状态的内核APC,存在则置1

UserApcPending:是否存在等待状态的用户APC,存在则置1

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函数都是与进程相关联的,具体点说:A进程的T线程中的所有APC函数,要访问的内存地址都是A进程的但线程是可以挂靠到其他的进程:比如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函数SavedApcStateA进程相关的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当线程正在执行退出的代码时,会将这个值设置为0 ,如果此时执行插入APC的代码(KeInsertQueueApc),在插入函数中会判断这个值的状态,如果为0,则插入失败

如果觉得《Windows APC学习笔记(一)—— APC的本质备用APC队列》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。