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