阅读:2452回复:2
{活动}关于驱动的简单逆向
一些几年前无聊写的乱七八糟无技术含量的东东,算是一点小小的总结吧。
驱动的逆向,其实说难不难,说简单也不简单,逆向者,原本就是倒推,怎么来怎么回去,不过如果不懂“怎么来”,那倒推回去根本无从谈起。所以基础还是比较重要的。 首先还是要熟悉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看看,果然如此。 综上所述,其实驱动的逆向并不难,无什么奇技淫巧,唯手熟尔。熟悉的编写驱动,你就离逆向进了一大步 |
|
最新喜欢:sijin |
沙发#
发布于:2010-12-31 01:46
好东西顶着学习了,谢谢LZ
|
|
|
板凳#
发布于:2011-01-05 22:06
路过,学习,赞一个
|
|