過濾驅動加密文件(代碼)
摘要: 我想做一個unlocker一樣的程序,不管這個文件有沒有被使用,先實現刪除它。在查資料過程中,就知道了如果不訪問磁盤扇區的話,除非寫驅動才能做到。奈何時間有限,工作匆忙,一直沒有完成。而且忽視了更簡便的方法——在別的路徑下把修改後的OCX控件重新注冊一下就可以了。 |
文件過濾加密的源代碼
//過濾讀 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的方法讀寫緩衝區,我找不到機會解密。 |
最後更新:2017-04-03 15:21:56