图片 11

驱动开发之

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

 

在写
filter driver 或 rootkit 时,平时供给 attach
到器械栈中的靶子设备,来堵住途经的 IRP(I/O Request
Packet卡塔 尔(英语:State of Qatar),完毕过滤效果。
第风流洒脱要意识到目的设备向
Windows Object Manager 维护的大局名称空间注册的 _DEVICE_OBJECT
名,此类信息方可因而像是 WinObj.exe 的工具获得。

随之调用
ObReferenceObjectByName(),该函数把获得的目的对象地址存款和储蓄到它的尾声三个参数(指针卡塔尔中,然后再次回到给调用者。
实战时我们会发觉,援引
_DRIVER_OBJECT 差十分的少总是成功;而援引
_DEVICE_OBJECT,则不分明会中标,重回的 NTSTATUS
状态码平日以二种居多:

1 C0000022(STATUS_ACCESS_DENIED)
2 C0000024(STATUS_OBJECT_TYPE_MISMATCH)

 

率先种意况习认为常是由于成立指标
_DEVICE_OBJECT 时钦命的 session id 与当前的 session id
不平等,只怕目的对象具有特殊的平安访问令牌/安全质量,所以大家爱莫能助以符合规律方法拿到,何况这种错误频仍出未来
IoGetDeviceObjectPointer() 调用时,偏偏多数讲过滤驱动和 rootkit
的图书都用 IoGetDeviceObjectPointer()
作为示范代码的意气风发局地,真是有一点点误人子弟的表示。

第二种意况普遍出未来经过
ObReferenceObjectByName() 援用某个 _DEVICE_OBJECT
的面貌中,缘由与 ObReferenceObjectByName()
利用别的实行体组件例程,在全局名称空间中施行的名字查找逻辑缜密相关,前面会解释。

亟待建议,既然经过
ObReferenceObjectByName() 引用绝大比相当多 _DRIVER_OBJECT
都会成功,并且 _DRIVER_OBJECT.DeviceObject
又针对该驱动创制的设备链中第三个
_DEVICE_OBJECT,那么那正是最妥贴的不二等秘书技。可是我们照旧要知道
STATUS_OBJECT_TYPE_MISMATCH 的原因。

 ObReferenceObjectByName()
是多个未公开的例程,在 MSDN 中尚无文书档案描述,另一面,包涵的 ntddk.h 或
wdm.h 头文件中也从不有关原型申明;

然而内核映像ntoskrnl.exe
和任何的版本,的确导出了它的暗记,换言之,我们只必要报告链接器把那几个函数名作为外界符号来深入分析就可以。
此外,ObReferenceObjectByName()
的第四个参数也是三个未文书档案化的数据类型(POBJECT_TYPE卡塔 尔(英语:State of Qatar),所以相关的宣示是必需的,如下图所示:

 

图片 1

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

请留心,大家证明了二个针对类型“POBJECT_TYPE”的指针——IoDeviceObjectType——而“POBJECT_TYPE”本人又是指向品种“OBJECT_TYPE”的指针,所以在传播第三个参数时,必须求审慎,使用操作符
*” 解引
IoDeviceObjectType,才会与它的形参类型(POBJECT_TYPE卡塔尔相配,否则会导致
ObReferenceObjectByName() 战败,干扰大家对回到的 NTSTATUS
原因判别!

 

假设大家温馨的驱动要博得“DeviceQQProtect”对应的
_DEVICE_OBJECT 指针,然后检查再次回到的 NTSTATUS
状态码,如下图所示:

(“DeviceQQProtect”是与当下通讯软件
QQ 一起安装的五个过滤驱动之风姿浪漫:QQProtect.sys
创立的设备对象名,
它也是大家稍后的
IRP Dispatch Routine Hook 实验目标!卡塔 尔(阿拉伯语:قطر‎

 

图片 2

 

能够观看,在设想机中测验时,DbgPrint()
打字与印刷重临的状态码为
C0000024(STATUS_OBJECT_TYPE_MISMATCH卡塔尔国,也等于指标类型不合作,如下图所示:

 

图片 3

 

正要手边有意气风发份
NT 5.2 版内核的源码,它用来编写翻译 Windows XP/Server 2003使用的内核,尽管与自己的测量检验机器的 NT 6.1 版内核有所差别,但是
要么姑且来看下
ObReferenceObjectByName() 内部毕竟干了些什么。ObReference*()
类别的例程多数坐落内核源码的“obref.c” 与“obdir.c
文件内。通过对有关调用链的深入解析,如下图所示:

图片 4

上海教室中有两处关键点:其一是
ObpLookupObjectName() 中,检核查象对象类型的先河化设定(用
_OBJECT_TYPE_INITIALIZER 结构意味着卡塔 尔(阿拉伯语:قطر‎中,是还是不是钦定了
ParseProcedure
例程,对于“设备”类对象,该函数值指针总是为 IopParseDevice() ,最后以致调用
IopParseDevice()

留意察看前方的图纸可以知道,从最先本身调用
ObReferenceObjectByName() 开端,就为它的第八个参数 ParseContext 传入 NULL,而 ParseContext
会在调用链中一路往下传递,最后由
IopParseDevice() 选用并对该参数举行验证,即便它为空,就回到
STATUS_OBJECT_TYPE_MISMATCH

前天你知道怎么
ObReferenceObjectByName()
援引指标设备连接令人这么蛋疼,关键就在急需分配并起先化那些 ParseContext。。。

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

自己在源码中领取了相关代码片段,如下边那些图所示,最佳能(CANON卡塔尔把它与地方的流程图比较加深驾驭,
前面作者会拿设想机上的
Windows 7(基于 NT 6.1
版内核卡塔尔调节和测验,你会惊叹地窥见,追踪栈回溯音信时,
以致与
NT 5.2
版内核源码中的调用链非常相似,那表明版本之间的迁移并不曾让对象名查找和注解逻辑退换太大。
(起码从
Windows XP 到 7
来讲是那般,之后的本子由于没测量试验过,就不精通了!卡塔尔

 

图片 5

 

图片 6

图片 7

 

 

 


IopParseDevice()
内部的这段注释,作者不明获得了绕过调用源检测的笔触——这就是追踪
NtCreateFile() ,看看 OPEN_PACKET 具体是在何地

分红并领头化的;由于
IopParseDevice() 会检测 POPEN_PACKET 结构实例的局部字段来担保
ObReferenceObjectByName() 调用
是从
NtCreateFile() 发起的,NtCreateFile() 实今后 NT 5.2 版内核源码的
creater.c
中,它只是简单地试行调用链
IoCreateFile()->IopCreateFile()(此两例程都实今后源码的 iosubs.c 中卡塔 尔(阿拉伯语:قطر‎,而现实由
IopCreateFile() 分配并初阶化 OPEN_PACKET 结构。

所以我们只要在援引目的设备对象前,仿照
IopCreateFile() 的连带逻辑来分配并起头化 OPEN_PACKET,并作为
ObReferenceObjectByName()
的参数字传送入,就能绕过
IopParseDevice() 的“调用源检查测量试验”逻辑。
那部分
Patch 就留待后边的随笔再发表。我们当前先要验证“设备”类对象的“ParseProcedure”确实为
IopParseDevice()。。。。。

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

在双击内核调节和测量检验情形中,首先通过设备名称“DeviceQQProtect”获得相应对象的音讯:

图片 8

赢得指标头地址后,格式化并转储此中的字段,大家感兴趣的是“TypeIndex”字段,它用来索引“对象类型表”中的相应“对象类型”:

 

图片 9

WInodws
内核使用八个数据结构——ObTypeIndexTable
寄存有关各个“对象类型”的音信,本质上 ObTypeIndexTable
是四个指南针数组,在 32 位体系布局上,各个指针大小
4 字节,而咱们拿到的索引号为(下标**
0
开始**卡塔 尔(英语:State of Qatar)19,下图中的两条表明式据此总括出该“对象类型”的地点:

图片 10

推断,相应“对象类型”结构之处为
0x855cef78——Windows 内核用数据结构 _OBJECT_TYPE
来代表“对象类型”的概念,所以再度
格式化并转储此中的字段,大家感兴趣的字段为“TypeInfo”,如前所述,它是贰个“对象类型开端化设定”结构,内核用
_OBJECT_TYPE_INITIALIZER
来代表“对象类型初叶化设定”的定义。供给小心,TypeInfo
偏移它的母结构起先地址 0x28
字节,所以要增加那一个
offset
再查看,如您所见,在那之中的“ParseProcedure”为
IopParseDevice()

 

图片 11

 

下卷作品将斟酌怎么样绕过
IopParseDevice() 的调用源检查测量试验,并调整大家的果实,将其使用于 rootkit
开荒工夫中。

 

发表评论