rku逆向分析 膜拜XueTr的linxer大牛

转载 2011年01月11日 17:21:00
这个驱动本来准备端午节搞的,但后来端午节去了躺北京玩了几天,也就搁置了...最近连续花了4个晚上,大致把它搞的差不多了,有些收获...初学window驱动,水平很菜,有些东西我也未必清明,加上3环的代码还没有吃透,期间也没有用调试器跟踪,全是IDA(F5)静态分析的,谬误在所难免,高手请飘过,希望对菜鸟学习有点帮助.

1.SSDT检测

这个功能有三个IoControlCode与之对应,他们分别是22000fh(拷贝KeServiceDescriptorTable);220007h(拷贝KeServiceDescriptorTable->ServiceTable);22000bh(恢复一个ssdt hook),这个功能目前还不具备检测和恢复inline hook的功能

2.Shadow SSDT检测

这个功能实现和SSDT差不多,都是从KeSystemServiceDescriptorTableShadow入手,不过3环需要为每个平台配置一张函数名表(ssdt可以不配置函数名表,可以从ntdll.dll中收集),详细文章可以参见zhuwg兄弟写的<<shadow ssdt学习笔记>>一文

3.进程

3.1 进程检测

IoControlCode是22001Bh,在检测之前会设置检测方式,然后根据检测方式进行检测.这个功能主要由irp_mj_device_control_dispatch_function函数的is_22001Bh_list_process分支完成,这里集成了4种检测方法,大致如下:

3.1.1 基于PspCidTalbe的检测,这里rku对句柄表做了解析,对每个Object判定是不是EPROCESS,是则插入到输出列表(icesword也有这中检测,不过在1.22中没有解析句柄表,而是用ExEnumHandleTable搞定这些) 详细代码见list_process_in_2k_by_handle_table/list_process_in_not_2k_by_handle_table函数
3.2.1 基于KiWaitListHead/KiWaitOutListHead的检测,这个检测方法很简单,关键是KiWaitListHead/KiWaitOutListHead两个链表的获取, 详细代码见list_process_by_list_head函数
3.3.1 如果是xp系统则还会采用*淫**荡*的内存暴力搜索进程进行检测,这段代码看debugman的yykingking发过, 详细代码在list_process_by_search_memory_in_xp函数
3.4.1 rku还会inline hook SwapContext函数,在这个函数里会记录当前的活动进程情况,经过上面三种方法的洗礼后,对在SwapContext的记录里的,但不在输出列表里的继续加入,当然是有判定条件的(条件就是EPROCESS不能在ntoskrnl模块内,即不为idle进程). BTW:这里有个逻辑我觉得有问题:

.text:000134A7 loc_134A7: ; CODE XREF: irp_mj_device_control_dispatch_function+233j
.text:000134A7 3B 05 34 4E 01 00 cmp eax, g_nCurrentProcessCount
.text:000134AD 7D 5A jge short loc_13509
这个检测方法的代码就在loc_134A7开始位置

上面获取的只是EPROCESS,要获取进程路径信息,还需要IoControlCode(220047h)的代码, 详细功能代码在get_image_path_by_eprocess函数里,在这个函数里,我们可以看到rku先走peb获取进程全路径,然后对非2k系统再走一次我们更为熟悉的SectionObject获取路径

3.2 杀进程 rku提供了两种杀进程的方法

3.2.1 IoControlCode(22001Fh) ZwOpenProcess/ZwTerminateProcess/ZwClose杀进程 这种杀法比较的弱
3.2.2 ioControlCode(22004fh) 内存清0杀进程 具体代码是kill_process_by_fill_zero函数,这个代码看debugman的yykingking也发过

3.3 Dump All Process Memory

IoControlCode是22008bh, 没什么可说的, 详细代码在dump_all_process_memory函数

3.4 Dump Seleted

这个就是拷贝主程序的内存镜象, IoControlCode是220083h, 先获取文件大小(对xp及其以上系统,通过EPROCESS->SectionObject->segmentObject->SizeOfSegment获取主程序内存镜象大小,对2k系统,由于手头缺乏资料,那段代码什么意思不知道,详细代码在get_main_file_size_by_eprocess函数), 然后输出缓冲区足够大就进入dump_selected函数拷贝内存

4.内核模块和Stealth Code检测

IoControlCode是0x220023h,在检测之前也会设置检测方式,然后根据检测方式进行检测.这个功能主要由list_kernel_module函数完成,这个函数里面集成了很多检测方法,很多方法都比较*淫**荡*,大致的检测方法有:

4.1 用IoDriverObjectType指向的OBJECT_TYPE.TypeList链表检测,遍历这个链表中的每一项,并会取每个DriverObject上的DeviceObject,并向上扫描这个设备所在的设备栈(注意这里没有向下扫描),尝试发现其它的DriverObject 详细代码见list_module_by_IoDriverObjectType函数
4.2 用IoDeviceObjectType指向的OBJECT_TYPE.TypeList链表检测,遍历这个链表中的每一个设备,并也会向上扫描这个设备所在的设备栈(注意这里没有向下扫描),尝试发现其它的DriverObject 详细代码见list_module_by_IoDeviceObjectType
4.3 用目录对象树(ZwOpenDirectoryObject("//"))检测,遍历这棵树,对叶子节点(具体对象)看其OBJECT_HEADER.Type字段是否指向IoDriverObjectType/IoDeviceObjectType,如果是的话,则会采用4.1/4.2相似的措施;对目录对象子树则递归处理之(内核堆栈空间太小,递归搞始终给人一种不安全感,看SnipeSword里面处理注册表部分也大量递归,比较汗) 详细代码见list_module_by_OpenDirectoryObject函数
4.4 用DriverSection(PsLoadedModuleList链表)检测,这个方法大家都比较熟悉, 详细代码见list_module_by_DriverSection函数

经过上面4个方法,DriverObject就获取完毕了,他们对应的都是有详细信息的内核模块(这项检测初步给人的感觉是比icesword可靠些,icesword则是先尝试恢复NtQuerySystemInformation,设置KernelMode,然后调用NtQuerySystemInformation获取内核模块信息),下面的检测主要是对一些零星的能执行代码的内存块进行检测(Stealth Code)

4.5 用上面几种方法已经找到了一些DriverObject,这里就对这些DriverObject下手,检测这些DriverObject的DriverStartIo/MajorFunction是否被hook,如果被hook且新地址不在我们已经找到的模块里,则说明是那种分内存,写代码似的hook,记录这块内存信息 详细代码见list_module_by_DriverStartIo_and_MajorFunction函数
4.6 暴力搜索内存, 找到PE头部,并判定OptionalHeader.Subsystem是否是Native 详细代码见list_module_by_scan_memory函数
4.7 利用句柄表检测,这个的具体原理我未能理解, 详细代码在list_module_use_suspicious_thread_by_handle_table_in_not_2k/list_module_use_suspicious_thread_by_handle_table_in_2k这两个函数,感觉跟内核模块检测无关......知道的请说一声
4.8 rku会inline hook三个调用频度很高的函数(ExAllocatePool/ExAllocatePoolWithTag/KeDelayExecutionThread),在这三个函数里会记录它们的返回地址,并利用这些地址来检测一些模块,如果返回地址不在某具体模块范界则会记录其内存信息 详细代码见list_module_by_return_address函数
4.9 检测KiSystemService/KiFastCallEntry是否在某具体模块范界,如果不在也记录其内存信息

到这里检测就完成了,上面的检测方法太多,有些检测获取的信息不足,rku会进行一些额外的修正处理,这些代码都在list_kernel_module的结尾部分,详细请参见源码,我都做了一些注释

5.File检测

由于目前一直在用IDA反,并没有使用调试器,主程序目前还只反了一点,这个部分具体做什么的,我不太清楚,不过在驱动里看到一个IoControlCode(2200A7)是在做扇区级别的操作......

6.Code Hooks检测

在驱动里并没有看到分析code hooks的代码, 只看到一些拷贝内存到3环的功能函数,把一些系统关键手工load展开后,进行内存对照比较就可以搞定这个了,当然这个里面还具备KiSystemService/KiFastCallEntry hook的检测和恢复代码,详细可以看IDB文件

7.rku的进程保护

7.1 ssdt上的保护,在ssdt上对三个函数(NtOpenProcess, NtOpenThread, NtDuplicateObject)进行了inline hook
NtOpenProcess 防止打开rku进程
NtOpenThread 防止打开rku的线程
NtDuplicateObject 防止复制rku进程的句柄

7.2 shadow ssdt上的保护,在shadow上对四个函数(NtUserQueryWindow, NtUserFindWindowEx, NtUserWindowFromPoint, NtUserNotifyIMEStatus)进行了inline hook,防止其它程序通过FindWindow,WindowFromPoint等函数来枚举rku的窗口,你可以看到spy++对rku已经失效

8.逆向这个的过程中,参考了网上很多大牛的文章,
IceSword&Rootkit Unhooker驱动简析
zhuwg <<shadow ssdt学习笔记>>
prince 翻译的<<侦测隐藏进程的强文>>
yykingking 发在debugman上的两个代码片段
还有些文章,无法一一列举,再次一并表示感谢

大致就是这样了.
linxer 2008-06-19 于哈尔滨

相关文章推荐

隐藏驱动模块(源码)

XP亲测有效,使用我们自己编写的枚举驱动模块会看不到。枚举驱动模块请看文章 http://blog.csdn.net/liujiayu2/article/details/72822478 但是使用A...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

仿mybatis逆向工程

/** * */ package com.b510.base.bean.install; import java.io.File; import java.io.FileWriter; imp...

鬼哥教你去广告之弹出广告

今天,我们再一次来到鬼哥教你去广告的小课堂,现在我们讲解的是去除插屏弹出广告,如下图所示的广告类型:...

VMP1.8的IAT分析,同时膜拜一下Nooby大牛

首先说一说VMP1.8,当然大家认为壳很老了,直接跑脚本就可以了,但本人并不是这麽认为,本人可能比较执拗的人,一定要知其然,知其所以然(所以学得慢吧,也许,呵呵。) 看了kissy的壳世界,对VMP...

linxer大侠的安全分析工具XueTr

  • 2009年09月25日 22:56
  • 260KB
  • 下载

速来膜拜!20位活跃在Github上的国内技术大牛

本文列举了20位在Github上非常活跃的国内大牛,看看其中是不是很多熟悉的面孔? 1. lifesinger(玉伯) Github主页: https://github.com...
  • Vic__li
  • Vic__li
  • 2015年11月25日 15:23
  • 708

Github上最受关注的前端大牛,快来膜拜吧!

github前端前端开发javascript开源名人堂 本文列出了Github上最受关注的10位前端大牛。看看他们负责的项目和提交的代码,你是不是能从中学到些什么? 1. Paul Iri...

Github上最受关注的前端大牛,快来膜拜吧!

2014-08-20  出处:code.csdn.net 作/译者: CSDN CODE   本文列出了Github上最受关注的10位前端大牛。看看他们负责的项目和提交的代码...

速来膜拜!20位活跃在Github上的国内技术大牛

原文地址:http://code.csdn.net/news/2821086/2
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:rku逆向分析 膜拜XueTr的linxer大牛
举报原因:
原因补充:

(最多只允许输入30个字)