min = 1564272; if (irp_stack->Parameters.Scsi.Srb->QueueSortKey <= max && irp_stack->Parameters.Scsi.Srb->QueueSortKey >= min) { KdPrint(("\natapi @ fake_handle : OperationCode is %02x, QueueSortKey is %d\n", irp_stack->Parameters.Scsi.Srb->Cdb[0], irp_stack->Parameters.Scsi.Srb->QueueSortKey)); Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); KdBreakPoint(); return STATUS_UNSUCCESSFUL; } return STATUS_SUCCESS; } NTSTATUS fake_scsi_dispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP irp ) { NTSTATUS status ; status = fake_handle(DeviceObject, irp); if (!NT_SUCCESS(status)) { return status; } else { _asm { push eax push irp push DeviceObject call g_orig_scsi_dispatch mov status, eax pop eax } return status; } } 给出的代码可以阻止对文件FsControl.exe的任何操作。用 WinHex对FsControl进行 读取时,会有如图2所示的结果,代理函数成功的中断。 图 2 最后的补充,笔者在阅读classpnp源码时发现,有的情况下 ClassReadWrite也会直接 调用atapi.sys的StartIo例程来处理,而不是ServiceTransferRequest(),所以在代码 中笔者也hook了atapi的StartIo例程, 详细请见随书的源码。还有, 为什么笔者用WinHex 进行实验?因为在文件进行一次读取后,Windows的Cache管理器会把文件保存在内存中一 个叫做VACB的数组里。所以可能只会捕捉到一次中断,更具体的原因请读者自行搜索。 本文ring3代码在VC6中编译,驱动在xpsp3+WDK中编译,所有程序在xp+sp3中成功 运行。Classpnp源码包含在WDK中,读者可自行查阅。存储设备十分复杂,加之行文仓促, |