返回列表 发帖

调试笔记之雨过天晴多点还原软件MBR实例

标 题: 【原创】调试笔记之雨过天晴多点还原软件MBR实例
作 者: sudami
时 间: 2009-09-22,22:49
链 接: http://bbs.pediy.com/showthread.php?t=98312

为了能够调试多点还原软件"雨过天晴"的启动代码,目前有2种方式:

引用:
(1) 在Bochs调试器上装Windows XP系统,然后用Bochs单步调试. 不过光安装操作系统就得花20个小时以上
(2) 用Wnhex克隆整个磁盘,配置Bochs的*.bxrc文件.用这个克隆的磁盘来调试MBR

方案二较简单,故我选择此方式调试.
在一个干净的Vmvare上装上雨过天晴,用Winhex克隆整个磁盘,Bochs调起来,发现根本没有进入ygtq的MBR,而是原始的引导代码. 这才意识到ygtq在驱动中做了手脚,对MBR的读写操作进行了重定向.于是开始分析起来. 经过几小时的战斗,终于搞定. 下面是一些调试分析的细节,希望对各位有所帮助!
-----------------------------------------------------------------------

雨过天晴拦截了对磁盘扇区的读写操作,会重新定位MBR,使得Winhex读取的MBR是原始的.这样用Bochs就没法调试ygtq的启动过程代码了.我们在调试器中恢复掉其在disk.sys 和 atapi.sys上的HOOK,再进行磁盘克隆.

雨过天晴在Shdbus.sys的分发例程中会检测disk.sys上的 0x4 和 0xf号派遣函数是否被恢复.若是,则恢复disk.sys的0x4 & 0xf为自己的地址,并全部替换掉atapi.sys的分发例程.
#define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0f
#define IRP_MJ_WRITE 0x04

在Windbg中观察:
kd> !drvobj \driver\disk 3
Driver object (81b7df38) is for:
\Driver\Disk
Driver Extension List: (id , addr)
(f99e33be 81b7dd38)
Device Object list:
81b7a7b0 81b7a030 81bc4030

DriverEntry: f99d38ab    disk!GsDriverEntry
DriverStartIo: 00000000   
DriverUnload: f99e353a    CLASSPNP!ClassUnload
AddDevice: f99e4ec0    CLASSPNP!ClassAddDevice

Dispatch routines:
[00] IRP_MJ_CREATE f9785cd6    Shield+0x3cd6
[01] IRP_MJ_CREATE_NAMED_PIPE f9785cd6    Shield+0x3cd6
[02] IRP_MJ_CLOSE f9785cd6    Shield+0x3cd6
[03] IRP_MJ_READ f9785cd6    Shield+0x3cd6
[04] IRP_MJ_WRITE f9785cd6    Shield+0x3cd6
[05] IRP_MJ_QUERY_INFORMATION f9785cd6    Shield+0x3cd6
[06] IRP_MJ_SET_INFORMATION f9785cd6    Shield+0x3cd6
[07] IRP_MJ_QUERY_EA f9785cd6    Shield+0x3cd6
[08] IRP_MJ_SET_EA f9785cd6    Shield+0x3cd6
[09] IRP_MJ_FLUSH_BUFFERS f9785cd6    Shield+0x3cd6
[0a] IRP_MJ_QUERY_VOLUME_INFORMATION f9785cd6    Shield+0x3cd6
[0b] IRP_MJ_SET_VOLUME_INFORMATION f9785cd6    Shield+0x3cd6
[0c] IRP_MJ_DIRECTORY_CONTROL f9785cd6    Shield+0x3cd6
[0d] IRP_MJ_FILE_SYSTEM_CONTROL f9785cd6    Shield+0x3cd6
[0e] IRP_MJ_DEVICE_CONTROL f9785cd6    Shield+0x3cd6
[0f] IRP_MJ_INTERNAL_DEVICE_CONTROL f9785cd6    Shield+0x3cd6
[10] IRP_MJ_SHUTDOWN f9785cd6    Shield+0x3cd6
[11] IRP_MJ_LOCK_CONTROL f9785cd6    Shield+0x3cd6
[12] IRP_MJ_CLEANUP f9785cd6    Shield+0x3cd6
[13] IRP_MJ_CREATE_MAILSLOT f9785cd6    Shield+0x3cd6
[14] IRP_MJ_QUERY_SECURITY f9785cd6    Shield+0x3cd6
[15] IRP_MJ_SET_SECURITY f9785cd6    Shield+0x3cd6
[16] IRP_MJ_POWER f9785cd6    Shield+0x3cd6
[17] IRP_MJ_SYSTEM_CONTROL f9785cd6    Shield+0x3cd6
[18] IRP_MJ_DEVICE_CHANGE f9785cd6    Shield+0x3cd6
[19] IRP_MJ_QUERY_QUOTA f9785cd6    Shield+0x3cd6
[1a] IRP_MJ_SET_QUOTA f9785cd6    Shield+0x3cd6
[1b] IRP_MJ_PNP f99e2d15    CLASSPNP!ClassDispatchPnp

而原始的地址函数名如下:
Dispatch routines:
[00] IRP_MJ_CREATE f7668c30    CLASSPNP!ClassCreateClose
[01] IRP_MJ_CREATE_NAMED_PIPE 804f5282    nt!IopInvalidDeviceRequest
[02] IRP_MJ_CLOSE f7668c30    CLASSPNP!ClassCreateClose
[03] IRP_MJ_READ f7662d9b    CLASSPNP!ClassReadWrite
[04] IRP_MJ_WRITE f7662d9b    CLASSPNP!ClassReadWrite //
[05] IRP_MJ_QUERY_INFORMATION 804f5282    nt!IopInvalidDeviceRequest
[06] IRP_MJ_SET_INFORMATION 804f5282    nt!IopInvalidDeviceRequest
[07] IRP_MJ_QUERY_EA 804f5282    nt!IopInvalidDeviceRequest
[08] IRP_MJ_SET_EA 804f5282    nt!IopInvalidDeviceRequest
[09] IRP_MJ_FLUSH_BUFFERS f7663366    CLASSPNP!ClassShutdownFlush
[0a] IRP_MJ_QUERY_VOLUME_INFORMATION 804f5282    nt!IopInvalidDeviceRequest
[0b] IRP_MJ_SET_VOLUME_INFORMATION 804f5282    nt!IopInvalidDeviceRequest
[0c] IRP_MJ_DIRECTORY_CONTROL 804f5282    nt!IopInvalidDeviceRequest
[0d] IRP_MJ_FILE_SYSTEM_CONTROL 804f5282    nt!IopInvalidDeviceRequest
[0e] IRP_MJ_DEVICE_CONTROL f766344d    CLASSPNP!ClassDeviceControlDispatch
[0f] IRP_MJ_INTERNAL_DEVICE_CONTROL f7666fc3    CLASSPNP!ClassInternalIoControl     //   
[10] IRP_MJ_SHUTDOWN f7663366    CLASSPNP!ClassShutdownFlush
[11] IRP_MJ_LOCK_CONTROL 804f5282    nt!IopInvalidDeviceRequest
[12] IRP_MJ_CLEANUP 804f5282    nt!IopInvalidDeviceRequest
[13] IRP_MJ_CREATE_MAILSLOT 804f5282    nt!IopInvalidDeviceRequest
[14] IRP_MJ_QUERY_SECURITY 804f5282    nt!IopInvalidDeviceRequest
[15] IRP_MJ_SET_SECURITY 804f5282    nt!IopInvalidDeviceRequest
[16] IRP_MJ_POWER f7664ef3    CLASSPNP!ClassDispatchPower
[17] IRP_MJ_SYSTEM_CONTROL f7669a24    CLASSPNP!ClassSystemControl
[18] IRP_MJ_DEVICE_CHANGE 804f5282    nt!IopInvalidDeviceRequest
[19] IRP_MJ_QUERY_QUOTA 804f5282    nt!IopInvalidDeviceRequest
[1a] IRP_MJ_SET_QUOTA 804f5282    nt!IopInvalidDeviceRequest
[1b] IRP_MJ_PNP f7668d15    CLASSPNP!ClassDispatchPnp

现在在调试器中手工修改函数地址:
kd> ln CLASSPNP!ClassInternalIoControl
(f99e0fc3) CLASSPNP!ClassInternalIoControl | (f99e0fc3) CLASSPNP!ClassInternalIoControl
Exact matches:
CLASSPNP!ClassInternalIoControl = <no type information>
kd> ed 81b7dfac f99e0fc3
kd> !drvobj \driver\disk 3
Driver object (81b7df38) is for:
\Driver\Disk
Driver Extension List: (id , addr)
(f99e33be 81b7dd38)
Device Object list:
81b7a7b0 81b7a030 81bc4030

DriverEntry: f99d38ab    disk!GsDriverEntry
DriverStartIo: 00000000   
DriverUnload: f99e353a    CLASSPNP!ClassUnload
AddDevice: f99e4ec0    CLASSPNP!ClassAddDevice

Dispatch routines:
[00] IRP_MJ_CREATE f9785cd6    Shield+0x3cd6
[01] IRP_MJ_CREATE_NAMED_PIPE f9785cd6    Shield+0x3cd6
[02] IRP_MJ_CLOSE f9785cd6    Shield+0x3cd6
[03] IRP_MJ_READ f9785cd6    Shield+0x3cd6
[04] IRP_MJ_WRITE f9785cd6    Shield+0x3cd6
[05] IRP_MJ_QUERY_INFORMATION f9785cd6    Shield+0x3cd6
[06] IRP_MJ_SET_INFORMATION f9785cd6    Shield+0x3cd6
[07] IRP_MJ_QUERY_EA f9785cd6    Shield+0x3cd6
[08] IRP_MJ_SET_EA f9785cd6    Shield+0x3cd6
[09] IRP_MJ_FLUSH_BUFFERS f9785cd6    Shield+0x3cd6
[0a] IRP_MJ_QUERY_VOLUME_INFORMATION f9785cd6    Shield+0x3cd6
[0b] IRP_MJ_SET_VOLUME_INFORMATION f9785cd6    Shield+0x3cd6
[0c] IRP_MJ_DIRECTORY_CONTROL f9785cd6    Shield+0x3cd6
[0d] IRP_MJ_FILE_SYSTEM_CONTROL f9785cd6    Shield+0x3cd6
[0e] IRP_MJ_DEVICE_CONTROL f9785cd6    Shield+0x3cd6
[0f] IRP_MJ_INTERNAL_DEVICE_CONTROL f99e0fc3    CLASSPNP!ClassInternalIoControl // 更改后
[10] IRP_MJ_SHUTDOWN f9785cd6    Shield+0x3cd6
[11] IRP_MJ_LOCK_CONTROL f9785cd6    Shield+0x3cd6
[12] IRP_MJ_CLEANUP f9785cd6    Shield+0x3cd6
[13] IRP_MJ_CREATE_MAILSLOT f9785cd6    Shield+0x3cd6
[14] IRP_MJ_QUERY_SECURITY f9785cd6    Shield+0x3cd6
[15] IRP_MJ_SET_SECURITY f9785cd6    Shield+0x3cd6
[16] IRP_MJ_POWER f9785cd6    Shield+0x3cd6
[17] IRP_MJ_SYSTEM_CONTROL f9785cd6    Shield+0x3cd6
[18] IRP_MJ_DEVICE_CHANGE f9785cd6    Shield+0x3cd6
[19] IRP_MJ_QUERY_QUOTA f9785cd6    Shield+0x3cd6
[1a] IRP_MJ_SET_QUOTA f9785cd6    Shield+0x3cd6
[1b] IRP_MJ_PNP f99e2d15    CLASSPNP!ClassDispatchPnp

然后下断点观察:
kd> ba w 4 81b7dfac
kd> bl
0 e 81b7dfac w 4 0001 (0001)
kd> g
Breakpoint 0 hit
Shdbus+0x56e:
f9ea056e a1200eeaf9 mov eax,dword ptr [Shdbus+0xe20 (f9ea0e20)]

kd> kvn
# ChildEBP RetAddr Args to Child
00 f9e2fb3c 804eedf9 81b7d8b8 81b7c828 81731530 Shdbus+0x56e
01 f9e2fb4c f99dd061 81bc5000 81439500 81731530 nt!IopfCallDriver+0x31
02 81b7d8b8 00000000 81b7f888 81bd6040 81bc4030 CLASSPNP!SubmitTransferPacket+0x82

kd> !thread
THREAD 81bc4da8 Cid 0004.006c Teb: 00000000 Win32Thread: 00000000 RUNNING on processor 0
Not impersonating
DeviceMap e1006008
Owning Process 81bbd7c0 Image: System
Wait Start TickCount 18821 Ticks: 3 (0:00:00:00.046)
Context Switch Count 12678
UserTime 00:00:00.000
KernelTime 00:00:02.281
Start Address Shield (0xf9782886)
Stack Init f9e30000 Current f9e2fd38 Base f9e30000 Limit f9e2d000 Call 0
Priority 16 BasePriority 8 PriorityDecrement 0 DecrementCount 0
ChildEBP RetAddr Args to Child
f9e2fb3c 804eedf9 81b7d8b8 81b7c828 81731530 Shdbus+0x56e
f9e2fb4c f99dd061 81bc5000 81439500 81731530 nt!IopfCallDriver+0x31 (FPO: [0,0,0])
81b7d8b8 00000000 81b7f888 81bd6040 81bc4030 CLASSPNP!SubmitTransferPacket+0x82 (FPO: [Non-Fpo])

IDA打开雨过天晴的boot0驱动shdbus.sys,定位到+0x1056e处,位于分发函数IrpInternalDeviceControl内,代码如下:


代码:
  1. NTSTATUS IrpInternalDeviceControl(int DeviceObject, PIRP Irp)
  2. {
  3.   int DeviceExtension, srb, atapi_driver_object, disk_driver_object, srb_cdb, IoControlCode ;  
  4.   HANDLE CurrentTID;   
  5.   struct _IRP::$::$::$::$A02EC6A2CE86544F716F4825015773AC::_IO_STACK_LOCATION *CurrentStackLocation;
  6.   char OperationCode;  

  7.   DeviceExtension = *(DWORD *)(DeviceObject + 0x28);
  8.   CurrentTID = PsGetCurrentThreadId();
  9.   PsGetCurrentProcessId();
  10.   srb = 0;
  11.   if ( g_disk_internal_device_control_dispatch )
  12.   {
  13.     disk_driver_object = *(DWORD *)(g_disk_device_object + 8);
  14.     if ( *(DWORD *)(disk_driver_object + 0x74) != g_disk_internal_device_control_dispatch
  15.       || *(DWORD *)(disk_driver_object + 0x48) != g_disk_internal_device_control_dispatch
  16.        )
  17.     {//
  18.      // #define IRP_MJ_INTERNAL_DEVICE_CONTROL    0x0f
  19.      // #define IRP_MJ_SCSI                       0x0f
  20.      // 雨过天晴会不断检查自己的HOOK点,并恢复之.若2个程序同时在同一点
  21.      // 循环检查并恢复自己的钩子,会导致系统启动后及其缓慢. 而且"雨过天晴"会结束
  22.      // 掉与其竞争的系统线程,导致系统出现异常错误.BSOD.
  23.      //
  24.       *(DWORD *)(disk_driver_object + 0x74) = g_disk_internal_device_control_dispatch;
  25.       *(DWORD *)(disk_driver_object + 0x48) = g_disk_internal_device_control_dispatch;

  26. // disk分发例程往下发的时候,起扩展设备偏移+0x008的地方是atapi.sys的设备对象,"雨过天晴"在此进行验证.
  27.       if ( *(DWORD *)(DeviceExtension + 8) == g_atapi_device_object )
  28.       {
  29.         if ( g_allowed_TID_1_0000006c
  30.           && CurrentTID != *(HANDLE *)g_allowed_TID_1_0000006c
  31.           && g_allowed_TID_2_ffffffff
  32.           && CurrentTID != *(HANDLE *)g_allowed_TID_2_ffffffff
  33.           && g_allowed_TID_3_00000070
  34.           && CurrentTID != *(HANDLE *)g_allowed_TID_3_00000070
  35.           && g_allowed_TID_4_00000240
  36.           && CurrentTID != *(HANDLE *)g_allowed_TID_4_00000240 )
  37.         {
  38. // 不是以上4个系统线程,便会被"雨过"结束掉,并且阻止当前IRP的下发.于是就BSOD了.
  39.           ZwTerminateProcess((HANDLE)0xFFFFFFFF, 0);            
  40. denny:
  41.           Irp->IoStatus.Status = 0;
  42.           IofCompleteRequest(Irp, 0);
  43.           return 0;
  44.         }
  45.       }
  46.     }
  47.     atapi_driver_object = *(DWORD *)(g_atapi_device_object + 8);
  48. if ( *(DWORD *)(atapi_driver_object + 0x74) != (DWORD)atapi_Proxy_dispatch ) // 在此处恢复对atapi.sys分发例程的HOOK
  49.       memset((void *)(atapi_driver_object + 0x38), (int)atapi_Proxy_dispatch, 0x6Cu);
  50.   }

  51.   CurrentStackLocation = Irp->Tail.Overlay.CurrentStackLocation;
  52.   IoControlCode = *((DWORD *)CurrentStackLocation + 3);
  53.   srb_cdb = 0;
  54.   if ( IoControlCode == 0x1B0012 || IoControlCode == 0x1B0011 )
  55.   {
  56.     srb = *((DWORD *)CurrentStackLocation + 1);
  57.     srb_cdb = srb + 0x30;
  58.   }
  59.   if ( *(DWORD *)(DeviceExtension + 8) == g_atapi_device_object )
  60.   {
  61.     if ( g_allowed_TID_1_0000006c )
  62.     {
  63.       if ( CurrentTID != *(HANDLE *)g_allowed_TID_1_0000006c )
  64.       {
  65.         if ( !g_allowed_TID_2_ffffffff || CurrentTID != *(HANDLE *)g_allowed_TID_2_ffffffff )
  66.         {
  67.           if ( !g_allowed_TID_3_00000070 || CurrentTID != *(HANDLE *)g_allowed_TID_3_00000070 )
  68.           {
  69.             if ( !g_allowed_TID_4_00000240 || CurrentTID != *(HANDLE *)g_allowed_TID_4_00000240 )
  70.             {
  71.               if ( srb )
  72.               {
  73.                 if ( !*(BYTE *)(srb + 2) )
  74.                 {
  75.                   if ( srb_cdb )
  76.                   {
  77.                     OperationCode = *(BYTE *)srb_cdb;
  78.                     if ( *(BYTE *)srb_cdb == SCSIOP_WRITE
  79.                       || OperationCode == SCSIOP_SEND
  80.                       || OperationCode == SCSIOP_FLUSH_BUFFER
  81.                       || OperationCode == SCSIOP_WRITE_VERIFY
  82.                       || OperationCode == SCSIOP_READ
  83.                       || OperationCode == SCSIOP_RECEIVE )
  84.                       goto denny;
  85.                   }
  86.                 }
  87.               }
  88.             }
  89.           }
  90.         }
  91.       }
  92.     }
  93.   }

  94.   return IrpReadWrite_dep(DeviceObject, Irp);
  95. }
复制代码
(1) 现在调试器中将jnz 改成 Jmp, 即 0F 84 à 90 E9


2) 经过初步分析,雨过天晴大致在Disk.sys和Atapi.sys层做了过滤,为了验证这一想法,我恢复掉其钩子后,自己写程序不经过文件系统层,构建IRP发到DR0上读取MBR,看是否成功.现要恢复Disk.sys的IRP_MJ_READ & IRP_MJ_INTERNAL_DEVICE_CONTROL例程 和 Atapi.sys的IRP_MJ_INTERNAL_DEVICE_CONTROL例程:

(因为我的程序是自己构建IRP,填充0xf号控制码,即isl->MajorFunction =   IRP_MJ_SCSI,然后发送到DR0设备上, 那么IRP往下走的过程中就会调用DR0对应的驱动对象的分发例程,也就是Disk.sys的0xf号分发例程,而非IRP_MJ_READ,所以根据我的程序特性,应该恢复Disk.sys的IRP_MJ_INTERNAL_DEVICE_CONTROL历程)

kd> ln CLASSPNP!ClassInternalIoControl
(f99e0fc3)   CLASSPNP!ClassInternalIoControl   |  (f99e0fc3)   CLASSPNP!ClassInternalIoControl
Exact matches:
CLASSPNP!ClassInternalIoControl = <no type information>

kd> ln CLASSPNP!ClassReadWrite
(f99dcd9b)   CLASSPNP!ClassReadWrite   |  (f99dcd9b)   CLASSPNP!ClassReadWrite
Exact matches:
    CLASSPNP!ClassReadWrite = <no type information>
kd> ed 81b7df38+0x38+0x3c f99e0fc3
kd> ed 81b7df38+0x38+0xc f99dcd9b
kd> !drvobj \driver\disk 3

Dispatch routines:
[00] IRP_MJ_CREATE                      f9785cd6      Shield+0x3cd6
[01] IRP_MJ_CREATE_NAMED_PIPE           f9785cd6 Shield+0x3cd6
[02] IRP_MJ_CLOSE                       f9785cd6      Shield+0x3cd6
[03] IRP_MJ_READ                        f99dcd9b    CLASSPNP!ClassReadWrite
[04] IRP_MJ_WRITE                       f9785cd6      Shield+0x3cd6

[0f] IRP_MJ_INTERNAL_DEVICE_CONTROL     f99e0fc3       CLASSPNP!ClassInternalIoControl


原始的Atapi.sys的分发例程如下:
Dispatch routines:
[00] IRP_MJ_CREATE                      bae6d572      atapi!IdePortAlwaysStatusSuccessIrp
[01] IRP_MJ_CREATE_NAMED_PIPE           804f5282 nt!IopInvalidDeviceRequest
[02] IRP_MJ_CLOSE                       bae6d572      atapi!IdePortAlwaysStatusSuccessIrp
[03] IRP_MJ_READ                        804f5282      nt!IopInvalidDeviceRequest
[04] IRP_MJ_WRITE                       804f5282      nt!IopInvalidDeviceRequest
[05] IRP_MJ_QUERY_INFORMATION           804f5282 nt!IopInvalidDeviceRequest
[06] IRP_MJ_SET_INFORMATION             804f5282   nt!IopInvalidDeviceRequest
[07] IRP_MJ_QUERY_EA                    804f5282    nt!IopInvalidDeviceRequest
[08] IRP_MJ_SET_EA                      804f5282      nt!IopInvalidDeviceRequest
[09] IRP_MJ_FLUSH_BUFFERS               804f5282   nt!IopInvalidDeviceRequest
[0a] IRP_MJ_QUERY_VOLUME_INFORMATION    804f5282    nt!IopInvalidDeviceRequest
[0b] IRP_MJ_SET_VOLUME_INFORMATION      804f5282     nt!IopInvalidDeviceRequest
[0c] IRP_MJ_DIRECTORY_CONTROL           804f5282 nt!IopInvalidDeviceRequest
[0d] IRP_MJ_FILE_SYSTEM_CONTROL         804f5282 nt!IopInvalidDeviceRequest
[0e] IRP_MJ_DEVICE_CONTROL              bae6d592  atapi!IdePortDispatchDeviceControl
[0f] IRP_MJ_INTERNAL_DEVICE_CONTROL     bae697b4      atapi!IdePortDispatch
[10] IRP_MJ_SHUTDOWN                    804f5282  nt!IopInvalidDeviceRequest
[11] IRP_MJ_LOCK_CONTROL                804f5282   nt!IopInvalidDeviceRequest
[12] IRP_MJ_CLEANUP                     804f5282     nt!IopInvalidDeviceRequest
[13] IRP_MJ_CREATE_MAILSLOT             804f5282  nt!IopInvalidDeviceRequest
[14] IRP_MJ_QUERY_SECURITY              804f5282  nt!IopInvalidDeviceRequest
[15] IRP_MJ_SET_SECURITY                804f5282    nt!IopInvalidDeviceRequest
[16] IRP_MJ_POWER                       bae6d5bc     atapi!IdePortDispatchPower
[17] IRP_MJ_SYSTEM_CONTROL              bae74164 atapi!IdePortDispatchSystemControl
[18] IRP_MJ_DEVICE_CHANGE               804f5282  nt!IopInvalidDeviceRequest
[19] IRP_MJ_QUERY_QUOTA                 804f5282  nt!IopInvalidDeviceRequest
[1a] IRP_MJ_SET_QUOTA                   804f5282     nt!IopInvalidDeviceRequest
[1b] IRP_MJ_PNP                         bae74130       atapi!IdePortDispatchPnp

kd> ln atapi!IdePortDispatch
(f97d87b4)   atapi!IdePortDispatch   |  (f97d8ccc)   atapi!IdePortTickHandler
Exact matches:
    atapi!IdePortDispatch = <no type information>
kd> ed 81b87b30+0x38+0x3c f97d87b4
kd> !drvobj \driver\atapi 3
Driver object (81b87b30) is for:
\Driver\atapi
Driver Extension List: (id , addr)
(f97e68d8 81bef140)  
Device Object list:
81b7e030  81b872f8  81b85030  81b86030
DriverEntry:   f97e75f7      atapi!GsDriverEntry
DriverStartIo: f97d97c6 atapi!IdePortStartIo
DriverUnload:  f97e3204     atapi!IdePortUnload
AddDevice:     f97e1300   atapi!ChannelAddDevice

Dispatch routines:
[00] IRP_MJ_CREATE                      f97dc572      atapi!IdePortAlwaysStatusSuccessIrp
[01] IRP_MJ_CREATE_NAMED_PIPE        f9ea0c14       Shdbus+0xc14
[02] IRP_MJ_CLOSE                       f9ea0c14       Shdbus+0xc14
[03] IRP_MJ_READ                        f9ea0c14      Shdbus+0xc14
[04] IRP_MJ_WRITE                       f9ea0c14       Shdbus+0xc14
[05] IRP_MJ_QUERY_INFORMATION        f9ea0c14       Shdbus+0xc14
[06] IRP_MJ_SET_INFORMATION           f9ea0c14       Shdbus+0xc14
[07] IRP_MJ_QUERY_EA                   f9ea0c14       Shdbus+0xc14
[08] IRP_MJ_SET_EA                      f9ea0c14       Shdbus+0xc14
[09] IRP_MJ_FLUSH_BUFFERS             f9ea0c14       Shdbus+0xc14
[0a] IRP_MJ_QUERY_VOLUME_INFORMATION   f9ea0c14      Shdbus+0xc14
[0b] IRP_MJ_SET_VOLUME_INFORMATION      f9ea0c14      Shdbus+0xc14
[0c] IRP_MJ_DIRECTORY_CONTROL             f9ea0c14     Shdbus+0xc14
[0d] IRP_MJ_FILE_SYSTEM_CONTROL           f9ea0c14     Shdbus+0xc14
[0e] IRP_MJ_DEVICE_CONTROL                 f9ea0c14     Shdbus+0xc14
[0f] IRP_MJ_INTERNAL_DEVICE_CONTROL    f97d87b4    atapi!IdePortDispatch
[10] IRP_MJ_SHUTDOWN                       f9ea0c14     Shdbus+0xc14
[11] IRP_MJ_LOCK_CONTROL                   f9ea0c14     Shdbus+0xc14
[12] IRP_MJ_CLEANUP                         f9ea0c14     Shdbus+0xc14
[13] IRP_MJ_CREATE_MAILSLOT               f9ea0c14       Shdbus+0xc14
[14] IRP_MJ_QUERY_SECURITY                f9ea0c14       Shdbus+0xc14
[15] IRP_MJ_SET_SECURITY                   f9ea0c14       Shdbus+0xc14
[16] IRP_MJ_POWER                          f9ea0c14       Shdbus+0xc14
[17] IRP_MJ_SYSTEM_CONTROL               f9ea0c14       Shdbus+0xc14
[18] IRP_MJ_DEVICE_CHANGE                f9ea0c14 Shdbus+0xc14
[19] IRP_MJ_QUERY_QUOTA                  f9ea0c14 Shdbus+0xc14
[1a] IRP_MJ_SET_QUOTA                     f9ea0c14  Shdbus+0xc14
[1b] IRP_MJ_PNP                             f9ea0c14 Shdbus+0xc14

(3) 经过以下3步终于成功.
步骤一: 废掉ygtq对disk & atapi分发例程的循环保护
步骤二: 恢复disk.sys 和atapi.sys的0xf号分发例程
步骤三: 自己构建IRP,发送到DR0设备对象上,获取MBR


kd> !devstack 0x81b874e0
  !DevObj   !DrvObj            !DevExt   ObjectName
  81bc4918  \Driver\PartMgr    81bc49d0  
  81b7d878  \Driver\Shield     81b7d930           // ß 注意这里,雨过天晴在Shildf.sys中循环恢复这个Attach在DR0上的过滤设备,
                                                                              // 用Winhex读MBR时,到这里就被重定向了.
  81bc4030  \Driver\Disk       81bc40e8  DR0  // ß 我的IRP发到此处,终于可以读到原始的MBR了
                                                                              // 若不恢复Disk.sys的0xf号分发例程,就会被ygtq拒绝掉,使得我构建的IRP完全失效,
                                                                              // 读到的MBR内容为空.见下图
  81b7d9b0  \Driver\Shdbus     81b7da68      
> 81b874e0  \Driver\atapi      81b87598  IdeDeviceP0T0L0-3
!DevNode 81b85ee8 :
  DeviceInst is "IDE\DiskVMware_Virtual_IDE_Hard_Drive___________00000001\3030303030303030303030303030303030303130"
  ServiceName is "disk"






但是,这仅仅是开始,因为我们的目的是用Winhex克隆安装有”雨过天晴”(非过期; 因为过期后系统不走ygtq的MBR了)的整个系统,以便用Bochs动态调试含有雨过天晴系统的MBR.但Winhex用标准的ReadFile & WriteFile 函数来读写扇区,被ygtq在文件系统层面拦截了.
我用XueTr.exe摘掉雨过天晴的文件过滤设备(ygtq没有对其进行循环恢复),但是其附着在DR0上的过滤设备无法摘除(ygtq开了线程循环恢复),所以当我用Winhex读取MBR时,到\Driver\Shield这层就被重定向了.

现在要做的工作是 找到并废除ygtq的那个循环恢复的线程,删除DR0上的Shield设备,然后就可以用Winhex克隆磁盘了.

kd> !object \driver\disk
Object: 81b7e360  Type: (81ba9900) Driver
    ObjectHeader: 81b7e348 (old version)
    HandleCount: 0  PointerCount: 5
    Directory Object: e12bbd10  Name: Disk
kd> dt nt!_device_object 81bc4030  
nt!_DEVICE_OBJECT
   +0x000 Type             : 3
   +0x002 Size             : 0x518
   +0x004 ReferenceCount   : 0
   +0x008 DriverObject     : 0x81b7e360 _DRIVER_OBJECT
   +0x00c NextDevice       : (null)
   +0x010 AttachedDevice   : 0x81b7d878 _DEVICE_OBJECT

kd> !devstack 0x81b7d878
  !DevObj   !DrvObj            !DevExt   ObjectName
  81bc4918  \Driver\PartMgr    81bc49d0  
> 81b7d878  \Driver\Shield     81b7d930  
  81bc4030  \Driver\Disk       81bc40e8  DR0
  81b7d9b0  \Driver\Shdbus     81b7da68  
  81b874e0  \Driver\atapi      81b87598  IdeDeviceP0T0L0-3
!DevNode 81b85ee8 :
  DeviceInst is "IDE\DiskVMware_Virtual_IDE_Hard_Drive___________00000001\3030303030303030303030303030303030303130"
  ServiceName is "disk"
kd> ba w 4 81bc4030+0x010  // 下硬件断点,然后用XueTr.exe删除这个设备,观察雨过天晴的线程是如何循环恢复的.
kd> bl
0 e f93f1660     0001 (0001) srb!Scsi_read_file_by_sector
1 e f93f14de     0001 (0001) srb!AtapiReadWriteDisk+0x2fe
2 e 81bc4040 w 4 0001 (0001)

kd> g            
Breakpoint 2 hit                   // 第一次断住,是因为我用XueTr.exe删除了这个设备,属于写操作
*** ERROR: Module load completed but symbols could not be loaded for XueTr.sys
XueTr+0x2b21:
f72c9b21 b301            mov     bl,1
kd> !thread
THREAD 81402020  Cid 034c.04a4  Teb: 7ffdd000 Win32Thread: e129ed00 RUNNING on processor 0
IRP List:
    814032a8: (0006,0094) Flags: 00000070  Mdl: 00000000
Not impersonating
DeviceMap                 e1859328
Owning Process            813f1020       Image:         XueTr.exe
Wait Start TickCount      106353         Ticks: 0
Context Switch Count      3482                 LargeStack
UserTime                  00:00:00.875
KernelTime                00:00:01.921
Win32 Start Address 0x00446e16
Start Address 0x7c810867
Stack Init f9460000 Current f945fcb8 Base f9460000 Limit f945a000 Call 0
Priority 10 BasePriority 8 PriorityDecrement 0 DecrementCount 16
ChildEBP RetAddr  Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
f945fbac f72ca325 81b7d878 0012da20 81725828 XueTr+0x2b21
f945fbec f72fe0c0 0012da20 00000008 00000000 XueTr+0x3325
f945fc34 804eedf9 81475978 814032a8 806d12d0 XueTr+0x370c0
f945fc44 80574b42 81403318 8166b660 814032a8 nt!IopfCallDriver+0x31 (FPO: [0,0,0])
f945fc58 805759d1 81475978 814032a8 8166b660 nt!IopSynchronousServiceTail+0x60 (FPO: [Non-Fpo])
f945fd00 8056e33c 00000138 00000000 00000000 nt!IopXxxControlFile+0x5e7 (FPO: [Non-Fpo])
f945fd34 8053d808 00000138 00000000 00000000 nt!NtDeviceIoControlFile+0x2a (FPO: [Non-Fpo])
f945fd34 7c92eb94 00000138 00000000 00000000 nt!KiFastCallEntry+0xf8 (FPO: [0,0] TrapFrame @ f945fd64)
0012d96c 7c92d8ef 7c801671 00000138 00000000 ntdll!KiFastSystemCallRet (FPO: [0,0,0])
0012d970 7c801671 00000138 00000000 00000000 ntdll!ZwDeviceIoControlFile+0xc (FPO: [10,0,0])
0012d9d0 00414d7f 00000138 006e0160 0012da28 0x7c801671
0012d9d4 00000000 006e0160 0012da28 00000018 0x414d7f

kd> g
Breakpoint 2 hit                   // 过了大概半秒钟,系统被Windbg第二次断住,为雨过天晴的行为.观察之.
*** ERROR: Module load completed but symbols could not be loaded for Shieldf.sys
Shieldf+0x3b4:
f9c2c3b4 c9              leave
kd> !thread
THREAD 8143b520  Cid 06ec.06f0  Teb: 7ffdf000 Win32Thread: e1abc730 RUNNING on processor 0
IRP List:
    814da538: (0006,01d8) Flags: 00000884  Mdl: 00000000
Not impersonating
DeviceMap                 e1859328
Owning Process            8143b798       Image:         shieldtray.exe
Wait Start TickCount      107179         Ticks: 0
Context Switch Count      352                 LargeStack
UserTime                  00:00:00.015
KernelTime                00:00:00.140
Win32 Start Address shieldtray (0x0044a981)
Start Address kernel32!BaseProcessStartThunk (0x7c810867)
Stack Init f7ada000 Current f7ad9968 Base f7ada000 Limit f7ad7000 Call 0
Priority 8 BasePriority 8 PriorityDecrement 0 DecrementCount 0
ChildEBP RetAddr  Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
f7ad99fc f9c2da17 814da548 814da538 805452fe Shieldf+0x3b4
f7ad9a4c f9c2de7b 814cf368 814da548 81bd3030 Shieldf+0x1a17
f7ad9b50 805b465e 81b79a20 00000000 816f4228 Shieldf+0x1e7b       // 雨过天晴的文件过滤驱动
f7ad9bd8 805b0b3f 00000000 f7ad9c18 00000040 nt!ObpLookupObjectName+0x56a (FPO: [Non-Fpo])
f7ad9c2c 8056b133 00000000 00000000 4b31f001 nt!ObOpenObjectByName+0xeb (FPO: [Non-Fpo])
f7ad9ca8 8056baaa 0012fc04 00100001 0012fbd0 nt!IopCreateFile+0x407 (FPO: [Non-Fpo])
f7ad9d04 8056f291 0012fc04 00100001 0012fbd0 nt!IoCreateFile+0x8e (FPO: [Non-Fpo])
f7ad9d44 8053d808 0012fc04 00100001 0012fbd0 nt!NtOpenFile+0x27 (FPO: [Non-Fpo])
f7ad9d44 7c92eb94 0012fc04 00100001 0012fbd0 nt!KiFastCallEntry+0xf8 (FPO: [0,0] TrapFrame @ f7ad9d64)
0012fb80 7c92dd09 7c81e74a 0012fc04 00100001 ntdll!KiFastSystemCallRet (FPO: [0,0,0])
0012fb84 7c81e74a 0012fc04 00100001 0012fbd0 ntdll!NtOpenFile+0xc (FPO: [6,0,0])
0012fbfc 7c82744d 00000000 0012fc34 0012fc3c kernel32!GetDiskFreeSpaceExW+0x7d (FPO: [Non-Fpo])
0012fc14 0042cbe8 0012fc74 0012fc34 0012fc3c kernel32!GetDiskFreeSpaceExA+0x2f (FPO: [Non-Fpo])
0012fc40 0041180e 0012fc74 0012fc80 0012fc84 shieldtray+0x2cbe8
00000000 00000000 00000000 00000000 00000000 shieldtray+0x1180e

打开IDA,载入Shiedlf.sys,定位到0x103b4处,即可看出其具体的流程:


于是在Windbg中,强行将其改成如下图所示的代码:


此时再用XueTr.exe删除雨过天晴的设备,调用Winhex成功读取到更改后的MBR.




若我们不做这些更改,用Winhex得到的内容如下:


现在开启Bochs,即可调试雨过天晴的启动代码了.结合IDA静态看,很容易了解它的MBR所做的工作.通过这次调试跟踪,对自己是个小小的锻炼.其实用调试器改还不如写个驱动来的容易,不过最终目的达到了, 嘿嘿. 接下来我准备写个驱动,一劳永逸….


此实例旨在告诉大家遇到问题如何一步一步跟踪解决,灵活变通,重在积累调试经验!
附件: 您需要登录才可以下载或查看附件。没有帐号?注册

[亘古未有]1950年—2009年全国高考英语所有试题下载大全
2009年普通高等学校招生全国统一考试英语试题(全国各地试卷)
2008年普通高等学校招生全国统一考试英语试题(全国各地试卷)
2007年普通高等学校招生全国统一考试英语试题(全国各地试卷)
2006年普通高等学校招生全国统一考试英语试题(全国各地试卷)
2005年普通高等学校招生全国统一考试英语试题(全国各地试卷)
2004年普通高等学校招生全国统一考试英语试题(全国各地试卷)
2003年普通高等学校招生全国统一考试英语试题(全国各地试卷)
2002年普通高等学校招生全国统一考试英语试题(全国各地试卷)
2001年普通高等学校招生全国统一考试英语试题(全国各地试卷)
2000年普通高等学校招生全国统一考试英语试题(全国各地试卷)
1999年全国普通高等学校招生全国统一考试英语试题
1998年全国普通高等学校招生全国统一考试英语试题
1997年全国普通高等学校招生全国统一考试英语试题
1996年全国普通高等学校招生全国统一考试英语试题
1995年全国普通高等学校招生全国统一考试英语试卷
1994年全国普通高等学校招生全国统一考试英语试卷
1993年全国普通高等学校招生全国统一考试英语试题
1992年全国普通高等学校招生全国统一考试英语试题
1991年全国普通高等学校招生全国统一考试英语试题
1990年全国普通高等学校招生全国统一考试英语试题
1989年全国普通高等学校招生全国统一考试英语试题
1988年全国普通高等学校招生全国统一考试英语试题
1987年全国普通高等学校招生全国统一考试英语试题
1986年全国普通高等学校招生全国统一考试英语试题
1985年全国普通高等学校招生全国统一考试英语试题
1984年全国普通高等学校招生全国统一考试英语试题
1983年全国普通高等学校招生全国统一考试英语试题
1982年全国普通高等学校招生全国统一考试英语试题
1981年全国普通高等学校招生全国统一考试英语试题
1980年全国普通高等学校招生全国统一考试英语试题
1979年全国普通高等学校招生全国统一考试英语试题
1978年全国普通高等学校招生全国统一考试英语试题
1966年全国普通高等学校招生全国统一考试英语试题
1965年全国普通高等学校招生全国统一考试英语试题
1964年全国普通高等学校招生全国统一考试英语试题
1963年全国普通高等学校招生全国统一考试英语试题
1962年全国普通高等学校招生全国统一考试英语试题
1961年全国普通高等学校招生全国统一考试英语试题
1960年全国普通高等学校招生全国统一考试英语试题
1959年全国普通高等学校招生全国统一考试英语试题
1958年全国普通高等学校招生全国统一考试英语试题
1957年全国普通高等学校招生全国统一考试英语试题
1956年全国普通高等学校招生全国统一考试英语试题
1954年全国普通高等学校招生全国统一考试英语试题
1953年全国普通高等学校招生全国统一考试英语试题
1952年全国普通高等学校招生全国统一考试英语试题
1951年全国普通高等学校招生全国统一考试英语试题
1950年全国普通高等学校招生全国统一考试英语试题
推荐:更多精品高考英语资料下载大全,考试交流园地
2010年全国各省各名校高考英语期中期末联考月考模拟试题下载汇总(全部可自由下载)

TOP

膜拜  ................................

TOP

返回列表