SERVICE_BOOT_START 驱动程序逆向

原创 2007年09月21日 08:33:00

21:33 2007-9-20

今天发现了 syser debugger  的 SDbgMsg.sys。 这个驱动程序就是SERVICE_BOOT_START  类型的驱动程序, 在windows 启动后最新给出提示信息 "Press "ESC" to Cancel Load Syser Boot  Module ",我想看看到底是怎样编程实现的:


打开 IDA 载入 SDbgMsg.sys 程序, 反汇编代码如下:


; int __stdcall start(PDEVICE_OBJECT DeviceObject)
public start
start           proc near

SymbolicLinkName    = UNICODE_STRING ptr -18h
DeviceName              = UNICODE_STRING ptr -10h
SystemRoutineName = UNICODE_STRING ptr -8
DeviceObject             = dword ptr  8       

.text:00010850 push    ebp             
.text:00010851 mov     ebp, esp                  ; 打开栈帧

.text:00010853 sub       esp, 18h
.text:00010856 push     ebx
.text:00010857 push     esi
.text:00010858 mov      esi, [ebp+DeviceObject]
.text:0001085B push    edi
.text:0001085C push    1Bh
.text:0001085E lea       edx, [esi+38h]
.text:00010861 pop      ecx                         ; 给ecx赋值 1Bh
.text:00010862 mov     eax, offset loc_10428
.text:00010867 mov     edi, edx
.text:00010869 rep stosd

上面的反汇编代码可能有问题, DeviceObject 应该是 DirverObject。如果是 DeviceObject ,那偏移 38H 位置是
DeviceObject->Queue.Blink 或者是 DeviceObject->Queue.Wcb.WaitQueueEntry.Blink 。我想不出 DeviceObject 的这些成员怎么使用。一般情况下程序开始时就是设置 Dispatch 例程, 而 DriverObject 的 Dispatch 例程就是在 38H 偏移位置, 所以我可以认为这里的 DeviceObject 就是 DriverObject。
可见 loc_10428 例程就是通用的派遣例程.

下面是DeviceObject 的偏移为38H 位置的结构图
       下面是 DriverObject 偏移为 38H 位置的结构图


.text:0001086B mov     edi, ds:RtlInitUnicodeString
.text:00010871 push    offset aDeviceSyserdbg ;          "
//Device//SyserDbgMsg"
.text:00010876 lea       eax, [ebp+DeviceName]
.text:00010879 push    eax             ; DestinationString

; 设置 DirverObject->DriverUnload = sub_10702
.text:0001087A mov     dword ptr [esi+34h], offset sub_10702

; 设置 DirverObject->MajorFunction[IRP_MJ_CREATE] = loc_103DC
.text:00010881 mov     dword ptr [edx], offset loc_103DC    

; 设置 DirverObject->MajorFunction[IRP_MJ_READ] = sub_10646
.text:00010887 mov     dword ptr [esi+44h], offset sub_10646

; 设置 DirverObject->MajorFunction[IRP_MJ_CLOSE] = loc_103F8
.text:0001088E mov     dword ptr [esi+40h], offset loc_103F8

; 设置 DirverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = loc_10442
.text:00010895 mov     dword ptr [esi+70h], offset loc_10442

.text:0001089C call    edi ; RtlInitUnicodeString

.text:0001089E                 lea       eax, [ebp+DeviceObject]
.text:000108A1                 push    eax             ; DeviceObject
.text:000108A2                 xor      ebx, ebx
.text:000108A4                 push    ebx             ; Exclusive
.text:000108A5                 push    ebx             ; DeviceCharacteristics
.text:000108A6                 push    22h             ; DeviceType
.text:000108A8                 lea       eax, [ebp+DeviceName]
.text:000108AB                 push    eax             ; DeviceName
.text:000108AC                 push    ebx             ; DeviceExtensionSize
.text:000108AD                 push    esi             ; DriverObject
.text:000108AE                 call     ds:IoCreateDevice


.text:000108B4                 test      eax, eax
.text:000108B6                 jl          short loc_108E6
.text:000108B8                 mov      eax, 2000h
.text:000108BD                 push    eax             ; BugCheckParameter1
.text:000108BE                 mov     dword_1221C, eax
.text:000108C3                 mov     dword_12220, ebx
.text:000108C9                 call      sub_10FD6
.text:000108CE                 cmp     eax, ebx
.text:000108D0                 pop      ecx
.text:000108D1                 mov     dword_12224, eax
.text:000108D6                 jnz       short loc_108F0
.text:000108D8                 push    [ebp+DeviceObject] ; DeviceObject
.text:000108DB                 call     ds:IoDeleteDevice

NTSTATUS NtStatus= IoCreateDevice( esi, 
      0,
      "
//Device//SyserDbgMsg",  // UNICODE_STRING 类型的变量
      22h,                                   // FILE_DEVICE_UNKNOWN 
      0,
      0,
      DeviceObject );
if (STATUS_SUCCESS != NtStatus)
{
   退出; 
}

sub_10FD6 ( , 2000h);

.text:000108F0                 mov     eax, [ebp+DeviceObject]
.text:000108F3                 or        dword ptr [eax+1Ch], 4
.text:000108F7                 mov     eax, [ebp+DeviceObject]
.text:000108FA                 and      byte ptr [eax+1Ch], 7Fh
.text:000108FE                 push    offset a??Syserdbgms_0 ; "
//??//SyserDbgMsg"
.text:00010903                 lea        eax, [ebp+SymbolicLinkName]
.text:00010906                 push     eax             ; DestinationString
.text:00010907                 call       edi ; RtlInitUnicodeString
.text:00010909                 lea        eax, [ebp+DeviceName]
.text:0001090C                 push    eax             ; DeviceName
.text:0001090D                 lea       eax, [ebp+SymbolicLinkName]
.text:00010910                 push    eax             ; SymbolicLinkName
.text:00010911                 call      ds:IoCreateSymbolicLink
.text:00010917                 push    offset SpinLock ; SpinLock
.text:0001091C                 call     ds:KeInitializeSpinLock

RtlInitUnicodeString (SymbolicLinkName , L"//??//SyserDbgMsg");

// SymbolicLinkName: "//??//SyserDbgMsg"
// DeviceName:       "
//Device//SyserDbgMsg"
IoCreateSymbolicLink( SymbolicLinkName , DeviceName) ;


.text:00010938                 push    offset aDbgsetdebugpri ; "DbgSetDebugPrintCallback"
.text:0001093D                 lea      eax, [ebp+SystemRoutineName]
.text:00010940                 push    eax             ; DestinationString
.text:00010941                 call      edi ; RtlInitUnicodeString
.text:00010943                 mov     esi, ds:MmGetSystemRoutineAddress
.text:00010949                 lea       eax, [ebp+SystemRoutineName]
.text:0001094C                 push    eax             ; SystemRoutineName
.text:0001094D                 call      esi ; MmGetSystemRoutineAddress
.text:0001094F                 cmp     eax, ebx
.text:00010951                 mov      dword_12000, eax
.text:00010956                 jz         short loc_109A3
.text:00010958                 push    1
.text:0001095A                 push    offset sub_10D8A
.text:0001095F                 call      eax
.text:00010961                 test      eax, eax
.text:00010963                 jl          short loc_109A3
.text:00010965                 push     offset aDbgsetdebugfil ; "DbgSetDebugFilterState"
.text:0001096A                 lea       eax, [ebp+SystemRoutineName]
.text:0001096D                 push    eax             ; DestinationString
.text:0001096E                 mov     byte_11FFC, 1
.text:00010975                 call      edi ; RtlInitUnicodeString
.text:00010977                 lea       eax, [ebp+SystemRoutineName]
.text:0001097A                 push    eax             ; SystemRoutineName
.text:0001097B                 call      esi ; MmGetSystemRoutineAddress
.text:0001097D                 cmp     eax, ebx
.text:0001097F                 mov     dword_12004, eax
.text:00010984                 jz        short loc_109A3
.text:00010986                 xor      edi, edi


RtlInitUnicodeString (uniSystemRoutineName, L"DbgSetDebugPrintCallback");
dword_12000 = MmGetSystemRoutineAddress(uniSystemRoutineName);

RtlInitUnicodeString (uniSystemRoutineName, L"DbgSetDebugFilterState");
dword_12004 = MmGetSystemRoutineAddress(uniSystemRoutineName);

if ( (dword_12000 == NULL) && (dword_12004 == NULL) )
{

.text:000109AB                 push    ebx             ; DeferredContext
.text:000109AC                 push    offset DeferredRoutine ; DeferredRoutine
.text:000109B1                 mov     edi, offset Dpc
.text:000109B6                 push    edi             ; Dpc
.text:000109B7                 call      ds:KeInitializeDpc
.text:000109BD                 mov     esi, offset unk_11FB0
.text:000109C2                 push    esi             ; Timer
.text:000109C3                 call      ds:KeInitializeTimer
.text:000109C9                 push    edi             ; Dpc
.text:000109CA                 push    3E8h            ; Period
.text:000109CF                 or        ecx, 0FFFFFFFFh
.text:000109D2                 push    ecx
.text:000109D3                 mov     eax, 0FF676980h
.text:000109D8                 push    eax             ; DueTime
.text:000109D9                 push    esi             ; Timer
.text:000109DA                 call     ds:KeSetTimerEx
.text:000109E0                 jmp     short loc_109F3


DeferredContext = 0;
KTIMER  g_Timer ;

KeInitializeDpc( &g_Dpc , DeferredRoutine, 0);

KeInitializeTimer(  &g_Timer );

KeSetTimerEx( &g_Timer, 0FF676980h, 3E8h, &g_Dpc );


.text:000109F3 loc_109F3:                              ; CODE XREF: start+159j
.text:000109F3                                         ; start+190j
.text:000109F3                 xor     eax, eax
.text:000109F5
.text:000109F5 loc_109F5:                              ; CODE XREF: start+9Bj
.text:000109F5                 pop     edi
.text:000109F6                 pop     esi
.text:000109F7                 pop     ebx
.text:000109F8                 leave
.text:000109F9                 retn    8
.text:000109F9 start          endp


程序结束
}


下面是关于延迟过程调用和Timer的说明:
If the Dpc parameter is specified, a DPC object is associated with the timer object.
When the timer expires, the timer object is removed from the system timer queue and it is set to a signaled state.
If a DPC object was associated with the timer when it was set, the DPC object is inserted in the system DPC queue to be executed as soon as conditions permit after the timer interval expires.


总结:
(1)DeferredRoutine 是一个延迟过程调用, 在该例程中会做些什么呢? 我想可能是先前执行的某段代码由于执行时机的原因而没有成功,  在该例程中会重复执行直至成功为止.

(2)sub_10702:  DriverUnload
        loc_103DC:  SDbgMsgCreate
        sub_10646:  SDbgMsgRead
        loc_103F8:  SDbgMsgClose
        loc_10442:  SDbgMsgDeviceIoControl

在 IDA 中分别选中这些函数名,然后 鼠标右键-->"rename" ,把这些函数替换为上面容易记忆的名字;

(3) 上面的 DirverEntry 例程中通过 MmGetSystemRoutineAddress 来得到 DbgSetDebugPrintCallback和 DbgSetDebugFilterState 系统例程, 并分别存在 dword_12000 和 dword_12004 内存位置.以后的代码中肯定使用这 2 个值(函数的地址), 我们可以在代码中找到 对dword_12000 和 dword_12004 访问的代码并把它改成具体的例程名 "DbgSetDebugPrintCallback" 和 "DbgSetDebugFilterState "

 
23:30 2007-9-20  

相关文章推荐

Windows Minifilter驱动 - 加载顺序 (2)

安装minifilter后,可以在注册表看到一些
  • zj510
  • zj510
  • 2014年09月17日 18:18
  • 4056

设置驱动程序开机启动

开发驱动程序时,每次都用INF文件安装再加载实在是很麻烦,就写个程序来实现。 但是在实现驱动程序开机启动时却遇到了问题。 函数原型如下: CreateService Function ...

u-boot下网络驱动程序的修改

Eth.c工作之前的初始化static struct eth_device *eth_devices, *eth_current;Eth.c中有个eth_devices需要外部调用函数eth_regi...
  • xgbing
  • xgbing
  • 2011年06月28日 14:38
  • 7108

如何定制一个基于REST Service的ODBC驱动程序

摘要:REST Service帮助开发者以简单统一的接口向终端用户提供服务。然而数据分析的应用场景中,一些成熟的数据分析工具要求用户提供ODBC数据源,在这种情况下,REST Service并不能满足...

start service at boot

I haven’t been messing around with the Android SDK for too long but I’ve already found some things t...

u-boot分析 四 (程序入口start.S)

u-boot分析 四 (程序入口start.S)注:部分内容摘抄自网络,如有问题,请联络博主。本文内容:了解以stars.S为开始的ARM汇编程序部分。回顾前几篇博文,咱们见识过了u-boot的目录结...
  • itxiebo
  • itxiebo
  • 2016年03月21日 22:10
  • 2329

linux基础之spi驱动程序理解

1.1     重要的数据结构 1.  spi_device 虽然用户空间不需要直接用到spi_device结构体,但是这个结构体和用户空间的程序有密切的关系,理解它的成员有助于理解SPI设备节点...
  • lbaihao
  • lbaihao
  • 2016年11月14日 23:22
  • 497

Linux块设备驱动程序原理

1.4  块设备驱动程序 1.4.1  Linux块设备驱动程序原理(1) 顾名思义,块设备驱动程序就是支持以块的方式进行读写的设备。块设备和字符设备最大的区别在于读写数据的基本单元不同。...

Linux设备驱动程序学习笔记12:中断调用流程

通过轮询的方式去查询各个硬件的状态显得有的低效,一种更好的机制是当硬件状态准备好之后能够主动地报告给CPU。中断就是这样的一种机制,它允许硬件发信号给CPU。 下面就先分析一下当一个中断发生时,Li...

windows驱动程序wdf--KMDF大致框架

继WDM后微软出了WDF,封装了WDM中的一些基本代码逻辑。本人菜鸟,也不知道本质上有何区别,只觉得是多了Wdf开头的函数,基本的编程框架上有点出入。KMDF是WDF的内核级部分,为了理清KMDF的结...
  • mao0514
  • mao0514
  • 2015年01月04日 16:18
  • 1941
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:SERVICE_BOOT_START 驱动程序逆向
举报原因:
原因补充:

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