文件过滤加密的源代码
//过滤读
NTSTATUS SfRead(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp)
{
PIO_STACK_LOCATION irp_stack;
BOOLEAN is_crypt;
NTSTATUS status;
PSFILTER_DEVICE_EXTENSION devExt;
PAGED_CODE();
ASSERT(!IS_MY_CONTROL_DEVICE_OBJECT( DeviceObject ));
ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));
devExt = (PSFILTER_DEVICE_EXTENSION)(DeviceObject->DeviceExtension);
if(Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO))
{
irp_stack = IoGetCurrentIrpStackLocation( Irp );
is_crypt = IsMyCryptFile(irp_stack->FileObject);
if(is_crypt) //是我的加密文件
{
//设置完成例程
IoCopyCurrentIrpStackLocationToNext( Irp );
IoSetCompletionRoutine(Irp, SfReadCompletion, 0, TRUE, FALSE, FALSE);
//调用原来的驱动
return IoCallDriver(devExt->AttachedToDeviceObject, Irp);
}
}
//非加密文件
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(devExt->AttachedToDeviceObject, Irp);
}
//读操作的完成例程
NTSTATUS SfReadCompletion(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp, __in PVOID Context)
{
ULONG length; //长度
PUCHAR buffer; //缓冲区
ULONG i;
PIO_STACK_LOCATION irp_stack;
irp_stack = IoGetCurrentIrpStackLocation( Irp );
ShowUnicodeString(&(irp_stack->FileObject->FileName));
DbgPrint("SfReadCompletion 读文件解密");
length = Irp->IoStatus.Information;
buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
for(i = 0; i < length; i++)
{
buffer[i] = buffer[i] - 17; //解密
}
return STATUS_SUCCESS;
}
//过滤写
NTSTATUS SfWrite(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp)
{
PIO_STACK_LOCATION irp_stack;
BOOLEAN is_crypt;
NTSTATUS status;
PSFILTER_DEVICE_EXTENSION devExt;
PAGED_CODE();
ASSERT(!IS_MY_CONTROL_DEVICE_OBJECT( DeviceObject ));
ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));
devExt = (PSFILTER_DEVICE_EXTENSION)(DeviceObject->DeviceExtension);
if(Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO))
{
irp_stack = IoGetCurrentIrpStackLocation( Irp );
is_crypt = IsMyCryptFile(irp_stack->FileObject);
if(is_crypt)
{
ULONG length; //长度
PUCHAR buffer, buffer2; //原来缓冲区和加密后缓冲区
ULONG i;
PMDL new_mdl;
length = irp_stack->Parameters.Write.Length;
buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
//分配同样大小的空间
buffer2 = (PUCHAR)ExAllocatePool(NonPagedPool, length);
if(buffer2 != 0)
{
ShowUnicodeString(&(irp_stack->FileObject->FileName));
DbgPrint("SfWrite 写文件加密");
for(i = 0; i < length; i++)
{
buffer2[i] = buffer[i] + 17; //加密
}
//设置完成例程
IoCopyCurrentIrpStackLocationToNext( Irp );
IoSetCompletionRoutine(Irp, SfWriteCompletion, Irp->MdlAddress, TRUE, TRUE, TRUE);
//替换成新的缓冲区
new_mdl = IoAllocateMdl(buffer2, length, FALSE, TRUE, NULL);
MmBuildMdlForNonPagedPool(new_mdl);
Irp->MdlAddress = new_mdl;
//调用原来的驱动
return IoCallDriver(devExt->AttachedToDeviceObject, Irp);
}
else
{
ShowUnicodeString(&(irp_stack->FileObject->FileName));
DbgPrint("SfWrite 写不能分配内存");
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
Irp->IoStatus.Information = 0;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return Irp->IoStatus.Status;
}
}
}
//非加密文件
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(devExt->AttachedToDeviceObject, Irp);
}
//写完成后就把分配的空间给删除掉
NTSTATUS SfWriteCompletion(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp, __in PVOID Context)
{
PMDL old_mdl, new_mdl;
PUCHAR buffer2; //我分配的缓冲区
PIO_STACK_LOCATION irp_stack;
irp_stack = IoGetCurrentIrpStackLocation( Irp );
ShowUnicodeString(&(irp_stack->FileObject->FileName));
DbgPrint("完成: SfWriteCompletion");
new_mdl = Irp->MdlAddress;
old_mdl = (PMDL)Context;
//还是指向原来的缓冲区
Irp->MdlAddress = old_mdl;
//删除掉我分配的缓冲区
buffer2 = MmGetSystemAddressForMdlSafe(new_mdl, NormalPagePriority);
IoFreeMdl(new_mdl);
ExFreePool(buffer2);
return STATUS_SUCCESS;
}
//文件打开的时候调用
NTSTATUS SfCreate(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp)
{
NTSTATUS status;
PSFILTER_DEVICE_EXTENSION devExt;
PAGED_CODE();
//如果不是过滤驱动设备就退出
if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject))
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return STATUS_SUCCESS;
}
ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));
devExt = (PSFILTER_DEVICE_EXTENSION)(DeviceObject->DeviceExtension);
//设置完成例程
IoCopyCurrentIrpStackLocationToNext( Irp );
IoSetCompletionRoutine(Irp, SfCreateCompletion, 0, TRUE, FALSE, FALSE);
//调用原来的驱动
return IoCallDriver( devExt->AttachedToDeviceObject, Irp );
}
//在打开文件的完成例程中记录文件对象
NTSTATUS SfCreateCompletion(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp, __in PVOID Context)
{
PIO_STACK_LOCATION irp_stack;
PFILE_OBJECT file_obj;
BOOLEAN is_crypt;
irp_stack = IoGetCurrentIrpStackLocation(Irp);
file_obj = irp_stack->FileObject;
is_crypt = IsMyCryptFile(file_obj);
if(is_crypt)
{
if(CcIsFileCached(file_obj))
{
ShowUnicodeString(&(file_obj->FileName));
DbgPrint("打开时清除缓存 \n");
CcPurgeCacheSection(file_obj->SectionObjectPointer, 0, 0, FALSE);
}
}
return STATUS_SUCCESS;
}
//关闭文件后的清理工作
NTSTATUS SfCleanupClose(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp)
{
NTSTATUS status;
PSFILTER_DEVICE_EXTENSION devExt;
PIO_STACK_LOCATION irp_stack;
PFILE_OBJECT file_obj;
BOOLEAN is_crypt;
PAGED_CODE();
if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject))
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return STATUS_SUCCESS;
}
ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));
irp_stack = IoGetCurrentIrpStackLocation(Irp);
file_obj = irp_stack->FileObject;
is_crypt = IsMyCryptFile(file_obj);
if(is_crypt)
{
if(CcIsFileCached(file_obj))
{
ShowUnicodeString(&(file_obj->FileName));
DbgPrint("关闭时清除缓存 \n");
CcPurgeCacheSection(file_obj->SectionObjectPointer, 0, 0, FALSE);
}
}
IoSkipCurrentIrpStackLocation( Irp );
devExt = (PSFILTER_DEVICE_EXTENSION)(DeviceObject->DeviceExtension);
return IoCallDriver(devExt->AttachedToDeviceObject, Irp);
}
开始写的时候,我本想保持保持缓冲区的数据同磁盘上一样,也是密文,这样就不用清理缓冲区了。但是试验没能成功,因为程序要是按照内存文件映射的方法或者DMA的方法读写缓冲区,我找不到机会解密。
作者:杨志朋
2010年1月28日
谨以此程序祝我能实现愿望,祝彩健康快乐。