首页
社区
课程
招聘
[求助]文件过滤驱动查询盘符问题。(Dynamic disk)
发表于: 2011-8-20 12:49 9431

[求助]文件过滤驱动查询盘符问题。(Dynamic disk)

2011-8-20 12:49
9431
在IRP_MJ_CREATE里面要查询文件的盘符,
之前用IoDeviceToDosVolume,不过这个函数在遇到挂载新盘符的时候会导致系统挂起。
后来改为用ObQueryNameString查到Device的 \Device\HarddiskDmVolumes\...
路径,然后再枚举 A: - Z: 符号链接,与之进行字符串比较,获取盘符。

现在遇到一个问题,如果一个卷标属于动态磁盘的话,例如K:
查询ObQueryNameString返回的是
\Device\HarddiskDmVolumes\PhysicalDmVolumes\BlockVolume1
在winobj里面看,这是一个设备。

但是用ZwQuerySymbolicLinkObject得到的却是
\Device\HarddiskDmVolumes\Workgrou-l87olxDg0\Volume1
在winobj里面看,这是一个指向\Device\HarddiskDmVolumes\PhysicalDmVolumes\BlockVolume1的符号链接。

我要怎么做才能查到这个盘符?是要对这个查询到的符号链接再递归的查询?还是说有其他办法更好一点的?

[课程]FART 脱壳王!加量不加价!FART作者讲授!

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 8865
活跃值: (2379)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
2
根据传说是这么处理的~~
//////////////////////////////////////////////////////////////////////////
//
// ConvertDeviceName
//
// 将形如 "\\Device\\HarddiskVolumeX\\xxxx的内核文件路径
// 转化为 DOS文件路径(c:\\xxxx\\xxx....)
//
//////////////////////////////////////////////////////////////////////////
NTSTATUS ConvertDeviceName(LPCWSTR FileName , LPCWSTR OutFileName)
{
	HANDLE	FileHandle ; 
	OBJECT_ATTRIBUTES oba; 
	IO_STATUS_BLOCK iosb ; 
	UNICODE_STRING uniname; 
	NTSTATUS	stat ; 
	PFILE_OBJECT FileObject ; 


	RtlInitUnicodeString(&uniname , FileName);

	InitializeObjectAttributes(&oba , &uniname , OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE , 0 , 0 );


	stat = IoCreateFile(&FileHandle , 
		FILE_READ_ATTRIBUTES , 
		&oba,
		&iosb , 
		0,
		FILE_ATTRIBUTE_NORMAL , 
		FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE ,
		FILE_OPEN,
		FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT  , 
		0 ,
		0,
		CreateFileTypeNone , 
		0,
		IO_NO_PARAMETER_CHECKING
		);

	if (!NT_SUCCESS(stat))
	{
		return stat ; 
	}
	
	stat = ObReferenceObjectByHandle(FileHandle , 
		GENERIC_READ , 
		*IoFileObjectType , 
		KernelMode , 
		&FileObject , 
		NULL);

	if (!NT_SUCCESS(stat) ||
		!FileObject ||
		!FileObject->FileName.Length ||
		!FileObject->FileName.Buffer)
	{
		ZwClose(FileHandle);
		return STATUS_INVALID_PARAMETER ; 
	}
	//开始获取DosName

	{
		UNICODE_STRING VolumeName ; 
		UNICODE_STRING FanalName ; 
		BOOL	WillFreeVolumeName = TRUE ; 


		VolumeName.Buffer = NULL ;
		VolumeName.Length = 0 ; 
		VolumeName.MaximumLength = 0 ; 
		

		stat = RtlVolumeDeviceToDosName(FileObject->DeviceObject , &VolumeName);

		if (!NT_SUCCESS(stat))
		{
			RtlInitUnicodeString(&VolumeName , L"\\" );
			WillFreeVolumeName = FALSE ; 
		}
		if (FileObject->FileName.Length + VolumeName.Length >= 0x800 * 2)
		{
			ObDereferenceObject(FileObject);
			ZwClose(FileHandle);
			if (WillFreeVolumeName && MmIsAddressValid(VolumeName.Buffer))
			{
				ExFreePool(VolumeName.Buffer);
			}
			return STATUS_INVALID_PARAMETER ; 
		}

		RtlZeroMemory((PVOID)OutFileName , 0x800 * 2);

		RtlInitUnicodeString(&FanalName , OutFileName);

		FanalName.MaximumLength = 0x800 * 2 ;
		
		//byte 

		if (!NT_SUCCESS(RtlAppendUnicodeStringToString(&FanalName , &VolumeName)))
		{
			ObDereferenceObject(FileObject);
			ZwClose(FileHandle);
			if (WillFreeVolumeName && MmIsAddressValid(VolumeName.Buffer))
			{
				ExFreePool(VolumeName.Buffer);
			}
			return STATUS_INVALID_PARAMETER ;			
		}

		if (!NT_SUCCESS(RtlAppendUnicodeStringToString(&FanalName , &FileObject->FileName)))
		{
			ObDereferenceObject(FileObject);
			ZwClose(FileHandle);
			if (WillFreeVolumeName && MmIsAddressValid(VolumeName.Buffer))
			{
				ExFreePool(VolumeName.Buffer);
			}
			return STATUS_INVALID_PARAMETER ;
		}
		
		ObDereferenceObject(FileObject);
		ZwClose(FileHandle);
		if (WillFreeVolumeName && MmIsAddressValid(VolumeName.Buffer))
		{
			ExFreePool(VolumeName.Buffer);
		}

		return STATUS_SUCCESS ; 
	

		

	}

}

2011-8-20 16:35
0
雪    币: 1149
活跃值: (833)
能力值: ( LV13,RANK:260 )
在线值:
发帖
回帖
粉丝
3
感觉你既然是动态挂载新盘符的时候出现 系统挂起,
也就是说你的挂载盘符是手动的时候,这个时候还不如设置 context 上下文,也就是扩展device 这样在create 取出对应的盘符 就可以.....

上面的那两个盘符 IoVolumeDeviceToDosName  RtlVolumeDeviceToDosName 动态挂载盘符,都有可能 出现问题,如果是 之前已挂载的可能不会出问题...

一家之言....个人想法....
2011-8-20 17:03
0
雪    币: 259
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
感谢v神~~~

意思是在IRP_MJ_CREATE传递到下层之前,先自己打开一遍这个文件然后用IoVolumeDeviceToDosName 查盘符吗?

嗯,如果是这样就要处理IRP重入问题。。可以根据那个flag pass掉吧。。

不过,还是用RtlVolumeDeviceToDosName /IoVolumeDeviceToDosName 这个函数的话,虽然和之前调用的时机是不同了(一个打开文件前,一个打开文件后),但不知道还会不会触发系统挂起的问题?

我这个问题老外说要用MountPointManager??
http://www.osronline.com/showThread.cfm?link=23125

关于IoVolumeDeviceToDosName系统挂起的问题-
http://www.osronline.com/showThread.CFM?link=96556
2011-8-20 18:02
0
雪    币: 259
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
在插入u盘得时候。调用这函数就会出问题。。
意思是加载驱动的时候先记录已经挂载的卷标到context的表里,然后在新挂卷标的时候update这个表?
2011-8-20 18:04
0
雪    币: 1149
活跃值: (833)
能力值: ( LV13,RANK:260 )
在线值:
发帖
回帖
粉丝
6
如果你用 的是minifilter的话,直接开辟context 上下文,设置 name 即可
如果你用sfilter 模型 那就放在扩展 对象里 就可
在create 里  无论是前处理 还是后处理,就不存在重入的问题...直接取出 使用
2011-8-20 18:07
0
雪    币: 259
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
用的是sfilter模型
是不是在SfFsNotification里面获取这个新MOUNT的卷标的盘符?
2011-8-20 20:27
0
雪    币: 1149
活跃值: (833)
能力值: ( LV13,RANK:260 )
在线值:
发帖
回帖
粉丝
8
做一下不就全知道了....
做比知道更重要  哈哈
2011-8-20 20:40
0
雪    币: 259
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
恩。正在做。。。。希望一切顺利
2011-8-20 21:35
0
游客
登录 | 注册 方可回帖
返回
//