IopParseDevice() 如何对传播的 OPEN

图片 11

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

在上生机勃勃篇文章中,大家早就见到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 选用菜单卡塔 尔(英语:State of Qatar)。

自作者把温馨的驱动完结存按需加载,也正是使用服务调整微处理器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()
宏定义那张图卡塔 尔(英语:State of Qatar)。

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

世袭按下
t” 单步试行,如下图所示,你能够观察,ExAllocatePoolWithTag()
的第3个参数,分配的内核内部存款和储蓄器大小为 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
就卡住了,不能够继续跟踪今后的调用链。从稍早的栈回溯新闻来看,与源码12月我们推断的调用连串大概切合,只是不领悟为何在
nt!ObpAllocateObjectNameBuffer() 中,为了给传入的驱动对象名称
“DeviceQQProtect”
分配内核内部存款和储蓄器,调用 nt!ExInterlockedPopEntrySList(),而前面一个却无能为力追踪。。。。是虚构机情形的原故,照旧原子操作类函数的不可分割性质?

 

图片 10

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

讲一点废话,平时大家在栈回溯中看到的顶层表达行,有叁个 “Args to Child” 项目,表示调用者传递给它的参数,然而最多也只能呈现前多个。

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

列出的数码一定于推行解引操作符 *
后的结果
卡塔尔,第一个参数是 UNICODE_STWranglerING
结构的地点,对应源码定义中的生机勃勃枚 _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卡塔尔国意况。

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