SERVICE_BOOT_START 驱动程序逆向 2

.text:000104D2 ; void __stdcall DeferredRoutine(struct _KDPC *,PVOID,PVOID,PVOID)
.text:000104D2 DeferredRoutine proc near               ; DATA XREF: start+15Co
.text:000104D2                 xor     ecx, ecx
.text:000104D4                 cmp     dword_12220, ecx
.text:000104DA                 jz      short locret_104EE
.text:000104DC                 mov     eax, Event
.text:000104E1                 cmp     eax, ecx
.text:000104E3                 jz      short locret_104EE
.text:000104E5                 push    ecx             ; Wait
.text:000104E6                 push    ecx             ; Increment
.text:000104E7                 push    eax             ; Event
.text:000104E8                 call    ds:KeSetEvent
.text:000104EE
.text:000104EE locret_104EE:                           ; CODE XREF: DeferredRoutine+8j
.text:000104EE                                         ; DeferredRoutine+11j
.text:000104EE                 retn    10h
.text:000104EE DeferredRoutine endp

这是上面  KeInitializeDpc 例程设置延迟调用过程, 第二个参数为NULL, 再该例程中如果 dword_12220 不为 0, 就设置事件,这个event 变量是全局

if (dword_12220 != 0)
{
        if (g_event != NULL)
 {
  KeSetEvent(g_event, NULL, NULL);  
 }
}

 

//--------------------下面是 IRP_MJ_CREATE 对应的例程--------------------------

.text:000103DC SDbgMsgCreate:                          ; DATA XREF: start+31o
.text:000103DC                 mov     ecx, [esp+8]
.text:000103E0                 and     dword ptr [ecx+18h], 0
.text:000103E4                 xor     dl, dl
.text:000103E6                 mov     dword ptr [ecx+1Ch], 1
.text:000103ED                 call    ds:IofCompleteRequest
.text:000103F3                 xor     eax, eax
.text:000103F5                 retn    8

NTSTATUS  SDbgMsgCreate(PDEVICE_OBJECT pDeviceObject, PIRP Irp)
{
 Irp->IoStatus.Status = STATUS_SUCCESS;
 Irp->IoStatus.Information = 1;
 
        //
        // IofCompleteRequest 例程是 _fastcall 调用方式
        // 采用 ecx 和 edx 传递参数
        //
 
   IoCompleteRequest( ecx , edx );   
       
        return Irp->IoStatus.Status ;
}


//--------------------下面是 IRP_MJ_READ 对应的派遣例程-------------------------
下面的代码是由 IDA 自动生成, SDbgMsgRead 是我根据在 DriverObject 例程中的分析得处的该例程对应着 IRP_MJ_READ

; int __stdcall SDbgMsgRead(int,KIRQL NewIrql)
.text:00010646 SDbgMsgRead     proc near               ; DATA XREF: start+37o
.text:00010646
.text:00010646 NewIrql         = byte ptr  18h
.text:00010646
.text:00010646                 push    ebx
.text:00010647                 push    ebp
.text:00010648                 push    esi
.text:00010649                 push    edi
.text:0001064A                 mov     edi, dword ptr [esp+NewIrql]
.text:0001064E                 mov     ebp, [edi+60h]
.text:00010651                 mov     ebx, offset SpinLock
.text:00010656                 mov     ecx, ebx        ; SpinLock
.text:00010658                 xor     esi, esi
.text:0001065A                 call    ds:KfAcquireSpinLock
.text:00010660                 mov     [esp+NewIrql], al
.text:00010664                 mov     eax, dword_12220
.text:00010669                 test    eax, eax
.text:0001066B                 jz      short loc_106BB
.text:0001066D                 mov     esi, [ebp+4]
.text:00010670                 inc     eax
.text:00010671                 cmp     esi, eax
.text:00010673                 jle     short loc_10677
.text:00010675                 mov     esi, eax
.text:00010677
// 上面的反汇编代码可能又有问题: NewIrql 是从哪来得?

  MOV edi, dword ptr [esp+NewIrql]
  MOV ebp, [edi+60h]
可以猜测出, 第二个参数应该是 Irp 才对, 这样Irp偏移量为 60H是 CurrentStackLocation

   
   

    ULONG UlLength;
    PVOID SystemBuffer = NULL ;

    ebp = IoGetCurrentIrpStackLocation(Irp);
   
    KfAcquireSpinLock(&g_SpinLock);       // __fastcall 调用方式
  
    UlLength  = ebp->Parameters.Read.Length;

    if (dword_12220 != 0)
 {
     if ( ebp->Parameters.Read.Length > dword_12220+1 )
  {
   UlLength = dword_12220+1;        // 应该是和存放读取数据的缓冲区有关, 取小值   
  } 

            if (UlLength == 0) 
  {
   ; 完成 Irp
                        ; 退出
  }
           
            // 取得读取数据的缓冲区
            pSystemBuffer = Irp->AssociatedIrp.SystemBuffer ;                                                   
.text:00010677 loc_10677:                              ; CODE XREF: SDbgMsgRead+2Dj
.text:00010677                 test    esi, esi        ; 比较  pSystemBuffer 是否为 NULL
.text:00010679                 jz      short loc_106BB
.text:0001067B                 mov     eax, [edi+0Ch]
.text:0001067E                 test    eax, eax
.text:00010680                 jz      short loc_106BB

   if ( pSystemBuffer == NULL)
  {
                        ; 完成 Irp
                        ; 退出
  }
.text:00010682                 push    esi             ; 读取数据的长度
.text:00010683                 push    dword_12224    
.text:00010689                 push    eax             ; 存放数据缓冲区的地址
.text:0001068A                 call    sub_1050E
 
          // 从数据存放的缓冲区中读取指定大小的字节
          retValue = sub_1050E( pSystemBuffer, dword_12224, UlLength);
         
.text:0001068F                 cmp     esi, dword_12220
.text:00010695                 jge     short loc_106B4
.text:00010697                 mov     eax, dword_12224
.text:0001069C                 lea     ecx, [eax+esi-1]
.text:000106A0                 push    ecx
.text:000106A1                 push    eax
.text:000106A2                 call    sub_104F2
        if (esi < dword_12220) 
        {
  sub104f2_Retvalue = sub_104F2 (dword_12224 , dword_12224+esi-1 );

.text:000106A7                 xor     eax, eax
.text:000106A9                 inc     eax
.text:000106AA                 sub     eax, esi
.text:000106AC                 add     dword_12220, eax
.text:000106B2                 jmp     short loc_106BB
               
                sub104f2_Retvalue = 1;
               
                sub104f2_Retvalue -= UlLength;
               
                dword_12220 +=  eax;      
               
        }else
        {
.text:000106B4 loc_106B4:                              ; CODE XREF: SDbgMsgRead+4Fj
.text:000106B4                 and     dword_12220, 0
  dword_12220 = 0;
        }

label :loc_106BB:      
.text:000106BB loc_106BB:                              ; CODE XREF: SDbgMsgRead+25j
.text:000106BB                                         ; SDbgMsgRead+33j ...
.text:000106BB                 mov     dl, [esp+NewIrql] ; NewIrql
.text:000106BF                 mov     ecx, ebx        ; SpinLock
.text:000106C1                 call    ds:KfReleaseSpinLock
         KfReleaseSpinLock(g_SpinLock);

.text:000106C7                 and     dword ptr [edi+18h], 0
.text:000106CB                 xor     dl, dl
.text:000106CD                 mov     ecx, edi        ; Irp
.text:000106CF                 mov     [edi+1Ch], esi                  ; esi 实际读取了多少字节的数据
.text:000106D2                 call    ds:IofCompleteRequest
.text:000106D8                 pop     edi
.text:000106D9                 pop     esi
.text:000106DA                 pop     ebp
.text:000106DB                 xor     eax, eax
.text:000106DD                 pop     ebx
.text:000106DE                 retn    8
 
 Irp->IoStatus.Status = STATUS_SUCCESS;
  Irp->IoStatus.Information = esi ;     // 实际读取了多少字节的数据    
 
 IofCompleteRequest(Irp, 0);         
 }
 

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Blue_Dream_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值