youngwinter
驱动牛犊
驱动牛犊
  • 注册日期2004-08-23
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分363分
  • 威望39点
  • 贡献值0点
  • 好评度38点
  • 原创分0分
  • 专家分0分
阅读:3684回复:15

请教:透明加解密驱动无法解密

楼主#
更多 发布于:2007-03-16 19:38
  各位路过的大牛大侠帮忙看一下,我参考toolfat大牛的sfilter做的透明加解密过滤驱动,现在加密没有问题,写入磁盘的是加密过的数据,但解密时却遇到麻烦。比如拷贝一个文件到加密目录,新生成的文件被正确加密了,但再打开时看到的都是密文,而不是明文;在加密目录下新建一个文件,也是这个样子。除非重起机器,重新加载驱动,再打开加密目录下的文件,看到的才是明文。一直不解其中原因,不知道是哪里错了,请各位知道原因的指点一二。
主要代码如下:
NTSTATUS SfRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    NTSTATUS Status = STATUS_SUCCESS;
    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
    PSFILTER_DEVICE_EXTENSION DevExt = DeviceObject->DeviceExtension;
    PFILE_OBJECT FileObject = IrpSp->FileObject;
    PFILE_CONTEXT FileContext;
    PFILE_CONTEXT TempContext;
    BOOLEAN DecryptOnRead;

    PAGED_CODE();

    if (IS_MY_DEVICE_OBJECT(DeviceObject))
    {
        // We only care about volume filter device object, other create request will pass through
        if (NULL == DevExt->StorageStackDeviceObject)
        {
            goto _ReturnAddress;
        }

        // only IRP_NOCACHE, IRP_PAGING_IO, IRP_SYNCHRONOUS_PAGING_IO will be processed
        if (0 == (Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO)))
        {
            goto _ReturnAddress;
        }

        // try to find opened entry in the table
        TempContext = ExAllocateFromPagedLookasideList(&gFileContextLookasideList);
        if (NULL == TempContext)
        {
            DbgPrint("[%s] [%u] ExAllocateFromPagedLookasideList() failed, memory exhausted!\n", __FILE__, __LINE__);
            goto _ReturnAddress;
        }

        TempContext->FsContext = FileObject->FsContext;

        ExAcquireFastMutex(&DevExt->FsContextTableMutex);
        FileContext = RtlLookupElementGenericTable(&DevExt->FsContextTable, TempContext);
        ExReleaseFastMutex(&DevExt->FsContextTableMutex);

        ExFreeToPagedLookasideList(&gFileContextLookasideList, TempContext);

        if (NULL == FileContext)    // not in the generic table, skip it
        {
            goto _ReturnAddress;
        }

        if (IsFileNeedCrypt(DeviceObject, Irp, FileContext) == FALSE)    // not in the specified directory
        {
            goto _ReturnAddress;
        }

        // check decrypt flag when reading
        KeWaitForSingleObject(&FileContext->Event, Executive, KernelMode, FALSE, NULL);
        DecryptOnRead = FileContext->DecryptOnRead;
        KeSetEvent(&FileContext->Event, IO_NO_INCREMENT, FALSE);

        if (DecryptOnRead == FALSE)
        {
            goto _ReturnAddress;
        }

        DbgPrint("[%s] [%u] Try to read %u bytes from 0x%08X of file %s! FO=0x%08X\n",
            __FILE__, __LINE__, IrpSp->Parameters.Read.Length, IrpSp->Parameters.Read.ByteOffset.LowPart, FileContext->FullName.RealName, FileObject);

        //  Initialize an event to wait for the completion routine to occur
//        KeInitializeEvent(&WaitEvent, NotificationEvent, FALSE);

        //  Copy the stack and set our Completion routine
        IoCopyCurrentIrpStackLocationToNext(Irp);

        IoSetCompletionRoutine(Irp, SfReadCompletion, NULL, TRUE, TRUE, TRUE);

        //  Call the next driver in the stack.
        Status = IoCallDriver(DevExt->AttachedToDeviceObject, Irp);

        DbgPrint("[%s] [%u] Read %u bytes from 0x%08X of file %s succeed! FO=0x%08X\n",
            __FILE__, __LINE__, Irp->IoStatus.Information,
            IrpSp->Parameters.Read.ByteOffset.LowPart, FileContext->FullName.RealName, FileObject);

        return Status;

_ReturnAddress:
        IoSkipCurrentIrpStackLocation(Irp);
        return IoCallDriver(DevExt->AttachedToDeviceObject, Irp);
    }

    if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject))
    {
        DbgPrint("[%s] [%u] I(%wZ) received a request for %s!\n",
            __FILE__, __LINE__, &DEVICE_NAME, IRP_MJ_STRINGS[IrpSp->MajorFunction]);
        // Reset the Status & information of IRP
        Irp->IoStatus.Status = STATUS_SUCCESS;
        Irp->IoStatus.Information = 0;

        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return STATUS_SUCCESS;
    }

    // Wrong device object, come here seems to be impossible
    Irp->IoStatus.Status = STATUS_INVALID_HANDLE;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return STATUS_INVALID_HANDLE;
}

NTSTATUS SfReadCompletion(IN PDEVICE_OBJECT DeviceObject,
                          IN PIRP Irp,
                          IN PVOID Context)
{
    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
    PVOID ReadBuffer;
    PVOID MyBuffer = NULL;
    ULONG Length = 0;
    PRC4_KEY CryptKey;
    
    UNREFERENCED_PARAMETER(DeviceObject);
    UNREFERENCED_PARAMETER(Context);
    
    ASSERT(IS_MY_DEVICE_OBJECT(DeviceObject));
    
    Length = IrpSp->Parameters.Read.Length;
    ReadBuffer = (Irp->MdlAddress) ? MmGetSystemAddressForMdl(Irp->MdlAddress) : Irp->UserBuffer;
    ASSERT(ReadBuffer);

    // try to decrypt it
    CryptKey = ExAllocateFromNPagedLookasideList(&gCryptKeyLookasideList);
    if (NULL == CryptKey)
    {
        DbgPrint("[%s] [%u] ExAllocateFromNPagedLookasideList() failed, memory exhausted!\n", __FILE__, __LINE__);
        return  STATUS_INSUFFICIENT_RESOURCES;
    }
    
    Length = Irp->IoStatus.Information;
    
    // allocate temporal buffer
    MyBuffer = ExAllocatePoolWithTag(NonPagedPool, Length, SF_POOL_TAG);
    if (NULL == MyBuffer)
    {
        ExFreeToNPagedLookasideList(&gCryptKeyLookasideList, CryptKey);
        DbgPrint("[%s] [%u] ExAllocatePoolWithTag() failed, memory exhausted!\n", __FILE__, __LINE__);
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    
    memcpy(CryptKey, gpCryptKey, sizeof(RC4_KEY));
    memcpy(MyBuffer, ReadBuffer, Length);
    RC4(CryptKey, Length, (const PUCHAR)MyBuffer, (PUCHAR)ReadBuffer);
    
    ExFreePoolWithTag(MyBuffer, SF_POOL_TAG);
    ExFreeToNPagedLookasideList(&gCryptKeyLookasideList, CryptKey);

    return STATUS_SUCCESS;
}

最新喜欢:

moonsetmoonse... linshierlinshi... easydrivereasydr...
michaelgz
论坛版主
论坛版主
  • 注册日期2005-01-26
  • 最后登录2012-10-22
  • 粉丝1
  • 关注1
  • 积分150分
  • 威望1524点
  • 贡献值1点
  • 好评度213点
  • 原创分0分
  • 专家分2分
沙发#
发布于:2007-03-16 22:05
I think the problem may be in your MJ_WRITE routine. File cache is filled with encrypted data.
magichere
驱动小牛
驱动小牛
  • 注册日期2007-01-24
  • 最后登录2008-05-07
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望137点
  • 贡献值0点
  • 好评度136点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-03-18 17:16
May be
创造美好的未来生活!!!
youngwinter
驱动牛犊
驱动牛犊
  • 注册日期2004-08-23
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分363分
  • 威望39点
  • 贡献值0点
  • 好评度38点
  • 原创分0分
  • 专家分0分
地板#
发布于:2007-03-19 08:30
那请帮助看一下,我写的Write相关的代码是否有问题。万分感谢!
NTSTATUS SfWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    NTSTATUS Status = STATUS_SUCCESS;
    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
    PSfFILTER_DEVICE_EXTENSION DevExt = DeviceObject->DeviceExtension;
    PFILE_OBJECT FileObject = IrpSp->FileObject;
    PFILE_CONTEXT FileContext;
    PFILE_CONTEXT TempContext;
    KEVENT WaitEvent;
    PVOID WriteBuffer = NULL;
    PVOID MyBuffer = NULL;
    ULONG Length = 0;
    PRC4_KEY CryptKey;
    BOOLEAN EncryptOnWrite;
    
    PAGED_CODE();
    
    if (IS_MY_DEVICE_OBJECT(DeviceObject))
    {
        // We only care about volume filter device object, other create request will pass through
        if (NULL == DevExt->StorageStackDeviceObject)
        {
            goto _ReturnAddress2;
        }

        // only IRP_NOCACHE, IRP_PAGING_IO, IRP_SYNCHRONOUS_PAGING_IO will be processed
        if (0 == (Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO)))
        {
            goto _ReturnAddress2;
        }

        // try to find opened entry in the table
        TempContext = ExAllocateFromPagedLookasideList(&gFileContextLookasideList);
        if (NULL == TempContext)
        {
            DbgPrint("[%s] [%u] ExAllocateFromPagedLookasideList() failed, memory exhausted!\n", __FILE__, __LINE__);
            goto _ReturnAddress2;
        }

        TempContext->FsContext = FileObject->FsContext;

        ExAcquireFastMutex(&DevExt->FsContextTableMutex);
        FileContext = RtlLookupElementGenericTable(&DevExt->FsContextTable, TempContext);
        ExReleaseFastMutex(&DevExt->FsContextTableMutex);

        ExFreeToPagedLookasideList(&gFileContextLookasideList, TempContext);

        if (NULL == FileContext)    // not in the generic table, skip it
        {
            goto _ReturnAddress2;
        }

        if (IsFileNeedCrypt(DeviceObject, Irp, FileContext) == FALSE)    // not in the specified directory
        {
            goto _ReturnAddress2;
        }

        // check decrypt flag when reading
        KeWaitForSingleObject(&FileContext->Event, Executive, KernelMode, FALSE, NULL);
        EncryptOnWrite = FileContext->EncryptOnWrite;
        KeSetEvent(&FileContext->Event, IO_NO_INCREMENT, FALSE);

        if (EncryptOnWrite == FALSE)
        {
            goto _ReturnAddress2;
        }

        Length = IrpSp->Parameters.Write.Length;

        DbgPrint("[%s] [%u] Try to write %u bytes from 0x%08X of file %s! FO=0x%08X\n",
            __FILE__, __LINE__, Length, IrpSp->Parameters.Write.ByteOffset.LowPart,
            FileContext->FullName.RealName, FileObject);

        // try encrypt data before write it
        CryptKey = ExAllocateFromNPagedLookasideList(&gCryptKeyLookasideList);
        if (NULL == CryptKey)
        {
            DbgPrint("[%s] [%u] ExAllocateFromNPagedLookasideList() failed, memory exhausted!\n", __FILE__, __LINE__);
            Status = STATUS_INSUFFICIENT_RESOURCES;
            goto _ReturnAddress1;
        }

        // allocate temporal buffer
        MyBuffer = ExAllocatePoolWithTag(NonPagedPool, Length, SfFS_POOL_TAG);
        if (NULL == MyBuffer)
        {
            ExFreeToNPagedLookasideList(&gCryptKeyLookasideList, CryptKey);
            DbgPrint("[%s] [%u] ExAllocatePoolWithTag() failed, memory exhausted!\n", __FILE__, __LINE__);
            Status = STATUS_INSUFFICIENT_RESOURCES;
            goto _ReturnAddress1;
        }

        WriteBuffer = (Irp->MdlAddress) ? MmGetSystemAddressForMdl(Irp->MdlAddress) : Irp->UserBuffer;
        ASSERT(WriteBuffer);

        memcpy(CryptKey, gpCryptKey, sizeof(RC4_KEY));
        memcpy(MyBuffer, WriteBuffer, Length);
        RC4(CryptKey, Length, (const PUCHAR)MyBuffer, (PUCHAR)WriteBuffer);

        ExFreePoolWithTag(MyBuffer, SfFS_POOL_TAG);
        ExFreeToNPagedLookasideList(&gCryptKeyLookasideList, CryptKey);

        //  Initialize an event to wait for the completion routine to occur
        KeInitializeEvent(&WaitEvent, NotificationEvent, FALSE);

        //  Copy the stack and set our Completion routine
        IoCopyCurrentIrpStackLocationToNext(Irp);

        IoSetCompletionRoutine(Irp, SfWriteCompletion, &WaitEvent, TRUE, TRUE, TRUE);

        //  Call the next driver in the stack.
        Status = IoCallDriver(DevExt->AttachedToDeviceObject, Irp);

        //  Wait for the completion routine to be called
        if (STATUS_PENDING == Status)
        {
            ASSERT(STATUS_SUCCESS == KeWaitForSingleObject(&WaitEvent, Executive, KernelMode, FALSE, NULL));
        }

        //  Verify the IoCompleteRequest was called
        ASSERT(KeReadStateEvent(&WaitEvent) != 0 || !NT_SUCCESS(Irp->IoStatus.Status));

        // We don't care about failed requests
        if (!NT_SUCCESS(Irp->IoStatus.Status) || Irp->IoStatus.Status == STATUS_REPARSE)
        {
            DbgPrint("[%s] [%u] Write %u bytes from 0x%08X of file %s failed!\n",
                __FILE__, __LINE__, Irp->IoStatus.Information,
                IrpSp->Parameters.Write.ByteOffset.LowPart, FileContext->FullName.RealName);
            goto _ReturnAddress1;
        }

        DbgPrint("[%s] [%u] Write %u bytes from 0x%08X of file %s succeed! FO=0x%08X\n",
            __FILE__, __LINE__, Irp->IoStatus.Information,
            IrpSp->Parameters.Write.ByteOffset.LowPart, FileContext->FullName.RealName, FileObject);

_ReturnAddress1:
        Status = Irp->IoStatus.Status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return Status;

_ReturnAddress2:    //  Save the Status and continue processing the IRP
        IoSkipCurrentIrpStackLocation(Irp);
        return IoCallDriver(DevExt->AttachedToDeviceObject, Irp);
    }
    
    if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject))
    {
        DbgPrint("[%s] [%u] I(%wZ) received a request for %s!\n",
            __FILE__, __LINE__, &DEVICE_NAME, IRP_MJ_STRINGS[IrpSp->MajorFunction]);
        // Reset the Status & information of IRP
        Irp->IoStatus.Status = STATUS_SUCCESS;
        Irp->IoStatus.Information = 0;
        
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return STATUS_SUCCESS;
    }
    
    // Wrong device object, come here seems to be impossible
    Irp->IoStatus.Status = STATUS_INVALID_HANDLE;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return STATUS_INVALID_HANDLE;
}

NTSTATUS SfWriteCompletion(IN PDEVICE_OBJECT DeviceObject,
                           IN PIRP Irp,
                           IN PVOID Context)
{
    PKEVENT Event = Context;
    
    UNREFERENCED_PARAMETER(DeviceObject);
    UNREFERENCED_PARAMETER(Irp);
    
    ASSERT(IS_MY_DEVICE_OBJECT(DeviceObject));
    KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
    return STATUS_MORE_PROCESSING_REQUIRED;
}
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
地下室#
发布于:2007-03-19 09:13
必须静态安装好后才行,动态的不行.
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
youngwinter
驱动牛犊
驱动牛犊
  • 注册日期2004-08-23
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分363分
  • 威望39点
  • 贡献值0点
  • 好评度38点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2007-03-19 16:45
引用第4楼wowocock2007-03-19 09:13发表的“”:
必须静态安装好后才行,动态的不行.


继续请教,使用sfilter.inf修改后进行静态安装,结果重起后在DriverEntry()里的IoCreateDevice()出错,错误码STATUS_OBJECT_NAME_COLLISION,请问是什么原因啊?如何修改避免?
storybaby
驱动牛犊
驱动牛犊
  • 注册日期2006-08-12
  • 最后登录2009-05-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望19点
  • 贡献值0点
  • 好评度18点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2007-04-06 21:30
请问你加密文件结尾怎么判断的呢??
goodone
驱动牛犊
驱动牛犊
  • 注册日期2007-01-30
  • 最后登录2014-04-30
  • 粉丝3
  • 关注0
  • 积分372分
  • 威望174点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2007-04-08 21:47
我也遇到相同问题,哪位大牛能在给些建议啊
栀子花驿站 www.zhizihua.com
qihuiling_0304
驱动牛犊
驱动牛犊
  • 注册日期2007-03-18
  • 最后登录2010-11-15
  • 粉丝0
  • 关注0
  • 积分662分
  • 威望68点
  • 贡献值0点
  • 好评度66点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2007-05-19 16:40
楼主用的是什么加密算法?
~要有追求卓越的执著~
blueshelly
驱动牛犊
驱动牛犊
  • 注册日期2007-06-04
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分140分
  • 威望15点
  • 贡献值0点
  • 好评度14点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2007-06-04 15:56
RC4加密算法是等长加密吗?
驱网无线,快乐无限
jl2004
驱动小牛
驱动小牛
  • 注册日期2007-04-10
  • 最后登录2011-02-22
  • 粉丝0
  • 关注0
  • 积分21分
  • 威望276点
  • 贡献值0点
  • 好评度129点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2007-06-07 11:18
问题出在写函数中.
向前,向前,向前....
jl2004
驱动小牛
驱动小牛
  • 注册日期2007-04-10
  • 最后登录2011-02-22
  • 粉丝0
  • 关注0
  • 积分21分
  • 威望276点
  • 贡献值0点
  • 好评度129点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2007-06-07 11:25
具体问题是WriteBuffer 所指向的区域的数据.

1.在加密之前它是明文.
2.向下写入硬盘后,WriteBuffer 所指的区域还必须恢复为明文,而不能为
  密文.
3.否则,出现楼主的问题.

一句话Irp->Mdladdres or Irp->Userbuffer所指向的数据在加密之后要
进行还原为明文!!!
向前,向前,向前....
jl2004
驱动小牛
驱动小牛
  • 注册日期2007-04-10
  • 最后登录2011-02-22
  • 粉丝0
  • 关注0
  • 积分21分
  • 威望276点
  • 贡献值0点
  • 好评度129点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2007-06-07 11:27


   // Wait for the completion routine to be called
       if (STATUS_PENDING == Status)
       {
           ASSERT(STATUS_SUCCESS == KeWaitForSingleObject(&WaitEvent, Executive, KernelMode, FALSE, NULL));
       }

之后加入还原的处理即可,当然一开如必须开一个buffer保存以前的明文.
向前,向前,向前....
Pegram
论坛版主
论坛版主
  • 注册日期2005-12-03
  • 最后登录2013-08-23
  • 粉丝13
  • 关注5
  • 积分1333分
  • 威望4717点
  • 贡献值1点
  • 好评度78点
  • 原创分0分
  • 专家分2分
13楼#
发布于:2007-12-29 16:28
InitializeObjectAttributes的时候,要设置OBJ_OPENIF属性就可以了。
《寒江独钓》与《竹林蹊径》的合作作者。精通USB开发,设计了CY001 USB驱动套件(http://bbs.driverdevelop.com/read.php?tid-119314.html)。
huangyehui
驱动牛犊
驱动牛犊
  • 注册日期2008-03-13
  • 最后登录2008-05-12
  • 粉丝0
  • 关注0
  • 积分270分
  • 威望28点
  • 贡献值0点
  • 好评度27点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2008-04-23 10:20
感谢jl2004,我也有同样的问题。 解决了
Stephenlsd
驱动牛犊
驱动牛犊
  • 注册日期2010-05-25
  • 最后登录2010-11-07
  • 粉丝0
  • 关注0
  • 积分3分
  • 威望31点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2010-11-07 22:57
请问你是怎么解决的?
游客

返回顶部