Vista/Win7的安全性有很大提高,对于磁盘的直接写入的防护就是其中一个方面。
详情我这里不多说,你可以自己参考MJ0011的《VISTA & WIN7对直接磁盘写入的防护》。
在文件系统层和磁盘层,都对磁盘直接写入有了防护。具体地,文件系统层体现在ntfs.sys和fat32.sys中,磁盘层应该是在volmgr.sys(未验证),所以不管是对卷的写入,还是对磁盘(PhysicalDriver)的写入,都统统没戏了。解决方法呢,就是用驱动啦~~下面的代码也是“上网记录深度擦除工具 V1.2”所带驱动的核心部分,用于实现对磁盘的直接写入。
下面是我源码中的一个重要函数,原函数来源于网上的开源代码,我只是稍做修改,在此表示对原作者表示感谢。
#define SL_FORCE_DIRECT_WRITE 0x10
NTSTATUS
IrpWriteFile(
IN PFILE_OBJECT FileObject,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL)
{
NTSTATUS ntStatus;
PIRP Irp;
KEVENT kEvent;
PIO_STACK_LOCATION IrpSp;
if (FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL)
return STATUS_UNSUCCESSFUL;
if (ByteOffset == NULL)
{
if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
return STATUS_INVALID_PARAMETER;
ByteOffset = &FileObject->CurrentByteOffset;
}
Irp = IoAllocateIrp(FileObject->Vpb->DeviceObject->StackSize, FALSE);
if (Irp == NULL) return STATUS_INSUFFICIENT_RESOURCES;
if(FileObject->DeviceObject->Flags & DO_BUFFERED_IO)
{
Irp->AssociatedIrp.SystemBuffer = Buffer;
}
else
{
Irp->MdlAddress = IoAllocateMdl(Buffer, Length, 0, 0, 0);
if (Irp->MdlAddress == NULL)
{
IoFreeIrp(Irp);
return STATUS_INSUFFICIENT_RESOURCES;
}
MmBuildMdlForNonPagedPool(Irp->MdlAddress);
}
KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
Irp->UserEvent = &kEvent;
Irp->UserIosb = IoStatusBlock;
Irp->RequestorMode = KernelMode;
Irp->Flags = IRP_WRITE_OPERATION;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject;
IrpSp = IoGetNextIrpStackLocation(Irp);
IrpSp->MajorFunction = IRP_MJ_WRITE;
IrpSp->MinorFunction = IRP_MN_NORMAL;
IrpSp->Flags=SL_FORCE_DIRECT_WRITE;//重要,Vista及以后必须加上该标志才行
IrpSp->DeviceObject = FileObject->Vpb->DeviceObject;
IrpSp->FileObject = FileObject;
IrpSp->Parameters.Write.Length = Length;
IrpSp->Parameters.Write.ByteOffset = *ByteOffset;
IoSetCompletionRoutine(Irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
ntStatus = IoCallDriver(FileObject->Vpb->DeviceObject, Irp);
if (ntStatus == STATUS_PENDING)
KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, NULL);
return IoStatusBlock->Status;
}
NTSTATUS
IoCompletionRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
{
*Irp->UserIosb = Irp->IoStatus;
if (Irp->UserEvent)
KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, 0);
if (Irp->MdlAddress)
{
IoFreeMdl(Irp->MdlAddress);
Irp->MdlAddress = NULL;
}
IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}
关键就在那个标志,其它都一样的,没什么好说的啦~~
详情我这里不多说,你可以自己参考MJ0011的《VISTA & WIN7对直接磁盘写入的防护》。
在文件系统层和磁盘层,都对磁盘直接写入有了防护。具体地,文件系统层体现在ntfs.sys和fat32.sys中,磁盘层应该是在volmgr.sys(未验证),所以不管是对卷的写入,还是对磁盘(PhysicalDriver)的写入,都统统没戏了。解决方法呢,就是用驱动啦~~下面的代码也是“上网记录深度擦除工具 V1.2”所带驱动的核心部分,用于实现对磁盘的直接写入。
下面是我源码中的一个重要函数,原函数来源于网上的开源代码,我只是稍做修改,在此表示对原作者表示感谢。
#define SL_FORCE_DIRECT_WRITE 0x10
NTSTATUS
IrpWriteFile(
IN PFILE_OBJECT FileObject,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL)
{
NTSTATUS ntStatus;
PIRP Irp;
KEVENT kEvent;
PIO_STACK_LOCATION IrpSp;
if (FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL)
return STATUS_UNSUCCESSFUL;
if (ByteOffset == NULL)
{
if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
return STATUS_INVALID_PARAMETER;
ByteOffset = &FileObject->CurrentByteOffset;
}
Irp = IoAllocateIrp(FileObject->Vpb->DeviceObject->StackSize, FALSE);
if (Irp == NULL) return STATUS_INSUFFICIENT_RESOURCES;
if(FileObject->DeviceObject->Flags & DO_BUFFERED_IO)
{
Irp->AssociatedIrp.SystemBuffer = Buffer;
}
else
{
Irp->MdlAddress = IoAllocateMdl(Buffer, Length, 0, 0, 0);
if (Irp->MdlAddress == NULL)
{
IoFreeIrp(Irp);
return STATUS_INSUFFICIENT_RESOURCES;
}
MmBuildMdlForNonPagedPool(Irp->MdlAddress);
}
KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
Irp->UserEvent = &kEvent;
Irp->UserIosb = IoStatusBlock;
Irp->RequestorMode = KernelMode;
Irp->Flags = IRP_WRITE_OPERATION;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject;
IrpSp = IoGetNextIrpStackLocation(Irp);
IrpSp->MajorFunction = IRP_MJ_WRITE;
IrpSp->MinorFunction = IRP_MN_NORMAL;
IrpSp->Flags=SL_FORCE_DIRECT_WRITE;//重要,Vista及以后必须加上该标志才行
IrpSp->DeviceObject = FileObject->Vpb->DeviceObject;
IrpSp->FileObject = FileObject;
IrpSp->Parameters.Write.Length = Length;
IrpSp->Parameters.Write.ByteOffset = *ByteOffset;
IoSetCompletionRoutine(Irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
ntStatus = IoCallDriver(FileObject->Vpb->DeviceObject, Irp);
if (ntStatus == STATUS_PENDING)
KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, NULL);
return IoStatusBlock->Status;
}
NTSTATUS
IoCompletionRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
{
*Irp->UserIosb = Irp->IoStatus;
if (Irp->UserEvent)
KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, 0);
if (Irp->MdlAddress)
{
IoFreeMdl(Irp->MdlAddress);
Irp->MdlAddress = NULL;
}
IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}
关键就在那个标志,其它都一样的,没什么好说的啦~~