fancylf
驱动牛犊
驱动牛犊
  • 注册日期2007-07-29
  • 最后登录2016-06-21
  • 粉丝1
  • 关注0
  • 积分61分
  • 威望501点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分0分
  • 社区居民
阅读:3382回复:5

调试IRP_MJ_DIRECTORY_CONTROL 发现的一个奇怪的问题

楼主#
更多 发布于:2008-10-23 15:51
首先谢谢boywhp,,我根据你的代码,结合sfiter ,做了一下隐藏文件的测试,
先贴代码,然后再说:
如下:

NTSTATUS
DirControlCompletion(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;    //注:必须返回这个值
}



BOOLEAN
HandleDirectory(IN OUT PFILE_BOTH_DIR_INFORMATION DirInfo, IN PULONG lpBufLenth)
{
        //处理目录操作
        PFILE_BOTH_DIR_INFORMATION currentDirInfo = DirInfo;
        ULONG offset = 0;
        ULONG position = 0;
        ULONG newLenth = *lpBufLenth;

        WCHAR wFileName[MAX_PATH]={0};
        UNICODE_STRING uCurFile;

        UNICODE_STRING uComFile1;
        UNICODE_STRING uComFile2;
        UNICODE_STRING uComFile3;
        UNICODE_STRING uComFile4;


        RtlInitUnicodeString(&uComFile1,L"hidetest.txt");
        RtlInitUnicodeString(&uComFile2,L"中国");
        RtlInitUnicodeString(&uComFile3,L"Admin");
        RtlInitUnicodeString(&uComFile4,L"测试.txt");

        do
        {
            //下一个文件对象的地址
            offset = currentDirInfo->NextEntryOffset;
            RtlZeroMemory(wFileName,sizeof(WCHAR)*MAX_PATH);
            RtlCopyMemory(wFileName,currentDirInfo->FileName,currentDirInfo->FileNameLength);
            KdPrint(("Current file: %ws\n",wFileName));

            RtlInitUnicodeString(&uCurFile,wFileName);
            //这里从隐藏列表中查找一下是否当前文件要隐藏

            if (RtlCompareUnicodeString(&uCurFile,&uComFile1,TRUE)==0
                ||RtlCompareUnicodeString(&uCurFile,&uComFile2,TRUE)==0
                ||RtlCompareUnicodeString(&uCurFile,&uComFile3,TRUE)==0
                ||RtlCompareUnicodeString(&uCurFile,&uComFile4,TRUE)==0)
            {
            
                //Now We Will Test The FileName
                 KdPrint(("Hided File:%ws ,File nameLength:%d\n",wFileName, currentDirInfo->FileNameLength));
                
                 //用后面的内存区域覆盖前面区域
                 RtlMoveMemory(currentDirInfo, (PUCHAR)currentDirInfo + offset, *lpBufLenth - position - offset);
                
                 //返回的长度
                 newLenth -= offset;
                 //向后移动
                 position += offset;
            }
          else
          {          
              if(currentDirInfo->FileAttributes&FILE_ATTRIBUTE_DIRECTORY)
              {
                  KdPrint(("Directory :"));
              }
              else
              {
                  KdPrint(("File      :"));
              }
                  
              KdPrint(("%ws ,File nameLength:%d\n",              wFileName,
                                                              currentDirInfo->FileNameLength));                        //Move Next            
              position += offset;                
              currentDirInfo = (PFILE_BOTH_DIR_INFORMATION)((PUCHAR)currentDirInfo + offset);    
          }
        } while (0 != offset);
        
        *lpBufLenth = newLenth;    
        return TRUE;
}


/*
*    驱动的目录处理函数
*/
NTSTATUS
sfDirectControl(
   IN  PDEVICE_OBJECT  DeviceObject,
   IN  PIRP   Irp
   )
{
        NTSTATUS status;
        PIO_STACK_LOCATION irpSp  = IoGetCurrentIrpStackLocation(Irp);    //当前Irp(IO_STACK_LOCATION)的参数
        PSFILTER_DEVICE_EXTENSION deExt= DeviceObject->DeviceExtension;
        PFILE_OBJECT pFileObject=irpSp->FileObject;
        KEVENT waitEvent;

        //文件所在的盘符
        UNICODE_STRING uDosName;    
        //以下两个变量用来保存打开或是创建的文件的全路径
        WCHAR szFilePath[MAX_PATH+10]={0};
        UNICODE_STRING uFileFullPath;

        ASSERT(!IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject));
        ASSERT(IS_MY_DEVICE_OBJECT(DeviceObject));
    
        if (IRP_MN_QUERY_DIRECTORY != irpSp->MinorFunction)
        {
             goto SkipHandle;
        }

        if (Irp->RequestorMode == KernelMode)
        {
            goto SkipHandle;    
        }

        if (FileBothDirectoryInformation !=irpSp->Parameters.QueryDirectory.FileInformationClass )
        {      
            goto SkipHandle;
        }

        //设置完成回调函数
        KeInitializeEvent(&waitEvent, NotificationEvent, FALSE);
        IoCopyCurrentIrpStackLocationToNext(Irp);
        IoSetCompletionRoutine(    
                            Irp,
                            DirControlCompletion,        //CompletionRoutine
                            &waitEvent,                    //context parameter
                            TRUE,
                            TRUE,
                            TRUE
                            );
            
        status = IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp );

        if (STATUS_PENDING == status)
        {
            //等待完成
            status = KeWaitForSingleObject(&waitEvent,
                                        Executive,
                                        KernelMode,
                                        FALSE,
                                        NULL
                                        );
            ASSERT(STATUS_SUCCESS == status);
        }

        if (!NT_SUCCESS(status) ||(0 == irpSp->Parameters.QueryFile.Length))
        {    
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            return status;
        }
        
        if(pFileObject&&pFileObject->DeviceObject!=NULL)    
        {            
            status=IoVolumeDeviceToDosName(pFileObject->DeviceObject, &uDosName);  //XP and later    
            if(NT_SUCCESS(status))
            {                    
                RtlInitEmptyUnicodeString(&uFileFullPath,szFilePath,sizeof(szFilePath));
                RtlCopyUnicodeString(&uFileFullPath,&uDosName);
                if(NT_SUCCESS(Irp->IoStatus.Status))
                {                
                    RtlAppendUnicodeStringToString(&uFileFullPath,&(pFileObject->FileName));
                }
            }
        }
 
        KdPrint(("Query Directory :%wZ\n",&uFileFullPath));
        HandleDirectory(Irp->UserBuffer,  &((PQUERY_DIRECTORY)&irpSp->Parameters)->Length);
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return status;

SkipHandle:
    return SfPassThrough(DeviceObject,Irp);
    }

我在调试的过程中发现一个很奇怪的问题,
如果要隐藏的文件或文件夹不含有中文名,那么可以顺利隐藏,
但当要隐藏文件或是文件夹名称中包含中文名称的时候,却不能隐藏
而用windbg 调试的时候,发现FILE_BOTH_DIR_INFORMATION,结构中的FileNameLength 的值正确
但是其中的NextEntryOffset;的值,却始终为0,这也导致了这个条语句:
         RtlMoveMemory(currentDirInfo, (PUCHAR)currentDirInfo + offset, *lpBufLenth - position - offset);
的执行,不起任何作用,相当于没有任何移动,所有不能达到隐藏的效果,
请问达人指点,怎样才能解决这个问题呢,我苦苦思索良久都没有头绪啊?
或是还有其他方法能隐藏含中文名的文件或是文件夹吗?
谢谢了!


fancylf
驱动牛犊
驱动牛犊
  • 注册日期2007-07-29
  • 最后登录2016-06-21
  • 粉丝1
  • 关注0
  • 积分61分
  • 威望501点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2008-10-23 19:58
没人理我啊
555555555555.。。。。。
自己UP一下!
fancylf
驱动牛犊
驱动牛犊
  • 注册日期2007-07-29
  • 最后登录2016-06-21
  • 粉丝1
  • 关注0
  • 积分61分
  • 威望501点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分0分
  • 社区居民
板凳#
发布于:2008-10-23 22:42
自己把问题解决了,但是为什么会出现上面的问题呢?
还请大牛们给点提示!
D-Numen
驱动牛犊
驱动牛犊
  • 注册日期2010-01-25
  • 最后登录2010-08-30
  • 粉丝0
  • 关注0
  • 积分12分
  • 威望121点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2010-02-18 17:24
你好··你是怎么解决的呢··
D-Numen
驱动牛犊
驱动牛犊
  • 注册日期2010-01-25
  • 最后登录2010-08-30
  • 粉丝0
  • 关注0
  • 积分12分
  • 威望121点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2010-02-18 17:27
我是这样实现的
                if (offset==0)
                {
                    RtlZeroMemory(currentDirInfo,(SIZE_T)(sizeof(FILE_BOTH_DIR_INFORMATION)+currentDirInfo->FileNameLength-sizeof(WCHAR)));
                }
                else
                {
                    RtlMoveMemory(currentDirInfo, (PUCHAR)currentDirInfo + offset, *lpBufLenth - position - offset);
                }
D-Numen
驱动牛犊
驱动牛犊
  • 注册日期2010-01-25
  • 最后登录2010-08-30
  • 粉丝0
  • 关注0
  • 积分12分
  • 威望121点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2010-02-18 17:29
实现的结果是:文件夹变了别的文件格式,大小为0,但是还是存在··不能隐藏··请问你是怎么实现的呢··能否赐教一下··
游客

返回顶部