调用源检测逻辑www.5929.com:

2019-06-15 19:50栏目:www.5929.com
TAG:

 

 

www.5929.com 1

然而,OPEN_PACKET 结构中唯有三个字段不是 “原生” 定义的——那就是 “PDUMMY_FILE_OBJECT” 类型,要求包括其余头文件才不形成编写翻译器报错。

也正是说,大家平昔复制 IopCreateFile() 中的 OPEN_PACKET 结构初阶化部分逻辑就行了?

www.5929.com 2

www.5929.com 3

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

 

nt!ExInterlockedPopEntrySList() 调用时,kd.exe 就卡住了,不能继续追踪此后的调用链。从稍早的栈回溯音讯来看,与源码仲春大家估摸的调用种类大概相符,只是不晓得为何在 nt!ObpAllocateObjectNameBuffer() 中,为了给传入的驱动对象名称 “DeviceQQProtect” 分配内核内部存款和储蓄器,调用 nt!ExInterlockedPopEntrySList(),而后者却无计可施追踪。。。。是虚拟机境遇的开始和结果,还是原子操作类函数的不可分割性质?

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

“-y” 钦赐符号文件的职位(机器指令中从不内核函数与变量的标识,所以调节和测试器供给查找额外的标识以向用户显示人类可读的名号);
“-k” 参数钦赐调节和测试类型为 “取名管道模拟串口1”,Porter率数值越高,响应越快。

www.5929.com 4

作者的消除方案是,直接把该字段的扬言所在行注释掉,下图突显了该字段具体的职位(在 “iomgr.h” 中的行号),方便各位神速寻找:

消除办法也很轻巧,我们的驱动中,不要借助理编辑译时刻的计量,间接把 “Size” 字段的值硬编码为 0x70 不就好了?

 

接轨的博文将研讨哪些将这种技能用在 rootkit 中,同不日常候适应现阶段风行的相辅相成多管理器(SMP)景况。

本人想大概是因为基础源码版本的变通,导致相关例程的决断逻辑也不等同了,不可能依靠前一版源码的逻辑来编排预计运维在后一版内核上的驱动。

因为 OPEN_PACKET 结构一样未有当面包车型大巴文书档案来叙述,所以依旧在大家的驱动力源码中用  “#include” 包括定义它的头文件,要么直接复制定义的那部分黏贴进来。很分明,后者相比轻便——OPEN_PACKET 在根本源码的 “iomgr.h” 中定义,而该头文件又嵌套包罗了一群杂七杂八的内核头文件,要清理这几个嵌套包罗关系很费劲,而且最主要的是,内部有个别头文件定义的数据类型会与驱动开垦中用的 “ntddk.h” 和“wdm.h”重复,引起编写翻译器的埋怨。就此直接在 “iomgr.h” 中寻找字串 “typedef struct _OPEN_PACKET”,把找到的定义块拷贝进来就能够。

接触软件断点后,大家一般会用 “kv” 命令查看栈回溯音信,它披暴光我们的驱动入口点 DriverEntry() 是由 I/O 管理器的 IopLoadDriver() 调用的:

www.5929.com 5

依照上述办法加载时,就能够活动触发我们设定好的软件断点,就能够在宿主机中检查虚拟机的基石空间。
其余还需注意一点:编写翻译驱动时的 “营造” 情形应该接纳 Check Build,那样会一并生成同名称的号子文件,后缀为 “.pdb”,从而调节和测试器能够显得大家同舟共济驱动中的函数与变量名称,升高调节和测试效能,如下图:

 

参数 “logo” 钦点要把全路调节和测试进程的出口新闻写入日志;

 

 

在上一篇文章中,大家早就看到 IopParseDevice() 怎么着对传播的 OPEN_PACKET 结构进行表明。若是ObReferenceObjectByName() 的调用者未有分配并初叶化第八个参数 ParseContext,而仅是粗略地扩散 “NULL” ,那么当调用链深切到 IopParseDevice() 内部时,就能因验证失利重返 C0000024(STATUS_OBJECT_TYPE_MISMATCH)。

那是小编的美好期待,但具中华全国体育总会是狂暴的,在自己追踪到原子操作连串函数

附带说一下,依照 A 设备名得到 A 设备对象的指针,然后把 rootkit/本身驱动创造的黑心设备 attach 到 A 设备所在的设施栈,从而阻碍检查通过 A 设备的 IRP 内数据。。。。这种措施已经比较过时了,因为今后反病毒软件的水源格局组件也会检查这几个设施栈,搜索别的相配特征码的黑心设备,再者,内核调试器的 “!devstack” 命令很轻松遍历揭发出给定设备所在的设施栈内容,被大规模用于Computer考查取证中,从 rootkit 的第一指标——完成隐身——的角度来看, attach 到器具栈就不是三个好标准。

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

www.5929.com 6
——————————————————————————————————————————————————————————————————

继续按下 “t” 单步实行,如下图所示,你能够看看,ExAllocatePoolWithTag() 的第四个参数,分配的基本内部存款和储蓄器大小为 0x70 字节,因为自个儿在宏定义中硬编码了那几个值,而不是用 sizeof(OPEN_PACKET) 表明式让编译器总括;另一方面,图中的 “dt” 命令也证实了它的分寸为 0x70 字节。

一句话来讲,基于以上理由作者不也许持续跟进到 ObpLookupObjectName() 里面查看它是或不是推行了 IopParseDevice() 回调,从而无法明显毕竟为啥后者再次来到 C0000024。

www.5929.com 7

实则化解方案照旧有个别,比较花时间而已,正是运用 “u” 指令反汇编 ObpLookupObjectName() 发轫处对应的机器指令,再反编写翻译成类似的 C 伪码,与 NT 5.2 版内核源码相比,搜索里面改造的地点,但那是一个费时费劲的干活,且收入甚微,还比不上直接在网络络搜释出的 NT 6.1 版内核源码,只怕临近的本子,再思量绕过的不二等秘书技。

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

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

以下图为例子吗,传递给 nt!ExAllocatePoolWithTag() 的四个参数(从左到右)便是00000000(NonPagedPool),00000070(笔者硬编码的值),704f6f49(ASCII 字符串“pOoI”),同理,传递给 hideprocess!DriverEntry() 的首先个参数 867c3550 是 _DRIVER_OBJECT 结构的地点,由I/O 处理器加载它时为它分配(注意与源码中 DriverEntry() 定义的一枚 _DRIVER_OBJECT 指针分裂,“Args to Child”

www.5929.com 8

讲一些废话,一般大家在栈回溯中观看的顶层表达行,有三个 “Args to Child” 项目,表示调用者传递给它的参数,不过最多也只好展现前四个。

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

www.5929.com 9

为了搜索故障原因,作者在分配 OPEN_PACKET 逻辑的前方利用内联系汇率编增添了一个软中断 “__asm{ int 3; }  ”,宿主机器上运维水源调节和测试器 kd.exe,作者的开发银行参数疑似那样:

栈的顶层函数 “ReferenceDeviceAndHookIRPdispatchRoutine 0x56” 是本人增多软中断的地点。施行 “r” 命令查看当前的 x86 通用寄存器状态,EIP 指向地址 0x8f4a3196 ,执行 “u hideprocess!ReferenceDeviceAndHookIRPdispatchRoutine 0x56 L2”,反汇编输出的率先行地址正是 0x8f4a3196,与 EIP 的值相符;第二行是把二个 16 进制值 “ 704F6F49h” 压栈,实际上它是 ASCII 字符 “pOoI” 的 16 进制编码,换言之,那是在通过内核栈传递 ExAllocatePoolWithTag() 的第多少个参数(从右往左传递,请纪念以前的 IopAllocateOpenPacket() 宏定义那张图)。

反而,通过 ObReferenceObjectByName() 总是能够收获驱动对象的指针,进而能够 hook 该驱动的 IRP 分发例程,这种手法隐蔽性相当高,而且不便于被检查实验出来。

只顾,NT 6.1 版内核在编写翻译时刻的 OPEN_PACKET 结构显然是未经 “恶意” 修改的,所以编写翻译器为其 “sizeof(OPEN_PACKET)” 表达式总结 0x70 的值,而小编辈在大团结的驱动中拿掉了 OPEN_PACKET 当中二个字段使得编写翻译器为发挥式 “sizeof(OPEN_PACKET)” 预总括 0x58 的值(前面包车型客车调整阶段会阐明),那会招致 “Size” 字段不是 IopParseDevice() 内部逻辑预期的 0x70,从而导致再次来到C0000024(STATUS_OBJECT_TYPE_MISMATCH)。

把重新编写翻译好的驱动放到虚拟机中,在提升权限后的吩咐提示符中推行 bcdedit.exe,启用调试情势,那样重启虚拟机后,就能够进入调节和测试方式(不必要在开行进程中按下 F8 选拔菜单)。

此地还应该有二个标题,肩负分配该组织体内核内部存款和储蓄器的例程 IopAllocateOpenPacket() 是七个宏,Visual C 二〇一六 中提交它是用 ExAllocatePoolWithTag() 定义的。那就好办了,在我们和睦的驱动力源码中,加多相应定义就能够,如下图:

自家把温馨的驱动达成成按需加载,也正是选取服务调整管理器sc.exe)发出命令来动态加载和卸载,达成此意义的关照批管理文件内容如下图,注意该文件要放在虚拟机中奉行,“start= demand” 表明通过 sc.exe 按需运营;“binpath” 正是驱动文件存放的磁盘路线,倘诺自个儿的驱动名为hideprocess.sys,施行该批处理职责后,就在有关的注册表地方增多了一项,以后只需在 cmd.exe 中实施 “sc.exe start/stop hideprocess” 就能够动态加卸载。

列出的数目一定于试行解引操作符 * 后的结果),第叁个参数是 UNICODE_ST本田CR-VING 结构的地点,对应源码定义中的一枚 _UNICODE_ST奥迪Q3ING 指针,该组织中储存的是大家驱动在注册表中的完整路线:

很不幸的是,小编把编写翻译出来的驱动放到虚拟机(Windows 7,基于 NT 6.1 版内核)里面动态加载测试,依然不能够取获得

大家依照源码中的暗中提示来追踪OPEN_PACKET 结构终究在哪分配的,如前所述,调用链 NtCreateFile->IoCreateFile()->IopCreateFile() 的末段,也正是在 IopCreateFile() 内部,实际担任 OPEN_PACKET 的初步化。下边贴出的代码片段以 NT 5.2 版内核源码为样例:

 

本人不想浪费时间在翻看内核内部存款和储蓄器的分配细节上,所以自个儿按下 “p”,步过 ExAllocatePoolWithTag() 函数调用,接下去的 cmp/jne 汇编系列对应源码中检查是否成功分配了内部存款和储蓄器并用于 openPacket 指针,实际的实践结果是跳转到地址 0x8f4a31c6 ,对应源码中起先化 OPEN_PACKET 结构前三个字段的逻辑:

 

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

www.5929.com 10

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

其余,由于 IopAllocateOpenPacket() 等价于 ExAllocatePoolWithTag(),而后者平常重回泛型指针(“ PVOID ,亦即 void * ”),
之所以自身强制把它转型为与 “openPacket” 一致的品种。
万事俱备,“东风” 就在于调用 ObReferenceObjectByName() 时,为第七个参数传入“openPacket” 就可以,上海教室体现的很精晓了。

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

 

www.5929.com 11

正如图所示,你还或然会注意到,我把 “Type” 字段的常量 “IO_TYPE_OPEN_PACKET” 改成了相应的数值,以管教一旦。

 

 

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

接下来直白单步实施到调用 ObReferenceObjectByName() 前夕,在此处大家要 “步入” 它的中间,进行故障排查,所以按下 “t” 跟进,这里有贰个小技能,大家早已解析过 ObReferenceObjectByName() 的源码,知道它会调用许多函数,而且大概通晓难题出现在 ObpLookupObjectName() 里面,所以指令 “tc”能够追踪到种种函数调用处结束,再由用户决定是或不是跟进该函数内部。

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

 

版权声明:本文由澳门皇家赌场网址导航发布于www.5929.com,转载请注明出处:调用源检测逻辑www.5929.com: