首页
社区
课程
招聘
[原创]调试笔记之雨过天晴多点还原软件MBR实例
发表于: 2009-9-22 22:49 61251

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

2009-9-22 22:49
61251
为了能够调试多点还原软件"雨过天晴"的启动代码,目前有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内,代码如下:


[COLOR=#000000]NTSTATUS IrpInternalDeviceControl(int DeviceObject, PIRP Irp)
[COLOR=#000000]{
[COLOR=#000000]  int DeviceExtension, srb, atapi_driver_object, disk_driver_object, srb_cdb, IoControlCode ;  
[COLOR=#000000]  HANDLE CurrentTID;   
[COLOR=#000000]  struct _IRP::$::$::$::$A02EC6A2CE86544F716F4825015773AC::_IO_STACK_LOCATION *CurrentStackLocation; 
[COLOR=#000000]  char OperationCode;  
[COLOR=#000000] 
[COLOR=#000000]  DeviceExtension = *(DWORD *)(DeviceObject + 0x28);
[COLOR=#000000]  CurrentTID = PsGetCurrentThreadId();
[COLOR=#000000]  PsGetCurrentProcessId();
[COLOR=#000000]  srb = 0;
[COLOR=#000000]  if ( g_disk_internal_device_control_dispatch )
[COLOR=#000000]  {
[COLOR=#000000]    disk_driver_object = *(DWORD *)(g_disk_device_object + 8);
[COLOR=#000000]    if ( *(DWORD *)(disk_driver_object + 0x74) != g_disk_internal_device_control_dispatch
[COLOR=#000000]      || *(DWORD *)(disk_driver_object + 0x48) != g_disk_internal_device_control_dispatch 
[COLOR=#000000]       )
[COLOR=#000000]    {// 
[COLOR=#000000]     // #define IRP_MJ_INTERNAL_DEVICE_CONTROL    0x0f
[COLOR=#000000]     // #define IRP_MJ_SCSI                       0x0f
[COLOR=#000000]     // [COLOR=#000000][FONT=Verdana][FONT=宋体]雨过天晴会不断检查自己的[/FONT]HOOK[FONT=宋体]点[/FONT],[FONT=宋体]并恢复之[/FONT].[FONT=宋体]若[/FONT]2[FONT=宋体]个程序同时在同一点[/FONT][/FONT]
[COLOR=#000000]     // [COLOR=#000000][FONT=Verdana][FONT=宋体]循环检查并恢复自己的钩子[/FONT],[FONT=宋体]会导致系统启动后及其缓慢[/FONT]. [FONT=宋体]而且[/FONT]"[FONT=宋体]雨过天晴[/FONT]"[FONT=宋体]会结束[/FONT][/FONT]
[COLOR=#000000]     // [COLOR=#000000][FONT=Verdana][FONT=宋体]掉与其竞争的系统线程[/FONT],[FONT=宋体]导致系统出现异常错误[/FONT].BSOD.[/FONT]
[COLOR=#000000]     // 
[COLOR=#000000]      *(DWORD *)(disk_driver_object + 0x74) = g_disk_internal_device_control_dispatch;
[COLOR=#000000]      *(DWORD *)(disk_driver_object + 0x48) = g_disk_internal_device_control_dispatch;
[COLOR=#000000] 
[COLOR=#000000]// disk[FONT=Verdana][FONT=宋体]分发例程往下发的时候[/FONT],[FONT=宋体]起扩展设备偏移[/FONT]+0x008[FONT=宋体]的地方是[/FONT]atapi.sys[FONT=宋体]的设备对象[/FONT],"[FONT=宋体]雨过天晴[/FONT]"[FONT=宋体]在此进行验证[/FONT].[/FONT]
[COLOR=#000000]      if ( *(DWORD *)(DeviceExtension + 8) == g_atapi_device_object )
[COLOR=#000000]      {
[COLOR=#000000]        if ( g_allowed_TID_1_0000006c
[COLOR=#000000]          && CurrentTID != *(HANDLE *)g_allowed_TID_1_0000006c
[COLOR=#000000]          && g_allowed_TID_2_ffffffff
[COLOR=#000000]          && CurrentTID != *(HANDLE *)g_allowed_TID_2_ffffffff
[COLOR=#000000]          && g_allowed_TID_3_00000070
[COLOR=#000000]          && CurrentTID != *(HANDLE *)g_allowed_TID_3_00000070
[COLOR=#000000]          && g_allowed_TID_4_00000240
[COLOR=#000000]          && CurrentTID != *(HANDLE *)g_allowed_TID_4_00000240 )
[COLOR=#000000]        {
[COLOR=#000000]// [FONT=Verdana][FONT=宋体]不是以上[/FONT]4[FONT=宋体]个系统线程[/FONT],[FONT=宋体]便会被[/FONT]"[FONT=宋体]雨过[/FONT]"[FONT=宋体]结束掉[/FONT],[FONT=宋体]并且阻止当前[/FONT]IRP[FONT=宋体]的下发[/FONT].[FONT=宋体]于是就[/FONT]BSOD[FONT=宋体]了[/FONT].[/FONT]
[COLOR=#000000]          ZwTerminateProcess((HANDLE)0xFFFFFFFF, 0);            
[COLOR=#000000]denny:
[COLOR=#000000]          Irp->IoStatus.Status = 0;
[COLOR=#000000]          IofCompleteRequest(Irp, 0);
[COLOR=#000000]          return 0;
[COLOR=#000000]        }
[COLOR=#000000]      }
[COLOR=#000000]    }
[COLOR=#000000]    atapi_driver_object = *(DWORD *)(g_atapi_device_object + 8);
[COLOR=#000000]if ( *(DWORD *)(atapi_driver_object + 0x74) != (DWORD)atapi_Proxy_dispatch ) // [COLOR=#000000][FONT=Verdana][FONT=宋体]在此处恢复对[/FONT]atapi.sys[FONT=宋体]分发例程的[/FONT]HOOK[/FONT]
[COLOR=#000000]      memset((void *)(atapi_driver_object + 0x38), (int)atapi_Proxy_dispatch, 0x6Cu);
[COLOR=#000000]  }
[COLOR=#000000] 
[COLOR=#000000]  CurrentStackLocation = Irp->Tail.Overlay.CurrentStackLocation;
[COLOR=#000000]  IoControlCode = *((DWORD *)CurrentStackLocation + 3);
[COLOR=#000000]  srb_cdb = 0;
[COLOR=#000000]  if ( IoControlCode == 0x1B0012 || IoControlCode == 0x1B0011 )
[COLOR=#000000]  {
[COLOR=#000000]    srb = *((DWORD *)CurrentStackLocation + 1);
[COLOR=#000000]    srb_cdb = srb + 0x30;
[COLOR=#000000]  }
[COLOR=#000000]  if ( *(DWORD *)(DeviceExtension + 8) == g_atapi_device_object )
[COLOR=#000000]  {
[COLOR=#000000]    if ( g_allowed_TID_1_0000006c )
[COLOR=#000000]    {
[COLOR=#000000]      if ( CurrentTID != *(HANDLE *)g_allowed_TID_1_0000006c )
[COLOR=#000000]      {
[COLOR=#000000]        if ( !g_allowed_TID_2_ffffffff || CurrentTID != *(HANDLE *)g_allowed_TID_2_ffffffff )
[COLOR=#000000]        {
[COLOR=#000000]          if ( !g_allowed_TID_3_00000070 || CurrentTID != *(HANDLE *)g_allowed_TID_3_00000070 )
[COLOR=#000000]          {
[COLOR=#000000]            if ( !g_allowed_TID_4_00000240 || CurrentTID != *(HANDLE *)g_allowed_TID_4_00000240 )
[COLOR=#000000]            {
[COLOR=#000000]              if ( srb )
[COLOR=#000000]              {
[COLOR=#000000]                if ( !*(BYTE *)(srb + 2) )
[COLOR=#000000]                {
[COLOR=#000000]                  if ( srb_cdb )
[COLOR=#000000]                  {
[COLOR=#000000]                    OperationCode = *(BYTE *)srb_cdb;
[COLOR=#000000]                    if ( *(BYTE *)srb_cdb == SCSIOP_WRITE
[COLOR=#000000]                      || OperationCode == SCSIOP_SEND
[COLOR=#000000]                      || OperationCode == SCSIOP_FLUSH_BUFFER
[COLOR=#000000]                      || OperationCode == SCSIOP_WRITE_VERIFY
[COLOR=#000000]                      || OperationCode == SCSIOP_READ
[COLOR=#000000]                      || OperationCode == SCSIOP_RECEIVE )
[COLOR=#000000]                      goto denny;
[COLOR=#000000]                  }
[COLOR=#000000]                }
[COLOR=#000000]              }
[COLOR=#000000]            }
[COLOR=#000000]          }
[COLOR=#000000]        }
[COLOR=#000000]      }
[COLOR=#000000]    }
[COLOR=#000000]  }
[COLOR=#000000] 
[COLOR=#000000]  return IrpReadWrite_dep(DeviceObject, Irp);
[COLOR=#000000]}


(1) 现在调试器中将jnz 改成 Jmp, 0F 84 à 90 E9


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

(因为我的程序是自己构建IRP,填充0xf号控制码,isl->MajorFunction =   IRP_MJ_SCSI,然后发送到DR0设备上, 那么IRP往下走的过程中就会调用DR0对应的驱动对象的分发例程,也就是Disk.sys0xf号分发例程,而非IRP_MJ_READ,所以根据我的程序特性,应该恢复Disk.sysIRP_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步终于成功.
步骤一: 废掉ygtqdisk & atapi分发例程的循环保护
步骤二: 恢复disk.sys atapi.sys0xf号分发例程
步骤三: 自己构建IRP,发送到DR0设备对象上,获取MBR


kd> !devstack 0x81b874e0
  !DevObj   !DrvObj            !DevExt   ObjectName

  81bc4918  \Driver\PartMgr    81bc49d0  

  81b7d878  \Driver\Shield     81b7d930           // ß 注意这里,雨过天晴在Shildf.sys中循环恢复这个AttachDR0上的过滤设备,
                                                                              // WinhexMBR,到这里就被重定向了.
  81bc4030  \Driver\Disk       81bc40e8  DR0  // ß 我的IRP发到此处,终于可以读到原始的MBR
                                                                              // 若不恢复Disk.sys0xf号分发例程,就会被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所做的工作.通过这次调试跟踪,对自己是个小小的锻炼.其实用调试器改还不如写个驱动来的容易,不过最终目的达到了, 嘿嘿. 接下来我准备写个驱动,一劳永逸….


此实例旨在告诉大家遇到问题如何一步一步跟踪解决,灵活变通,重在积累调试经验!

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
免费 8
支持
分享
最新回复 (79)
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
2
123456
上传的附件:
2009-9-22 22:57
0
雪    币: 115
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
ding一个
2009-9-22 23:24
0
雪    币: 150
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
好不懂 膜拜啊啊啊
2009-9-22 23:35
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
5
太强大了 看不懂啊
2009-9-22 23:55
0
雪    币: 8865
活跃值: (2379)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
6
没那么复杂~
根据VMW开放的代码可以直接从VMware的img文件里提取出disk.img来不多说了~
弄这么复杂干啥~

唉~
2009-9-22 23:58
0
雪    币: 205
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
太复杂了。。看不懂。
2009-9-23 00:02
0
雪    币: 284
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
坐个大沙发,顶sudami
2009-9-23 00:04
0
雪    币: 5
活跃值: (369)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
关注下六楼  等高人
2009-9-23 00:18
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
神奇的楼主...
2009-9-23 01:17
0
雪    币: 337
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
教授就是教授啊,写的东西都那么强
2009-9-23 02:00
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
知道的太少了
2009-9-23 08:26
0
雪    币: 1233
活跃值: (907)
能力值: ( LV12,RANK:750 )
在线值:
发帖
回帖
粉丝
13
学习下调试倒是可以,不过调试不是软件的核心,创造比复制更重要,调试只是一种辅助,虽然调试很重要,但仅此而已
2009-9-23 08:48
0
雪    币: 367
活跃值: (20)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
14
精神可嘉,要吃鸡蛋,不必从养鸡开始.
直接从虚拟机文件dump出来更省事.
2009-9-23 08:58
0
雪    币: 1233
活跃值: (907)
能力值: ( LV12,RANK:750 )
在线值:
发帖
回帖
粉丝
15
qemu-img.exe convert  c:\.....vmdk   e:\disk.img
2009-9-23 10:02
0
雪    币: 1407
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
膜拜大米
另外学习一下LS的做法
2009-9-23 10:43
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
17
我火星了....
2009-9-23 10:50
0
雪    币: 178
活跃值: (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
18
图文并貌,很详细,学习了
2009-9-23 11:13
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
就是太牛了,看不懂啊
2009-9-23 11:33
0
雪    币: 1432
活跃值: (823)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
教授啊~~~~~~~
2009-9-23 13:04
0
雪    币: 433
活跃值: (1875)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
21
support!这玩意太高级了,放弃学习
2009-9-23 13:14
0
雪    币: 1708
活跃值: (586)
能力值: ( LV15,RANK:670 )
在线值:
发帖
回帖
粉丝
22
大咪太强大了,无法学习...
2009-9-23 14:26
0
雪    币: 1919
活跃值: (901)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
23
强啊,收藏一份
2009-9-23 14:29
0
雪    币: 239
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
强贴留名,收藏
2009-9-24 11:53
0
雪    币: 768
活跃值: (515)
能力值: ( LV13,RANK:460 )
在线值:
发帖
回帖
粉丝
25
强悍!!!!
作者收学生不?
2009-9-24 20:02
0
游客
登录 | 注册 方可回帖
返回
//