文件重定向(hook IRP_MJ_CREATE)

本文介绍如何通过Windows I/O管理器实现文件对象的重定向,包括修改文件名、设置状态码等步骤,并提供了具体的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Windows的I/O管理器提供了一个方便的方法来重定向一个文件对象。通常使用文件过滤驱动(在文件打开和文件创建的操作中)实现该方法。操作方法如下:


1、在IRP_MJ_CREATE的分发函数中,获得FILE_OBJET的FileName属性。
2、用目标文件的完整路径替换原有的文件名字。这个全名,包括卷设备对象的名字(例如,Device/HardDiskVolume0/Directory/MyFile.txt)。可以释放掉原有的FileName.Buffer,同时用自己定义的缓冲区(buffer,以NonPagedPool方式申请)替换它。
3、设置IoStatus的status字段为STATUS_REPARSE,然后设置Information字段为IO_REPARSE.
4、完成该IRP请求。

5、返回STATUS_REPARSE


I/O管理器接收到该返回后,便会触发另一个文件打开操作,并发送一个IRP_MJ_CREATE的请求。
‍而目标文件可以是本地或远程计算机。而若要重定向远程文件打开操作,文件名要遵循以下语法:
"/??/UNC/HostName/Share/File" 或 "/Device/Mup/HostName/Share/File" 或
"/Device/LanmanagerRedirector/HostName/Share/File"(在你的目标文件是CIFS/SMB/LanManager的情况下)
在你的首次打开/创建文件操作是相对于另一个文件对象的时候,没有必有修改FILE_OBJECT的RelatedFileObject域。在重定向时,I/O管理器只考虑FileName域,而不考虑RelatedFileObject域(在I/O管理器收到STATUS_REPARSE后,它便会释放该域)。
I/O管理器为了避免重定向的无限循环,在嵌套循环中加了一些限制:重定向操作的最大嵌套次数是32.
//在IRP_MJ_CREATE例程里添加如下代码:

irpSp = IoGetCurrentIrpStackLocation(Irp);
RtlInitUnicodeString(&cmpFileName, L"//hello.txt");
KdPrint((">>> Create/Open FileName:%ws/n", irpSp->FileObject->FileName.Buffer));

if (RtlCompareUnicodeString(&cmpFileName, &irpSp->FileObject->FileName, FALSE) == 0)
{
	pusFileName = &(irpSp->FileObject->FileName);

	/*方法很简单
	就是把FileObject->FileName.Buffer释放掉
	然后自己ExAllocatePool...分配一个缓冲区用于保存重定向的文件名 这里需要是全文件名
	FileObject->FileName指向新分配的缓冲区
	把新文件名拷贝到FileObject->FileName里
	设置Irp->IoStatus的值如下
	Irp->IoStatus.Status = STATUS_REPARSE;
	Irp->IoStatus.Information = IO_REPARSE;
	返回STATUS_REPARSE
	经测试跨卷访问也可以*/

	RtlInitUnicodeString(&usNewFileName, L"//??//E://123//hello.txt");

	pwNewNameBuffer = ExAllocatePool(PagedPool, usNewFileName.MaximumLength);

	if (pwNewNameBuffer == NULL)
	{
		Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
		Irp->IoStatus.Information = 0;
		IoCompleteRequest( Irp, IO_NO_INCREMENT );
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	ExFreePool( pusFileName->Buffer );
	pusFileName->Buffer = pwNewNameBuffer;
	pusFileName->MaximumLength = usNewFileName.MaximumLength;
	RtlCopyUnicodeString(pusFileName, &usNewFileName);

	Irp->IoStatus.Status = STATUS_REPARSE;
	Irp->IoStatus.Information = IO_REPARSE;
	IoCompleteRequest( Irp, IO_NO_INCREMENT );

	return STATUS_REPARSE;
}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值