过滤驱动加密文件(代码)

摘要:     我想做一个unlocker一样的程序,不管这个文件有没有被使用,先实现删除它。在查资料过程中,就知道了如果不访问磁盘扇区的话,除非写驱动才能做到。奈何时间有限,工作匆忙,一直没有完成。而且忽视了更简便的方法——在别的路径下把修改后的OCX控件重新注册一下就可以了。

    这些都不要说了,这段闲暇时间,我写了一个过滤加密,就这么简单。在DDK的示例Sfilter基础上改的。

 

文件过滤加密的源代码

 

//过滤读

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的方法读写缓冲区,我找不到机会解密。

你可能感兴趣的:(文件)