guoyuekun
驱动牛犊
驱动牛犊
  • 注册日期2008-08-12
  • 最后登录2011-08-19
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望39点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2452回复:2

{活动}关于驱动的简单逆向

楼主#
更多 发布于:2010-12-29 20:40
    一些几年前无聊写的乱七八糟无技术含量的东东,算是一点小小的总结吧。
  驱动的逆向,其实说难不难,说简单也不简单,逆向者,原本就是倒推,怎么来怎么回去,不过如果不懂“怎么来”,那倒推回去根本无从谈起。所以基础还是比较重要的。
  首先还是要熟悉IDA的使用,这个是逆向的利器,而且最好还是懂点汇编,Hex-ray的F5在某些情况下不是很智能……
  这里以两个简单的SSDT钩子以及还原的驱动的逆向做说明……高手路过。
  首先拿到驱动的时候,没必要直接开始着手,可以先看看import等(IDA的红色区域),比如:
.idata:00010608 ; void __stdcall RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
.idata:00010608                 extrn __imp_RtlInitUnicodeString:dword
.idata:00010608                                         ; DATA XREF: RtlInitUnicodeStringr
.idata:0001060C ; void __stdcall IoDeleteDevice(PDEVICE_OBJECT DeviceObject)
.idata:0001060C                 extrn __imp_IoDeleteDevice:dword
.idata:0001060C                                         ; DATA XREF: IoDeleteDevicer
.idata:00010610 ; NTSTATUS __stdcall IoCreateSymbolicLink(PUNICODE_STRING SymbolicLinkName, PUNICODE_STRING DeviceName)
.idata:00010610                 extrn __imp_IoCreateSymbolicLink:dword
.idata:00010610                                         ; DATA XREF: IoCreateSymbolicLinkr
.idata:00010614 ; NTSTATUS __stdcall IoCreateDevice(PDRIVER_OBJECT DriverObject, ULONG DeviceExtensionSize, PUNICODE_STRING DeviceName, ULONG DeviceType, ULONG DeviceCharacteristics, BOOLEAN Exclusive, PDEVICE_OBJECT *DeviceObject)
.idata:00010614                 extrn __imp_IoCreateDevice:dword
.idata:00010614                                         ; DATA XREF: IoCreateDevicer
.idata:00010618                 extrn __imp_IoCompleteRequest:dword
.idata:00010618                                         ; DATA XREF: IoCompleteRequestr
.idata:0001061C                 extrn __imp_KeServiceDescriptorTable:dword
.idata:0001061C                                         ; DATA XREF: KeServiceDescriptorTabler
.idata:00010620 ; ULONG DbgPrint(PCH Format, ...)
.idata:00010620                 extrn __imp_DbgPrint:dword ; DATA XREF: DbgPrintr
.idata:00010624 ; NTSTATUS __stdcall IoDeleteSymbolicLink(PUNICODE_STRING SymbolicLinkName)
.idata:00010624                 extrn __imp_IoDeleteSymbolicLink:dword
.idata:00010624                                         ; DATA XREF: IoDeleteSymbolicLinkr
.idata:00010628 ; void __fastcall IofCompleteRequest(PIRP Irp, CCHAR PriorityBoost)
.idata:00010628                 extrn __imp_IofCompleteRequest:dword
.idata:00010628                                         ; DATA XREF: IofCompleteRequestr
.idata:0001062C
.idata:0001062C
这些大多数都是驱动的常用函数,比如创建符号链接,设备等,要注意的是特别的东西,比如导出的KeServiceDescriptorTable,熟悉这个的都知道,这是SSDT表,基本上我们就有了大概的方向了。
 IDA一般会识别一些公用的函数,比如IoCreateSybolicLink之类的,我们需要注意的只是各个sub函数,比如其中一个sub:
sub_102E0 proc near
mov     eax, offset KeServiceDescriptorTable  //指针,指向SSDT表
mov     eax, [eax]
retn
sub_102E0 endp
很简单,如果稍稍懂点汇编直接就能看出来这是对SSDT相关的,sub当中还有一些完成例程相关的函数和代码,这些也是通用的,可以无视。
sub_105E4 proc near
mov     eax, [eax+60h]
retn
sub_105E4 endp
这里是基地址+索引的方式定位还原SSDT,类似于:
pBase = KeServiceDescriptorTable->pvSSDTBase;
 *((PULONG)OutputBuffer) = *( pBase + uIndex );
这类处理方式。

对于SSDT HOOK,则又是一种情况,当然大体上差不多:
mov     eax, offset KeServiceDescriptorTable
mov     eax, [eax]
retn
依旧是定位,这个几乎已经成了SSDT XX的标志了。
鉴于SSDT HOOK的函数定位方式:KeServiceDescriptorTable->ServiceTableBase + 函数ID* 4,那么我们只需要找到那个基地址,看看值加了多少,然后除以4,就可以得到ID,也就可以通过ID反查函数了,很简单,不是吗?
比如,我们跟踪到此处:
push    ebp
mov     ebp, esp
mov     eax, [ebp+DriverObject]
mov     dword ptr [eax+34h], offset sub_111FD
call    sub_1118F
mov     eax, [eax]
add     eax, 0E4h
mov     dword_13004, eax
mov     eax, dword_13004
mov     eax, [eax]
mov     dword_13008, eax
mov     eax, dword_13008
mov     dword_1300C, eax
cli
mov     eax, cr0
and     eax, 0FFFEFFFFh
mov     cr0, eax
mov     eax, offset sub_111F4
mov     edx, dword_13004
mov     [edx], eax
mov     eax, cr0
or      eax, 10000h
mov     cr0, eax
看到cli和公式化的mov Cr0,eax,再迟钝的人也意识到了吧,这一段就是SSDT HOOK的过程,开中断——写入——关中断。定位成功后,在临近的函数找找,很快就有发现:
sub_1118F proc near
mov     eax, offset KeServiceDescriptorTable
mov     eax, [eax]
retn
sub_1118F endp

call    sub_1118F
mov     eax, [eax]
add     eax, 0E4h //加了16进制的E4
鉴于上面的1118F已经定位了SSDT的基地址,那么很显然这个E4h就是目标,除以4得到39,查查ID索引,恩,NtDebugActiveProcess,加载驱动后用ARK看看,果然如此。
综上所述,其实驱动的逆向并不难,无什么奇技淫巧,唯手熟尔。熟悉的编写驱动,你就离逆向进了一大步

最新喜欢:

sijinsijin
sijin
驱动牛犊
驱动牛犊
  • 注册日期2008-03-31
  • 最后登录2017-06-08
  • 粉丝0
  • 关注0
  • 积分22分
  • 威望122点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2010-12-31 01:46
好东西顶着学习了,谢谢LZ
努力学习号技术
eleqi
驱动小牛
驱动小牛
  • 注册日期2005-12-20
  • 最后登录2014-01-03
  • 粉丝4
  • 关注2
  • 积分172分
  • 威望1475点
  • 贡献值0点
  • 好评度115点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2011-01-05 22:06
路过,学习,赞一个
游客

返回顶部