(49)逆向分析KiSystemService/KiFastCallEntry调用内核函数部分(SST,SSDT,SSPT)
一、回顾
前两篇博客,我逆向分析了 KiSystemService 和 KiFastCallEntry 填充_KTRAP_FRAME 结构体的代码,二者大同小异,主要的区别是 sysenter 只改了eip,cs,ss,虽然esp也改了,但是windows不使用,而是从TSS里取esp0;另外sysenter并没有像中断门那样压栈,所以3环的 ss, esp, eflags, cs,eip都要在函数里依次保存到 _KTRAP_FRAME 。
这次课后作业是逆向 KiSystemService / KiFastCallEntry 调用内核函数部分,放在一块讲是因为这两个函数虽然入口不同,但是填充完 _KTRAP_FRAME 后,就会执行相同的代码。他们两个函数就像两头蛇一样,有两个入口,初始化的工作有区别,但是往后就共用一个函数体。
在逆向之前,先介绍所需的前置知识。同时,思考两个问题:
- 如何根据系统服务号(eax中存储)找到要执行的内核函数?
- 调用时参数是存储到3环的堆栈,如何传递给内核函数?
二、SystemServiceTable 系统服务表SST
SST:系统服务表
SSDT:系统服务调度表
SSPT:系统服务参数表
关系:
首先强调,SystemServiceTable 系统服务表不是SSDT。
看示意图:
通过此图,我们可以得知以下信息:
- 通过 _KTHREAD 可以找到系统服务表
- 系统服务表又指向了函数地址表和函数参数表
- 有两张系统服务表,第一张是用来找内核函数的,第二张是找Win32k.sys驱动函数的。
通过逆向,我们还可以判定,其实两张系统服务表是线性地址连续的,每张16字节。
说明一下表的4个属性:
ServiceTable 指向函数地址表,Count没有用,ArgmentTable 指向函数参数表,ServiceLimit 是这两张表的长度。
要注意函数参数表每项存储的是对应函数参数占的字节数,每项只有1字节。 这个在逆向中也可以验证。
最后补充一点,我们之前逆向API三环部分时,它进0环之前,无论是中断门还是快速调用,都会在 eax 里存一个值,我们称之为系统调用号或者服务号,这个东西的低12位就是函数参数表和函数地址表的下标,而第13位(下标12)如果是0,表示找第一张系统服务表(绿色的表),如果是1,那么找第二张表(黄色的表)。这点可以先记住,待会逆向的时候可以印证这个结论。
三、逆向分析 KiSystemService / KiFastCallEntry 调用内核函数部分
从Kernel32.dll中的某个函数开始分析其执行流程(怎么找到对应的内核函数 怎么找到参数 如何将参数传递到0环)
这是作业要求,我这里就只贴了0环逆向部分,至于3环那些,我在之前的博客已经详细分析了,有需要可以查看前面的博客。
直接贴结果了,比较简单,看注释就能看懂了。
.text:004665CD loc_4665CD: ; CODE XREF: _KiBBTUnexpectedRange+18j
.text:004665CD ; _KiSystemService+6Fj
.text:004665CD mov edi, eax ; 这里是 KiSystemService 和 KiFastCallEntry 的汇合处
.text:004665CD ; edi = eax = 系统调用号
.text:004665CF shr edi, 8
.text:004665D2 and edi, 30h ; 检测系统调用号12位
.text:004665D2 ; 如果等于1,那么 edi == 0x10
.text:004665D2 ; 如果等于0,那么 edi == 0x00
.text:004665D5 mov ecx, edi
.text:004665D7 add edi, [esi+0E0h] ; edi += CurrentThread.ServiceTable
.text:004665D7 ; 此时 edi 指向了API对应的系统服务表
.text:004665D7 ;
.text:004665D7 ; 他这个设计 0x10 刚好是系统服务表的大小
.text:004665D7 ; 系统服务表有 ServiceTable, Count, ServiceLimit 和 ArgmentTable
.text:004665D7 ; 4项共0x10字节,所以通过这里的代码也可以推断,内核和win32k.sys的系统服务表是连续的
.text:004665D7 ; 第一张是内核的,第二张是win32k.sys的
.text:004665DD mov ebx, eax ; ebx = 系统调用号
.text:004665DF and eax, 0FFFh ; eax = 系统服务表下标
.text:004665E4 cmp eax, [edi+8]
.text:004665E7 jnb _KiBBTUnexpectedRange ; 检查系统调用号是否超过系统服务表的范围,超过就跳到异常处理
.text:004665ED cmp ecx, 10h
.text:004665F0 jnz short loc_46660C ; 跳转条件:系统服务(ntdll.dll 的API)
.text:004665F0 ; 不跳转条件:图形及用户界面(gdi.dll 的API)
.text:004665F2 mov ecx, ds:0FFDFF018h ; ecx 指向 _KPCR
.text:004665F8 xor ebx, ebx
.text:004665FA
.text:004665FA loc_4665FA: ; DATA XREF: _KiTrap0E+113o
.text:004665FA or ebx, [ecx+0F70h]
.text:00466600 jz short loc_46660C
.text:00466602 push edx
.text:00466603 push eax
.text:00466604 call ds:_KeGdiFlushUserBatch
.text:0046660A pop eax
.text:0046660B pop edx
.text:0046660C
.text:0046660C loc_46660C: ; CODE XREF: _KiSystemService+16Fj
.text:0046660C ; _KiSystemService+17Fj
.text:0046660C inc dword ptr ds:0FFDFF638h ; _KCPR.KPRCB.KeSystemCalls += 1, 系统调用计数加1
.text:00466612 mov esi, edx ; esi = edx = 3环参数指针
.text:00466614 mov ebx, [edi+0Ch] ; edi 指向系统服务表
.text:00466614 ; ebx 指向函数参数表
.text:00466614 ; eax 是系统服务表下标
.text:00466617 xor ecx, ecx
.text:00466619 mov cl, [eax+ebx] ; cl = 参数字节数
.text:0046661C mov edi, [edi] ; edi 指向函数地址表
.text:0046661E mov ebx, [edi+eax*4] ; ebx 指向函数
.text:00466621 sub esp, ecx ; 从这句开始,到call为止,完成了复制3环参数的工作
.text:00466621 ; 这句是模拟压栈操作
.text:00466623 shr ecx, 2 ; 参数字节数 / 4,得到参数个数
.text:00466626 mov edi, esp
.text:00466628 cmp esi, ds:_MmUserProbeAddress ; 越界检查
.text:00466628 ; 如果 esi(3环参数指针)大于等于 0x7fff0000,则返回 c0000005 异常
.text:0046662E jnb loc_4667DC
.text:00466634
.text:00466634 loc_466634: ; CODE XREF: _KiSystemService+35Fj
.text:00466634 ; DATA XREF: _KiTrap0E+109o
.text:00466634 rep movsd ; 复制参数:复制 esi 到 edi,每次复制4字节,次数由 ecx 决定
.text:00466634 ; 方向由DF决定,DF=0,故每次复制后,edi 和 esi 都加4
.text:00466636 call ebx ; 调用内核函数
至此,系统调用过程,除了0环返回3环(涉及APC知识),我们都已经分析完成了。
(49)逆向分析KiSystemService/KiFastCallEntry调用内核函数部分(SST,SSDT,SSPT)相关推荐
- (47)逆向分析 KiSystemService 函数填充 _KTRAP_FRAME 部分
一.回顾 之前的课程,我们学习了API系统调用在3环部分做的事情,有两种方式进0环,分别是中断门和快速调用,分别调用两个不同的函数 KiSystemService 和 KiFastCallEntry. ...
- linux应用调用内核函数,Hooking linux内核函数(一):寻找完美解决方案
前言 我们最近参与了一个Linux系统安全相关项目,需要hooking几个重要的Linux内核函数调用,例如打开文件和启动进程,并利用它来启用系统活动监控并抢先阻止可疑进程. 最后,我们发明了一种有效 ...
- Linux驱动小技巧 | 利用DRIVER_ATTR实现调用内核函数
1. 前言 很多朋友在调试驱动的时候,都会遇到这样一个场景:修改一个参数,然后调用某个内核中的函数. 比如将某个gpio的值拉高/拉低,修改某个寄存器的值等等. 如果每一个参数都通过字符设备的ioct ...
- (48)逆向分析 KiFastCallEntry 函数填充 _KTRAP_FRAME 部分
一.回顾 上一篇博客我逆向了 KiSystemService 函数填充 _KTRAP_FRAME 部分. 逆向分析 KiSystemService 函数填充 _KTRAP_FRAME 部分 里面涉及了 ...
- PyCUDA内核函数
元素级内核函数 import pycuda.gpuarray as gpuarray import pycuda.driver as drv from pycuda.elementwise impor ...
- 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 远程调用 目标进程中 libc.so 动态库中的 mmap 函数 二 | 准备参数 | 远程调用 mmap 函数 )
文章目录 一.准备 mmap 函数的参数 二.mmap 函数远程调用 一.准备 mmap 函数的参数 上一篇博客 [Android 逆向]Android 进程注入工具开发 ( 注入代码分析 | 远程调 ...
- 系统调用002 KiSystemService函数逆向分析
文章目录 前言 保存现场 _KTRAP_FRAME KRPC ExceptionList _KTHREAD结构体 先前模式 抬高堆栈 判断当前权限 更新_KTRAP_FRAME 保存三环的寄存器环境 ...
- 【Android 逆向】整体加固脱壳 ( DEX 优化流程分析 | DexPrepare.cpp 中 dvmContinueOptimizati() 函数分析 )
文章目录 前言 一.DexPrepare.cpp 中 dvmContinueOptimizati() 方法分析 前言 上一篇博客 [Android 逆向]整体加固脱壳 ( DEX 优化流程分析 | D ...
- 【Android 逆向】函数拦截原理 ( 通过修改 GOT 全局偏移表拦截函数 | 通过在实际被调用的函数中添加跳转代码实现函数拦截 )
文章目录 一.通过修改 GOT 全局偏移表拦截函数 二.通过在实际被调用的函数中添加跳转代码实现函数拦截 一.通过修改 GOT 全局偏移表拦截函数 使用 GOT 全局偏移表 拦截函数 , 只需要将 G ...
最新文章
- 对口令协议的几种攻击方式
- 笔记2 自定义文件上传
- HPAIC人类蛋白质图谱分类挑战赛金牌经验分享
- ADSL断流问题分析
- .NET Core 3.0 部署在docker上运行
- (二)注册服务提供者
- 【Linux】字符转换命令join
- 技术圈儿002---高并发整体可用性:一文详解降级、限流和熔断
- ipad中的active失效?
- vivado2018.3根据板卡Boards直接创建工程(比如basys3和Arty A7)
- JS开发工具WebStorm使用快捷键
- 图片转文字,手机摇身一变就是万能扫描仪!
- ssm大型分布式商城项目实战视频教程下载java分布式开发教程
- Unity笔记-29-ARPG游戏项目-03-攀爬系统
- 小程序开发工具绑定服务器,微信小程序绑定到第三方平台流程
- 前端练习——弹窗、判断语句 (星座测试)
- Qt入门-QLabel类
- Vue+高德地图API的使用(插件的使用)
- 将一根木棍分成三段,求这三段构成三角形的概率
- 文献—Emergent simplicity in microbial community assembly--论文全过程详细阅读整理与翻译
热门文章
- 成功解决TypeError: ‘tuple‘ object is not callable
- Py之pandas:对dataframe型数据排序相关的问题总结之按照多个字段的多个条件进行排序(先打乱再排序)
- VM:如何向vmware虚拟机中传输文件(或者共享文件夹)之详细攻略(图文教程)
- DL之DNN优化技术:自定义MultiLayerNetExtend算法(BN层使用/不使用+权重初始值不同)对Mnist数据集训练评估学习过程
- MAT之NN:实现BP神经网络的回归拟合,基于近红外光谱的汽油辛烷值含量预测结果对比
- Anaconda多环境多版本python配置指导
- 《疯狂Java讲义》10
- SQLServer之分离数据库
- Help:立体图绘制以及根据X,Y,Z三坐标值,在图上描点
- 人的执念真的是非常的可怕