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


    转载自http://www.misssir.cn/art/_show.aspx?art=49

    摘要:     我想做一个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的方法读写缓冲区,我找不到机会解密。

  • 相关阅读:
    徒手撸设计模式组合模式
    徒手撸设计模式过滤器模式
    徒手撸设计模式享元模式
    徒手撸设计模式桥接模式
    徒手撸设计模式命令模式
    徒手撸设计模式观察者模式
    徒手撸设计模式装饰器模式
    徒手撸设计模式责任链模式
    徒手撸设计模式代理模式
    徒手撸设计模式解释器模式
  • 原文地址:https://www.cnblogs.com/lzjsky/p/1881945.html
Copyright © 2020-2023  润新知