阅读:3382回复:5
调试IRP_MJ_DIRECTORY_CONTROL 发现的一个奇怪的问题
首先谢谢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); 的执行,不起任何作用,相当于没有任何移动,所有不能达到隐藏的效果, 请问达人指点,怎样才能解决这个问题呢,我苦苦思索良久都没有头绪啊? 或是还有其他方法能隐藏含中文名的文件或是文件夹吗? 谢谢了! |
|
沙发#
发布于:2008-10-23 19:58
没人理我啊
555555555555.。。。。。 自己UP一下! |
|
板凳#
发布于:2008-10-23 22:42
自己把问题解决了,但是为什么会出现上面的问题呢?
还请大牛们给点提示! |
|
地板#
发布于:2010-02-18 17:24
你好··你是怎么解决的呢··
|
|
地下室#
发布于: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); } |
|
5楼#
发布于:2010-02-18 17:29
实现的结果是:文件夹变了别的文件格式,大小为0,但是还是存在··不能隐藏··请问你是怎么实现的呢··能否赐教一下··
|
|