-
-
[原创]Windows内核逆向-----<KiSystemCall64>
-
2021-9-8 14:38
20494
-
[原创]Windows内核逆向-----<KiSystemCall64>
算是介绍
最近比较懒,已经摸鱼半个月了,以后会把学的东西整理下发出来,算是督促下自己吧,大概周更。主要是对Windows内核中函数的逆向。
应该会用到的东西:Win10_x64 + Windbg + IDA + Xp源代码 + Intel手册
垃圾二本 开学大三 水平有限 还请各位前辈多多指点
算是正文
先从进入内核开始
syscall
在R3使用的Windows API 函数 大多都要进入R0来完成核心工作,所以进入R0的动作也算频繁,因此 (也不一定因此)CPU提供一条指令来用于从用户态切换到内核态,如图
以下步骤在执行syscall指令时由CPU完成,是对上图的解释。
1.1)将RIP保存到RCX(因为完成API的功能后程序还是要正常执行的)并将RIP改成一个系统指定好的值(系统中所有线程执行syscall指令后都会跳转到这里执行,这也提供了一种HOOK方案,但不用VT分分钟PG)
1.2)将RFLAGS保存到R11,并参考一个MSR寄存器,改变RFLAGS的值(根据windbg读出来的值NT内核在执行syscall时 将 TF IF DF 位置零)
2)简单理解为更改了CPU当前特权级别,并强制平坦(就是弱化了段机制)
内核接管流程
新的RIP值指向内核层代码 符号名是 KiSystemCall64 (开启页表隔离后会是另一个),此段代码主要功能:
1.切换GS指向KPCR
2.将用户栈切换到内核栈
3.关闭SMAP使得可以在内核态访问用户态数据
4.一段神奇的代码,猜测是参考cpu特征解决下硬件漏洞
5.保存用户态线程上下文到_KTRAP_FRAME
6.根据eax算出用户指定的内核态例程地址(地址计算方法会在下文总结)
7.将用户栈上的参数复制到内核栈(算出复制代码执行地址)
8.调用内核函数
9.执行下用户态APC
10.将函数返回值写入_KTRAP_FRAME.RAX 恢复用户态上下文 使用sysret指令返回用户态执行
<<<<-------下文会根据这10步放上IDA截图,细节在IDA注释上补充------->>>>
个人感觉用图片表述更加直观
接管细节分析
下图主要做了 1 2 3 5步所述内容
下图主要做了 4 5 步所述内容,4步为个人推测,未经验证
下图主要做了 6 步所述内容
首先会根据线程特征选用不同的表
然后使用选出的表算出函数地址
下图表述了函数地址的计算方式
用Excel画图是真的累 ;(
CommonThread为普通线程用的表,GuiThread为GUI线程用的表,XX_EntryNumber为表中的偏移个数,ArgNumber为函数的参数个数,
下图主要做了 7 步所述内容
下图的代码主要用于复制参数,执行位置由上图代码算出
下图主要做了 8 步所述内容
下图主要做了 9 10 步所述内容
sysret
此指令用于从内核态返回用户态,过程可反向参考syscall,执行此指令后CPU回到用户特权级(R3)并执行用户层代码
算是废话
以前看一些帖子总觉得讲的不仔细,第一次自己写才知道,所有细节都写出来估计要累死。过两天开学了还要准备英语补考:(((((((((((((((想想都脑子疼。
下一篇逆一下内存或者线程切换相关的把,难免有错误还请大佬们多多指点
[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界
最后于 2021-9-8 19:30
被小白养的菜鸡编辑
,原因: 改一下...