————————————————————————————————————————————————————————————————

在上风华正茂篇小说中,我们早就阅览IopParseDevice() 怎样对传播的 OPEN_PACKET 结构进行验证。假若ObReferenceObjectByName() 的调用者未有分配并起初化第多少个参数
ParseContext,而仅是粗略地扩散 “NULL” ,那么当调用链深刻到
IopParseDevice()
内部时,就能够因验证战败再次来到 C0000024(STATUS_OBJECT_TYPE_MISMATCH)。

咱俩依据源码中的暗暗提示来跟踪OPEN_PACKET 结构究竟在哪分配的,如前所述,调用链
NtCreateFile->IoCreateFile()->IopCreateFile() 的终极,也正是在
IopCreateFile() 内部,实际担负 OPEN_PACKET
的起先化。上面贴出的代码片段以 NT 5.2 版内核源码为样例:

 

图片 1

也正是说,我们直接复制
IopCreateFile() 中的 OPEN_PACKET 结构起始化部分逻辑就能够了?

此地还会有三个主题素材,负担分配该协会体内核内部存储器的例程 IopAllocateOpenPacket()
是多少个宏,Visual C++ 二〇一四 中付出它是用 ExAllocatePoolWithTag()
定义的。那就好办了,在我们本身的驱动力源码中,增多相应定义就可以,如下图:

 

图片 2

 

————————————————————————————————————————————————————————————

因为
OPEN_PACKET 结构形似未有公开的文书档案来汇报,所以照旧在大家的驱动力源码中用 
#include
满含定义它的头文件,要么直接复制订义的那有个别黏贴进来。很确定,前面一个相当轻便——OPEN_PACKET
在基本源码的 “iomgr.h
中定义,而该头文件又嵌套包含了一群乌七八糟的内核头文件,要清理那一个嵌套包罗关系很麻烦,并且最注重的是,中间有的头文件定义的数据类型会与驱动开拓中用的 “ntddk.h”
和“wdm.h”重复,引起编写翻译器的抱怨。
由此直接在 “iomgr.h
中寻觅字串 “typedef struct
_OPEN_PACKET”,把找到的概念块拷贝进来就可以。

然而,OPEN_PACKET
结构中仅仅多个字段不是 “原生” 定义的——那正是 “PDUMMY_FILE_OBJECT”
类型,须求富含其余头文件才不产生编写翻译器报错。

本身的减轻方案是,直接把该字段的宣示所在行注释掉,下图展现了该字段具体的岗位(在
iomgr.h” 中的行号卡塔 尔(阿拉伯语:قطر‎,方便各位连忙搜索:

 

图片 3

——————————————————————————————————————————————————————————————————

注意,NT
6.1 版内核在编写翻译时刻的 OPEN_PACKET 结构明显是未经 “恶意
修改的,所以编译器为其 “sizeof(OPEN_PACKET)” 表明式计算 0x70
的值,而大家在本人的驱动中拿掉了 OPEN_PACKET
当中叁个字段使得编写翻译器为表明式 “sizeof(OPEN_PACKET)” 预总结 0x58
的值(后面包车型大巴调度阶段会表明),那会造成 “Size” 字段不是
IopParseDevice() 内部逻辑预期的 0x70,进而形成再次回到C0000024(STATUS_OBJECT_TYPE_MISMATCH)。

解决办法也非常的粗略,大家的驱动中,不要依附理编辑译时刻的乘除,间接把
Size” 字段的值硬编码为 0x70 不就好了?

如下图所示,你还有恐怕会小心到,笔者把
“Type” 字段的常量 “IO_TYPE_OPEN_PACKET”
改成了相应的数值,以保证生龙活虎旦。

 

图片 4

 

除此以外,由于
IopAllocateOpenPacket() 等价于
ExAllocatePoolWithTag(),而后人平日重临泛型指针(“ PVOID ,亦即 void
”),
于是本人强制把它转型为与
“openPacket” 生龙活虎致的项目。
厉兵粟马,“东风”
就在于调用 ObReferenceObjectByName() 时,为第几个参数字传送入“openPacket”
就可以,上海体育场合显示的很驾驭了。

——————————————————————————————————————————————————————————————————

十分不幸的是,笔者把编写翻译出来的驱动放到设想机(Windows
7,基于 NT 6.1 版内核卡塔尔国里面动态加载测量试验,仍然不大概获得到

“DeviceQQProtect”
相应的设备对象指针,ObReferenceObjectByName() 重返 C0000024。

为了寻觅故障原因,作者在分配
OPEN_PACKET 逻辑的前方利用内联系汇率编加多了两个软中断 “__asm{ int
3; } 

”,宿主机器上运维水源调节和测量试验器 kd.exe,我的开行参数像是那样:

kd.exe
-n -v -logo d:virtual_machine_debugging.txt -y
SRV*C:Symbols* -k
com:pipe,port=\.pipecom_1,baud=115200,reconnect

 

参数
“logo” 钦点要把方方面面调节和测量试验进程的输出音讯写入日志;

“-y”
钦点符号文件的任务(机器指令中绝非内核函数与变量的符号,所以调节和测验器供给查找额外的符号以向客商显示人类可读的称呼);
“-k”
参数钦点调节和测验类型为
取名管道模拟串口1”,Porter率数值越高,响应越快。

把重新编写翻译好的驱动放到设想机中,在晋级权限后的一声令下提醒符中实施
bcdedit.exe,启用调节和测量试验格局,那样重启虚构机后,就能进来调节和测量试验格局(无需在开发银行进度中按下
F8 选拔菜单卡塔尔。

自家把本人的驱动完结有按需加载,也正是选取劳务调整微处理器sc.exe卡塔尔发出命令来动态加载和卸载,完成此功能的应和批处理公事内容如下图,注意该文件要放在设想机中推行,“start=
demand” 评释通过 sc.exe 按需运行
;“binpath”
正是驱动文件寄存的磁盘路线
,即使自己的驱动名字为hideprocess.sys,试行该批管理职分后,就在连带的注册表地方增多了后生可畏项,以后只需在
cmd.exe 中实行 “sc.exe start/stop hideprocess” 就能够动态加卸载。

图片 5

 

遵照上述方法加载时,就能自行触发大家设定好的软件断点,就可以在宿主机中检查虚构机的基业空间。
此外还需注意一点:编写翻译驱动时的
“创设” 景况应当接受 Check
Build
,那样会后生可畏并生成同名称的暗号文件,后缀为
.pdb”,进而调节和测验器能够展现我们和煦驱动中的函数与变量名称,进步调节和测验效用,如下图:

 

图片 6

——————————————————————————————————————————————————————————————————————

接触软件断点后,大家常常会用
kv” 命令查看栈回溯音讯,它披流露大家的驱动入口点 DriverEntry() 是由
I/O 微处理机的 IopLoadDriver() 调用的:

 

图片 7

栈的顶层函数
“ReferenceDeviceAndHookIRPdispatchRoutine+0x56
是自个儿加多软中断的地点。履行 “r” 命令查看当前的 x86
通用寄放器状态,EIP 指向地址 0x8f4a3196 ,推行 “u
hideprocess!ReferenceDeviceAndHookIRPdispatchRoutine+0x56
L2”,反汇编输出的首先行地址正是 0x8f4a3196,与 EIP
的值适合;第二行是把三个 16 进制值 “ 704F6F49h” 压栈,实际上它是
ASCII 字符 “pOoI” 的 16
进制编码,换言之,这是在通过内核栈传递 ExAllocatePoolWithTag()
的第八个参数(从右往左传递,请纪念以前的 IopAllocateOpenPacket()
宏定义那张图卡塔 尔(阿拉伯语:قطر‎。

————————————————————————————————————————————————————————————————

持续按下
t” 单步实践,如下图所示,你能够看出,ExAllocatePoolWithTag()
的第叁个参数,分配的基行业内部部存款和储蓄器大小为 0x70
字节,因为本身在宏定义中硬编码了这么些值,实际不是用 sizeof(OPEN_PACKET)
表明式让编写翻译器总结;其他方面,图中的 “dt” 命令也认证了它的大小为
0x70 字节。

第八个传入的参数
NonPagedPool
为不可换页池,其内的多寡不能被换出物理内部存款和储蓄器,该常量对应的数值为
“0”:

图片 8

 

本人不想浪费时间在翻看内核内部存款和储蓄器的分红细节上,所以本人按下
p”,步过 ExAllocatePoolWithTag() 函数调用,接下去的 cmp/jne
汇编连串
对应源码中反省是或不是成功分配了内部存款和储蓄器并用于 openPacket
指针,实际的进行结果是跳转到地址 0x8f4a31c6 ,对应源码中初阶化
OPEN_PACKET 结构前四个字段的逻辑:

图片 9

接下来间接单步施行到调用
ObReferenceObjectByName() 前夕,在那我们要 “步入
它的内部,举办故障每一种审核,所以按下 “t
跟进,这里有三个小手艺,大家曾经分析过 ObReferenceObjectByName()
的源码,知道它会调用相当多函数,何况大致领会难点条件成熟自然发生在
ObpLookupObjectName() 里面,所以指令
tc”能够追踪到每一种函数调用项结束,再由顾客决定是还是不是跟进该函数内部。

这是小编的光明期望,但现实总是残忍的,在笔者追踪到原子操作种类函数

nt!ExInterlockedPopEntrySList()
调用时,kd.exe
就卡住了,不可能继续追踪从此以后的调用链。从稍早的栈回溯消息来看,与源码杏月我们预测的调用连串大约切合,只是不通晓为何在
nt!ObpAllocateObjectNameBuffer() 中,为了给传入的驱动对象名称
“DeviceQQProtect”
分配内核内部存款和储蓄器,调用 nt!ExInterlockedPopEntrySList(),而前者却回天无力追踪。。。。是虚构机情况的原故,仍旧原子操作类函数的不可分割性质?

 

图片 10

 ——————————————————————————————————————————————————————————————

讲一点废话,日常大家在栈回溯中看看的顶层说明行,有一个 “Args to Child” 项目,表示调用者传递给它的参数,可是最多也必须要显示前多个。

以下图为例子吗,传递给 nt!ExAllocatePoolWithTag()
的三个参数(从左到右卡塔 尔(阿拉伯语:قطر‎就是00000000(NonPagedPool卡塔 尔(英语:State of Qatar),00000070(小编硬编码的值卡塔 尔(英语:State of Qatar),704f6f49(ASCII
字符串“pOoI”)
,同理,传递给 hideprocess!DriverEntry() 的第多少个参数
867c3550 是 _DRIVER_OBJECT 结构之处,由I/O
处理器加载它时为它分配(注意与源码中 DriverEntry() 定义的大器晚成枚
_DRIVER_OBJECT 指针差异,“Args to
Child”

列出的多寡一定于实行解引操作符 *
后的结果
卡塔尔,第四个参数是 UNICODE_ST君越ING
结构的地点,对应源码定义中的风度翩翩枚 _UNICODE_ST君越ING
指针,该组织中贮存的是我们驱动在注册表中的完整路线:

 

图片 11
——————————————————————————————————————————————————————————————————

显而易见,基于上述理由小编一点办法也未有继续跟进到 ObpLookupObjectName()
里面查看它是否施行了 IopParseDevice()
回调,进而不能明确毕竟为啥后面一个再次回到 C0000024。

自家想只怕是因为根本源码版本的浮动,以致相关例程的决断逻辑也不均等了,无法依赖前风姿洒脱版源码的逻辑来编排估量运维在后生机勃勃版内核上的驱动。

实际上施工方案仍有的,相比较花时间而已,便是利用 “u” 指令反汇编
ObpLookupObjectName() 开端处对应的机器指令,再反编译成肖似的 C 伪码,与
NT 5.2
版内核源码比较,寻找里面改造的地点,但那是三个费时费力的行事,且收入甚微,还不比直接在网络络搜释出的
NT 6.1 版内核源码,大概贴近的本子,再用脑筋想绕过的点子。

顺便说一下,根据 A 设备名获得 A 设备对象的指针,然后把
rootkit/本身驱动成立的恶意设备 attach 到 A
设备所在的配备栈,进而阻碍检查通过 A 设备的 IRP
内数据。。。。这种方式已经比较过时了,因为今后反病毒软件的水源形式组件也会检查这几个器械栈,寻觅其余相配特征码的恶意设备,再者,内核调节和测验器的
“!devstack”
命令十分轻易遍历揭穿出给定设备所在的设施栈内容,被大范围用于Computer考查取证中,从
rootkit 的首要指标——实现隐身——的角度来看, attach
到设备栈就不是三个好规范。

反倒,通过 ObReferenceObjectByName()
总是能够赢得驱动对象的指针,进而可以 hook 该驱动的 IRP
分发例程,这种手段掩盖性超级高,并且不便于被检查评定出来。

后续的博文将商量哪些将这种技巧用在
rootkit 中,同有的时候候适应现阶段流行的相辅而行多微机(SMP卡塔尔意况。

————————————————————————————————————————————————————————————————

相关文章