故障排查,驱动开发之

by admin on 2019年4月3日

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

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

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

——–驱动开发之 ObReferenceObjectByName() 故障排查——–,

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

 

在写 filter driver 或 rootkit 时,平时须求 attach
到设备栈中的指标设备,来堵住途经的 ISportageP(I/O Request
Packet),达成过滤效果。
第一要查出目的设备向 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() 是3个未公开的例程,在 MSDN
中从未文书档案描述,另一方面,包蕴的 ntddk.h 或 wdm.h
头文件中也远非有关原型注解;

不过内核影象 ntoskrnl.exe
和此外的本子,的确导出了它的标志,换言之,大家只要求告诉链接器把那么些函数名作为外部符号来分析即可。
此外,ObReferenceObjectByName()
的第5个参数也是3个未文书档案化的数据类型(POBJECT_TYPE),所以有关的申明是必须的,如下图所示:

 

home88一必发 1

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

请留心,大家注解了一个针对性类型“POBJECT_TYPE”的指针——IoDeviceObjectType——而“POBJECT_TYPE”本人又是指向品种“OBJECT_TYPE”的指针,所以在流传第七个参数时,一定要深思熟虑,使用操作符
*” 解引
IoDeviceObjectType,才会与它的形参类型(POBJECT_TYPE)匹配,不然会招致
ObReferenceObjectByName() 退步,苦恼大家对回到的 NTSTATUS 原因判断!

 

倘诺大家相濡以沫的驱动要取得“\Device\QQProtect”对应的
_故障排查,驱动开发之。DEVICE_OBJECT 指针,然后检查再次回到的 NTSTATUS
状态码,如下图所示:

(“\Device\QQProtect”是与当下通讯软件 QQ
1同安装的八个过滤驱动之一:QQProtect.sys 创立的设施对象名,
它也是大家稍后的 I本田UR-VP Dispatch Routine Hook 实验对象!)

 

home88一必发 2

 

能够观望,在虚拟机中测试时,DbgPrint() 打字与印刷重返的状态码为
C00000二四(STATUS_OBJECT_TYPE_MISMATCH),也正是指标类型不合作,如下图所示:

 

home88一必发 3

 

凑巧手边有壹份 NT 五.二 版内核的源码,它用来编写翻译 Windows XP/Server 2003使用的基业,即便与自家的测试机器的 NT 6.一 版内核有所差别,但是
依旧姑且来看下 ObReferenceObjectByName()
内部毕竟干了些什么。ObReference*()
连串的例程多数位居内核源码的“obref.c” 与“obdir.c
文本内。通过对有关调用链的剖析,如下图所示:

home88一必发 4

上图中有两处关键点:其1是 ObpLookupObjectName()
中,检核对象对象类型的初始化设定(用 _OBJECT_TYPE_INITIALIZER
结构意味着)中,是不是钦命了 ParseProcedure
例程,对于“设备”类对象,该函数值指针总是为
IopParseDevice() ,最后促成调用 IopParseDevice()

密切考查前方的图形可见,从初期作者调用 ObReferenceObjectByName()
伊始,就为它的第五个参数 ParseContext 传入 NULL,而 ParseContext
会在调用链中一路往下传递,最后由 IopParseDevice()故障排查,驱动开发之。
接受并对该参数实行认证,借使它为空,就回去
STATUS_OBJECT_TYPE_MISMATCH

以往您驾驭为啥 ObReferenceObjectByName()
引用指标设备连接令人那样蛋疼,关键就在急需分配并伊始化这多少个ParseContext。。。

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

自个儿在源码中领到了连带代码片段,如上面这一个图所示,最棒能把它与地点的流程图相比加深掌握,
背后笔者会拿虚拟机上的 Windows 7(基于 NT 陆.1版内核)调节和测试,你会惊讶地意识,追踪栈回溯消息时,
依旧与 NT 五.2版内核源码中的调用链卓殊相似,那声明版本之间的迁移并从未让对象名查找和验证逻辑改动太大。
(至少从 Windows XP 到 7而言是这么,之后的版本由于没测试过,就不精通了!)

 

home88一必发 5

 

home88一必发 6

home88一必发 7

 

 

 

IopParseDevice()
内部的那段注释,作者隐隐获得了绕过调用源检查实验的笔触——那便是跟踪
NtCreateFile() ,看看 OPEN_PACKET 具体是在哪里

分红并初阶化的;由于 IopParseDevice() 会检测 POPEN_PACKET
结构实例的一部分字段来保险 ObReferenceObjectByName() 调用
是从 NtCreateFile() 发起的,NtCreateFile() 完结在 NT 伍.2版内核源码的 creater.c 中,它只是简单地履行调用链
IoCreateFile()->IopCreateFile()(此两例程都完毕在源码的
iosubs.c 中),而实际由 IopCreateFile() 分配并开始化
OPEN_PACKET 结构。

据此我们假若在引用指标设备对象前,仿照 IopCreateFile()
的相关逻辑来分配并开头化 OPEN_PACKET,并作为
ObReferenceObjectByName()
的参数字传送入,就会绕过 IopParseDevice() 的“调用源检测”逻辑。
那部分 Patch
就留待前面包车型地铁小说再公布。我们当下先要验证“设备”类对象的“ParseProcedure”确实为
IopParseDevice()。。。。。

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

在双击内核调节和测试环境中,首先通过设备名称“\Device\QQProtect”取得相应对象的音讯:

home88一必发 8

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

 

home88一必发 9

WInodws 内核使用一个数据结构——ObTypeIndexTable
存放有关各个“对象类型”的音信,本质上 ObTypeIndexTable
是二个指南针数组,在 3二 位类别布局上,每一个指针大小 肆字节,而大家赢得的索引号为(下标**从 0
开始**)1玖,下图中的两条表明式据此估测计算出该“对象类型”的地点:

home88一必发 10

由此可见,相应“对象类型”结构的地点为 0x855cef78——Windows
内核用数据结构 _OBJECT_TYPE 来代表“对象类型”的概念,所以重复
格式化并转储个中的字段,大家感兴趣的字段为“TypeInfo”,如前所述,它是三个“对象类型初步化设定”结构,内核用

_OBJECT_TYPE_INITIALIZER
来代表“对象类型初阶化设定”的概念。要求注意,TypeInfo
偏移它的母结构初始地址 0x2捌 字节,所以要抬高那么些
offset 再查看,如你所见,当中的“ParseProcedure”为 IopParseDevice()

 

home88一必发 11

 

下篇文章将切磋哪边绕过 IopParseDevice()
的调用源检验,并调节大家的战果,将其应用于 rootkit 开发技术中。

 

ObReferenceObjectByName()
故障排查——–, ————————————————————————————————————…

 

 

 

在写
filter driver 或 rootkit 时,经常索要 attach
到设备栈中的靶子设备,来堵住途经的 IPAJEROP(I/O Request
Packet),达成过滤效果。
第二要意识到指标设备向
Windows Object Manager 维护的大局名称空间注册的 _DEVICE_OBJECT
名,此类新闻方可透过像是 WinObj.exe 的工具获得。

在写
filter driver 或 rootkit 时,平时索要 attach
到装备栈中的对象设备,来阻止途经的 I奥德赛P(I/O Request
Packet),达成过滤效果。
先是要查出指标设备向
Windows Object Manager 维护的全局名称空间注册的 _DEVICE_OBJECT
名,此类新闻可以因此像是 WinObj.exe 的工具获得。

在写
filter driver 或 rootkit 时,常常需求 attach
到设备栈中的目的设备,来堵住途经的 ICR-VP(I/O Request
Packet),达成过滤效果。
首先要得知指标设备向
Windows Object Manager 维护的大局名称空间注册的 _DEVICE_OBJECT
名,此类消息方可通过像是 WinObj.exe 的工具获得。

继之调用
ObReferenceObjectByName(),该函数把得到的对象对象地址存款和储蓄到它的末段贰个参数(指针)中,然后回到给调用者。
实战时我们会发现,引用
_DRIVER_OBJECT 大约连接成功;而引用
_DEVICE_OBJECT,则不肯定会成功,再次来到的 NTSTATUS
状态码一般以二种居多:

随后调用
ObReferenceObjectByName(),该函数把收获的对象对象地址存款和储蓄到它的终极二个参数(指针)中,然后回到给调用者。
实战时大家会意识,引用
_DRIVER_OBJECT 差不多连接成功;而引用
_DEVICE_OBJECT,则不必然会成功,重返的 NTSTATUS
状态码一般以二种居多:

紧接着调用
ObReferenceObjectByName(),该函数把得到的目的对象地址存款和储蓄到它的最后贰个参数(指针)中,然后回到给调用者。
实战时大家会意识,引用
_DRIVER_OBJECT 差不离总是成功;而引用
_DEVICE_OBJECT,则不必然会成功,重回的 NTSTATUS
状态码一般以两种居多:

1 C0000022(STATUS_ACCESS_DENIED)
2 C0000024(STATUS_OBJECT_TYPE_MISMATCH)
1 C0000022(STATUS_ACCESS_DENIED)
2 C0000024(STATUS_OBJECT_TYPE_MISMATCH)
1 C0000022(STATUS_ACCESS_DENIED)
2 C0000024(STATUS_OBJECT_TYPE_MISMATCH)

 

 

 

率先种情况家常便饭是由于创制目的
_DEVICE_OBJECT 时钦命的 session id 与当前的 session id
不平等,只怕指标对象具备特殊的平安访问令牌/安全品质,所以我们鞭长莫及以常规方法获取,而且那种错误频仍出现在
IoGetDeviceObjectPointer() 调用时,偏偏多数讲过滤驱动和 rootkit
的书本都用 IoGetDeviceObjectPointer()
作为示范代码的1有些,真是有点误人子弟的意味。

先是种情景见惯司空是出于成立目的
_DEVICE_OBJECT 时钦命的 session id 与当下的 session id
不均等,或许目的对象拥有特殊的平安访问令牌/安全质量,所以我们鞭长莫及以常规方式获得,而且那种似是而非频仍出现在
IoGetDeviceObjectPointer() 调用时,偏偏多数讲过滤驱动和 rootkit
的书籍都用 IoGetDeviceObjectPointer()
作为示范代码的一局地,真是有点误人子弟的象征。

先是种情形普通是由于创制指标
_DEVICE_OBJECT 时钦命的 session id 与如今的 session id
分化,或许目的对象具备特殊的阜新访问令牌/安全品质,所以大家不可能以健康办法赢得,而且这种不当频仍现身在
IoGetDeviceObjectPointer() 调用时,偏偏多数讲过滤驱动和 rootkit
的图书都用 IoGetDeviceObjectPointer()
作为示范代码的一部分,真是有点误人子弟的代表。

其次种状态普遍出现在通过
ObReferenceObjectByName() 引用有个别 _DEVICE_OBJECT
的境况中,缘由与 ObReferenceObjectByName()
利用其余执行体组件例程,在全局名称空间中履行的名字查找逻辑缜密相关,前面会解释。

第一种情景普遍出现在经过
ObReferenceObjectByName() 引用某些 _DEVICE_OBJECT
的光景中,缘由与 ObReferenceObjectByName()
利用此外执行体组件例程,在大局名称空间中实践的名字查找逻辑缜密相关,前面会分解。

其次种意况普遍出现在通过
ObReferenceObjectByName() 引用有些 _DEVICE_OBJECT
的场合中,缘由与 ObReferenceObjectByName()
利用别的执行体组件例程,在全局名称空间中执行的名字查找逻辑缜密相关,前面会解释。

亟需提出,既然经过
ObReferenceObjectByName() 引用绝大部分 _DRIVER_OBJECT
都会成功,而且 _DRIVER_OBJECT.DeviceObject
又针对该驱动成立的配备链中第贰个
_DEVICE_OBJECT,那么这正是最妥贴的章程。然则大家依旧要驾驭
STATUS_OBJECT_TYPE_MISMATCH 的原因。

亟待提议,既然经过
ObReferenceObjectByName() 引用绝半数以上 _DRIVER_OBJECT
都会成功,而且 _DRIVER_OBJECT.DeviceObject
又针对该驱动创造的设施链中第陆个
_DEVICE_OBJECT,那么这正是最妥善的措施。然则大家还是要精通
STATUS_OBJECT_TYPE_MISMATCH 的原因。

要求提议,既然经过
ObReferenceObjectByName() 引用绝大多数 _DRIVER_OBJECT
都会成功,而且 _DRIVER_OBJECT.DeviceObject
又针对该驱动创造的装置链中第11个
_DEVICE_OBJECT,那么那正是最稳当的艺术。然则大家依旧要精晓
STATUS_OBJECT_TYPE_MISMATCH 的原因。

 ObReferenceObjectByName()
是叁个未公开的例程,在 MSDN 中从未文书档案描述,另一方面,包括的 ntddk.h 或
wdm.h 头文件中也从未有关原型评释;

 ObReferenceObjectByName()
是一个未公开的例程,在 MSDN 中未有文书档案描述,另壹方面,包括的 ntddk.h 或
wdm.h 头文件中也未尝有关原型注脚;

 ObReferenceObjectByName()
是多少个未公开的例程,在 MSDN 中绝非文书档案描述,另一方面,包括的 ntddk.h 或
wdm.h 头文件中也尚无相关原型表明;

然则内核映像ntoskrnl.exe
和其余的版本,的确导出了它的符号,换言之,大家只须要告诉链接器把这几个函数名作为外部符号来分析即可。
此外,ObReferenceObjectByName()
的第四个参数也是2个未文书档案化的数据类型(POBJECT_TYPE),所以相关的评释是必须的,如下图所示:

可是内核映像ntoskrnl.exe
和别的的本子,的确导出了它的标记,换言之,大家只必要告诉链接器把那些函数名作为外部符号来分析即可。
此外,ObReferenceObjectByName()
的第几个参数也是2个未文档化的数据类型(POBJECT_TYPE),所以有关的申明是必须的,如下图所示:

然而内核影像ntoskrnl.exe
和其余的本子,的确导出了它的符号,换言之,大家只要求告诉链接器把那几个函数名作为外部符号来分析即可。
此外,ObReferenceObjectByName()
的第多个参数也是2个未文书档案化的数据类型(POBJECT_TYPE),所以有关的注明是必须的,如下图所示:

 

 

 

home88一必发 12

home88一必发 13

home88一必发 14

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

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

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

请小心,大家证明了1个针对性类型“POBJECT_TYPE”的指针——IoDeviceObjectType——而“POBJECT_TYPE”自个儿又是指向项目“OBJECT_TYPE”的指针,所以在流传第陆个参数时,一定要审慎,使用操作符
*” 解引
IoDeviceObjectType,才会与它的形参类型(POBJECT_TYPE)匹配,否则会促成
ObReferenceObjectByName() 退步,烦扰大家对回到的 NTSTATUS
原因判断!

请留心,大家表明了多少个针对类型“POBJECT_TYPE”的指针——IoDeviceObjectType——而“POBJECT_TYPE”本身又是指向项目“OBJECT_TYPE”的指针,所以在传唱第四个参数时,一定要深图远虑,使用操作符
*” 解引
IoDeviceObjectType,才会与它的形参类型(POBJECT_TYPE)匹配,不然会促成
ObReferenceObjectByName() 失利,干扰大家对回到的 NTSTATUS
原因判断!

请留心,大家申明了3个针对类型“POBJECT_TYPE”的指针——IoDeviceObjectType——而“POBJECT_TYPE”自己又是指向品种“OBJECT_TYPE”的指针,所以在扩散第陆个参数时,一定要小心翼翼,使用操作符
*” 解引
IoDeviceObjectType,才会与它的形参类型(POBJECT_TYPE)匹配,不然会促成
ObReferenceObjectByName() 败北,干扰大家对回到的 NTSTATUS
原因判断!

 

 

 

假设我们团结的驱动要收获“\Device\QQProtect”对应的
_DEVICE_OBJECT 指针,然后检查重临的 NTSTATUS
状态码,如下图所示:

若果我们和好的驱动要赢得“\Device\QQProtect”对应的
_DEVICE_OBJECT 指针,然后检查重返的 NTSTATUS
状态码,如下图所示:

假如大家友好的驱动要得到“\Device\QQProtect”对应的
_DEVICE_OBJECT 指针,然后检查再次来到的 NTSTATUS
状态码,如下图所示:

(“\Device\QQProtect”是与当时通讯软件
QQ 一同安装的多少个过滤驱动之一:QQProtect.sys
创设的设备对象名,
它也是我们稍后的
I汉兰达P Dispatch Routine Hook 实验指标!)

(“\Device\QQProtect”是与当下通讯软件
QQ 一同安装的多个过滤驱动之1:QQProtect.sys
创制的装备对象名,
它也是咱们稍后的
I普拉多P Dispatch Routine Hook 实验对象!)

(“\Device\QQProtect”是与当时通讯软件
QQ 壹同安装的四个过滤驱动之1:QQProtect.sys
创设的配备对象名,
它也是我们稍后的
I索罗德P Dispatch Routine Hook 实验指标!)

 

 

 

home88一必发 15

home88一必发 16

home88一必发 17

 

 

 

能够看看,在虚拟机中测试时,DbgPrint()
打字与印刷重回的状态码为
C00000二四(STATUS_OBJECT_TYPE_MISMATCH),也正是指标类型不匹配,如下图所示:

能够见见,在虚拟机中测试时,DbgPrint()
打字与印刷重临的状态码为
C00000二4(STATUS_OBJECT_TYPE_MISMATCH),也等于指标类型不般配,如下图所示:

能够观察,在虚拟机中测试时,DbgPrint()
打字与印刷再次回到的状态码为
C00000二四(STATUS_OBJECT_TYPE_MISMATCH),也正是目标类型不般配,如下图所示:

 

 

 

home88一必发 18

home88一必发 19

home88一必发 20

 

 

 

刚好手边有1份
NT 5.二 版内核的源码,它用来编写翻译 Windows XP/Server 二〇〇二使用的木本,固然与本身的测试机器的 NT 6.1 版内核有所差距,不过
抑或姑且来看下
ObReferenceObjectByName() 内部终究干了些什么。ObReference*()
连串的例程多数坐落内核源码的“obref.c” 与“obdir.c
文本内。通过对相关调用链的分析,如下图所示:

司空眼惯手边有一份
NT 5.二 版内核的源码,它用来编写翻译 Windows XP/Server 200三使用的水源,就算与自身的测试机器的 NT 六.1 版内核有所差别,可是
抑或姑且来看下
ObReferenceObjectByName() 内部毕竟干了些什么。ObReference*()
系列的例程多数位居内核源码的“obref.c” 与“obdir.c
文件内。通过对相关调用链的辨析,如下图所示:

刚巧手边有一份
NT 5.二 版内核的源码,它用来编译 Windows XP/Server 200三使用的水源,就算与本人的测试机器的 NT 6.一 版内核有所差距,可是
抑或姑且来看下
ObReferenceObjectByName() 内部毕竟干了些什么。ObReference*()
连串的例程多数身处内核源码的“obref.c” 与“obdir.c
文件内。通过对相关调用链的辨析,如下图所示:

home88一必发 21

home88一必发 22

home88一必发 23

上海体育场所中有两处关键点:其1是
ObpLookupObjectName() 中,检查对象对象类型的伊始化设定(用
_OBJECT_TYPE_INITIALIZER 结构意味着)中,是或不是钦命了
ParseProcedure
例程,对于“设备”类对象,该函数值指针总是为 IopParseDevice() ,末了导致调用
IopParseDevice()

上图中有两处关键点:其壹是
ObpLookupObjectName() 中,检核查象对象类型的初步化设定(用
_OBJECT_TYPE_INITIALIZER 结构意味着)中,是或不是钦命了
ParseProcedure
例程,对于“设备”类对象,该函数值指针总是为 IopParseDevice() ,最终导致调用
IopParseDevice()

上海教室中有两处关键点:其一是
ObpLookupObjectName() 中,检核对象对象类型的伊始化设定(用
_OBJECT_TYPE_INITIALIZER 结构意味着)中,是不是钦命了
ParseProcedure
例程,对于“设备”类对象,该函数值指针总是为 IopParseDevice() ,最终造成调用
IopParseDevice()

有心人调查前方的图片可见,从早期本身调用
ObReferenceObjectByName() 开头,就为它的第三个参数 ParseContext 传入 NULL,而 ParseContext
会在调用链中一路往下传递,最后由
IopParseDevice() 接受并对该参数进行求证,即便它为空,就回去
STATUS_OBJECT_TYPE_MISMATCH

有心人考察前方的图样可见,从中期自身调用
ObReferenceObjectByName() 伊始,就为它的第5个参数 ParseContext 传入 NULL,而 ParseContext
会在调用链中一路往下传递,最后由
IopParseDevice() 接受并对该参数实行表达,即使它为空,就赶回
STATUS_OBJECT_TYPE_MISMATCH

细心察看前方的图形可见,从初期作者调用
ObReferenceObjectByName() 起首,就为它的第多个参数 ParseContext 传入 NULL,而 ParseContext
会在调用链中一路往下传递,最终由
IopParseDevice() 接受并对该参数进行验证,若是它为空,就回到
STATUS_OBJECT_TYPE_MISMATCH

今天你精通怎么
ObReferenceObjectByName()
引用目标设备连接让人那样蛋疼,关键就在需求分配并开端化那多少个 ParseContext。。。

当今您知道干什么
ObReferenceObjectByName()
引用目的设备连接令人那样蛋疼,关键就在供给分配并起首化那多少个 ParseContext。。。

今后您精通怎么
ObReferenceObjectByName()
引用指标设备连接让人那样蛋疼,关键就在供给分配并起首化那个 ParseContext。。。

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

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

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

自身在源码中提取了有关代码片段,如上面那个图所示,最佳能(CANON)把它与地方的流程图相比加深领悟,
末尾小编会拿虚拟机上的
Windows 7(基于 NT 6.壹版内核)调试,你会奇怪地发现,追踪栈回溯新闻时,
竟然与
NT 伍.贰版内核源码中的调用链卓殊相像,这表达版本之间的搬迁并不曾让对象名查找和认证逻辑改动太大。
(至少从
Windows XP 到 7而言是这般,之后的本子由于没测试过,就不知情了!)

自身在源码中提取了有关代码片段,如下边这个图所示,最CANON把它与地方的流程图相比较加深精通,
前面作者会拿虚拟机上的
Windows 7(基于 NT 陆.1版内核)调节和测试,你会惊讶地窥见,追踪栈回溯信息时,
居然与
NT 五.二版内核源码中的调用链万分相似,那证明版本之间的动员搬迁并不曾让对象名查找和申明逻辑改动太大。
(至少从
Windows XP 到 7而言是那样,之后的版本由于没测试过,就不知道了!)

自个儿在源码中提取了有关代码片段,如上边那些图所示,最佳能(CANON)把它与地点的流程图相比较加深理解,
背后我会拿虚拟机上的
Windows 七(基于 NT 6.一版内核)调节和测试,你会惊叹地意识,追踪栈回溯信息时,
甚至与
NT 伍.二版内核源码中的调用链卓殊相像,这表明版本之间的迁移并不曾让对象名查找和注明逻辑改动太大。
(至少从
Windows XP 到 7而言是这么,之后的本子由于没测试过,就不理解了!)

 

 

 

home88一必发 24

home88一必发 25

home88一必发 26

 

 

 

home88一必发 27

home88一必发 28

home88一必发 29

home88一必发 30

home88一必发 31

home88一必发 32

 

 

 

 

 

 

 

 

 


IopParseDevice()
内部的这段注释,笔者不明得到了绕过调用源检验的笔触——那便是跟踪
NtCreateFile() ,看看 OPEN_PACKET 具体是在哪个地方


IopParseDevice()
内部的那段注释,作者不明得到了绕过调用源检查实验的思绪——那正是跟踪
NtCreateFile() ,看看 OPEN_PACKET 具体是在何地


IopParseDevice()
内部的那段注释,作者不明获得了绕过调用源检查测试的思绪——那正是跟踪
NtCreateFile() ,看看 OPEN_PACKET 具体是在哪里

分配并初阶化的;由于
IopParseDevice() 会检测 POPEN_PACKET 结构实例的部分字段来保管
ObReferenceObjectByName() 调用
是从
NtCreateFile() 发起的,NtCreateFile() 完结在 NT 伍.二 版内核源码的
creater.c
中,它只是简单地推行调用链
IoCreateFile()->IopCreateFile()(此两例程都落实在源码的 iosubs.c 中),而具体由
IopCreateFile() 分配并开首化 OPEN_PACKET 结构。

分配并开端化的;由于
IopParseDevice() 会检测 POPEN_PACKET 结构实例的一些字段来担保
ObReferenceObjectByName() 调用
是从
NtCreateFile() 发起的,NtCreateFile() 达成在 NT 5.二 版内核源码的
creater.c
中,它只是简单地实施调用链
IoCreateFile()->IopCreateFile()(此两例程都实以后源码的 iosubs.c 中),而具体由
IopCreateFile() 分配并初阶化 OPEN_PACKET 结构。

分配并起首化的;由于
IopParseDevice() 会检测 POPEN_PACKET 结构实例的一对字段来确定保证
ObReferenceObjectByName() 调用
是从
NtCreateFile() 发起的,NtCreateFile() 实今后 NT 五.贰 版内核源码的
creater.c
中,它只是简短地推行调用链
IoCreateFile()->IopCreateFile()(此两例程都落到实处在源码的 iosubs.c 中),而具体由
IopCreateFile() 分配并初步化 OPEN_PACKET 结构。

故而大家只要在引用目的设备对象前,仿照
IopCreateFile() 的连带逻辑来分配并伊始化 OPEN_PACKET,并作为
ObReferenceObjectByName()
的参数字传送入,就会绕过
IopParseDevice() 的“调用源检查测试”逻辑。
那有个别Patch 就留待后边的小说再发布。大家日前先要验证“设备”类对象的“ParseProcedure”确实为
IopParseDevice()。。。。。

于是大家假如在引用指标设备对象前,仿照
IopCreateFile() 的有关逻辑来分配并开始化 OPEN_PACKET,并作为
ObReferenceObjectByName()
的参数字传送入,就会绕过
IopParseDevice() 的“调用源检查评定”逻辑。
那一部分
Patch 就留待前面包车型的士小说再发表。大家日前先要验证“设备”类对象的“ParseProcedure”确实为
IopParseDevice()。。。。。

所以大家借使在引用指标设备对象前,仿照
IopCreateFile() 的有关逻辑来分配并伊始化 OPEN_PACKET,并作为
ObReferenceObjectByName()
的参数字传送入,就会绕过
IopParseDevice() 的“调用源检查评定”逻辑。
那一部分
Patch 就留待前边的小说再公布。我们近日先要验证“设备”类对象的“ParseProcedure”确实为
IopParseDevice()。。。。。

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

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

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

在双击内核调节和测试环境中,首先通过配备名称“\Device\QQProtect”取得相应对象的新闻:

在双击内核调节和测试环境中,首先通过设备名称“\Device\QQProtect”取得相应对象的新闻:

在双击内核调节和测试环境中,首先通过配备名称“\Device\QQProtect”取得相应对象的音讯:

home88一必发 33

home88一必发 34

home88一必发 35

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

收获目的头地址后,格式化并转储个中的字段,我们感兴趣的是“TypeIndex”字段,它用来索引“对象类型表”中的相应“对象类型”:

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

 

 

 

home88一必发 36

home88一必发 37

home88一必发 38

WInodws
内核使用贰个数据结构——ObTypeIndexTable
存放有关各类“对象类型”的消息,本质上 ObTypeIndexTable
是贰个指针数组,在 3二 位连串布局上,每种指针大小
四 字节,而我们获得的索引号为(下标**
0
开始**)1玖,下图中的两条表达式据此计算出该“对象类型”的地方:

WInodws
内核使用1个数据结构——ObTypeIndexTable
存放有关种种“对象类型”的消息,本质上 ObTypeIndexTable
是三个指针数组,在 3二 位体系布局上,每种指针大小
四 字节,而我们获取的索引号为(下标**
0
开始**)1九,下图中的两条表明式据此计算出该“对象类型”的地方:

WInodws
内核使用一个数据结构——ObTypeIndexTable
存放有关种种“对象类型”的消息,本质上 ObTypeIndexTable
是一个指南针数组,在 3二 位种类布局上,每一种指针大小
四 字节,而笔者辈获得的索引号为(下标**
0
开始**)1九,下图中的两条表明式据此测算出该“对象类型”的地点:

home88一必发 39

home88一必发 40

home88一必发 41

由此可见,相应“对象类型”结构的地点为
0x855cef78——Windows 内核用数据结构 _OBJECT_TYPE
来表示“对象类型”的概念,所以重复
格式化并转储个中的字段,大家感兴趣的字段为“TypeInfo”,如前所述,它是四个“对象类型初叶化设定”结构,内核用
_home88一必发,OBJECT_TYPE_INITIALIZER
来表示“对象类型开始化设定”的概念。供给专注,TypeInfo
偏移它的母结构起头地址 0x28字节,所以要抬高这几个
offset
再查看,如您所见,当中的“ParseProcedure”为
IopParseDevice()

测算,相应“对象类型”结构的地点为
0x855cef78——Windows 内核用数据结构 _OBJECT_TYPE
来表示“对象类型”的概念,所以重复
格式化并转储在那之中的字段,我们感兴趣的字段为“TypeInfo”,如前所述,它是二个“对象类型起始化设定”结构,内核用
_OBJECT_TYPE_INITIALIZER
来代表“对象类型伊始化设定”的定义。须求专注,TypeInfo
偏移它的母结构早先地址 0x28字节,所以要加上那个
offset
再查看,如您所见,当中的“ParseProcedure”为
IopParseDevice()

估测计算,相应“对象类型”结构的地方为
0x855cef78——Windows 内核用数据结构 _OBJECT_TYPE
来表示“对象类型”的概念,所以重复
格式化并转储当中的字段,大家感兴趣的字段为“TypeInfo”,如前所述,它是贰个“对象类型开头化设定”结构,内核用
_OBJECT_TYPE_INITIALIZER
来表示“对象类型初叶化设定”的定义。须要专注,TypeInfo
偏移它的母结构初叶地址 0x2捌字节,所以要丰硕这么些
offset
再查看,如您所见,个中的“ParseProcedure”为
IopParseDevice()

 

 

 

home88一必发 42

home88一必发 43

home88一必发 44

 

 

 

下卷小说将研究怎么着绕过
IopParseDevice() 的调用源检验,并调节和测试我们的成果,将其行使于 rootkit
开发技术中。

下卷小说将切磋哪边绕过
IopParseDevice() 的调用源检验,并调节和测试大家的收获,将其行使于 rootkit
开发技术中。

下篇文章将研商哪些绕过
IopParseDevice() 的调用源检查测试,并调节我们的战果,将其选取于 rootkit
开发技术中。

 

 

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图