【原创】内核驱动文件重定向 加图加代码

  作 者: defddr
时 间: 2010-11-10,00:02:38
链 接: http://bbs.pediy.com/showthread.php?t=124524

最近学习了下内核驱动中的文件重定向。现在总结一下,希望对大家有用

不知道在逆向论坛发表文件过滤驱动是一个错误?  我承认这些是很基础的东西 但是不能发表工作成果的我发表一些试验程序的副产品也是为了和大家分享

那个啥啥Miminka (Mummy) 巨婴们攀爬的是Žižkov的电视塔曾经被评选为最丑陋的建筑物 不也被当地的群众以艺术的宽容接受了么

拜托大家宽容的对待这些  大不了一笑而过吧  当然 管理员能给个精华最好了 谢谢

最近几天将附加上MINIFILTER重定位代码(已加) 以及附上完整的将指定文件重定位到内存中的实验代码
额  其实不是想吸引眼光 所以强调下只是实验代码



重定向,字面即为对某A文件的操作直接转移到B文件。比如读、写 、设置长度或文件结尾指针等属性、甚至是删除操作。
内核驱动中文件重定向主要用于加解密.打开密文文件时将其复制到一个隐藏的临时文件,并解密后打开,保存时将临时文件加密后覆盖原文件。
或者打开文件等对象重定向,用于系统还原,以及使用重定向技术将应用程序数据与操作系统数据分离存储来达到保护系统的作用



以下是基于  SFILTER框架的 文件重定向
相对MINIFILTER框架 SFILTER看起来比较复杂 但是他可以跨分区跨卷进行文件重定向

无论我们查询设置文件属性 读写 删除文件等 均是通过打开文件来开始的 而在内核中打开文件便是创建--Create
我们进行路径替换来重定位也是从这里开始
代码:
PDEVICE_EXTENSION deviceExtension; 
PDEVICE_OBJECT attachedDevice; 


///
//获得当前IRP堆栈 里面包含读写IRP的重要内容 
//诸如要读写的文件对象 读写的偏移 长度
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp); 
NTSTATUS status; 
PFILE_OBJECT FileObject = irpSp->FileObject; 
LARGE_INTEGER offset = irpSp->Parameters.Read.ByteOffset; 
ULONG length = irpSp->Parameters.Read.Length; 


WCHAR nameBuf[512]; 
UNICODE_STRING name; 
UNICODE_STRING sourceName; 
UNICODE_STRING destinationName; 

//以下IF代码检验驱动对象
if(!(DeviceObject->DriverObject==FsDriverObject)) 
{ 
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; 
Irp->IoStatus.Information = 0; 
status = Irp->IoStatus.Status; 
IoCompleteRequest(Irp, IO_NO_INCREMENT); 
return status; 
} 


deviceExtension = DeviceObject->DeviceExtension; 
attachedDevice = deviceExtension->FileSystemDeviceObject; 

if(deviceExtension->RealDeviceObject==NULL) 
{ 
IoSkipCurrentIrpStackLocation(Irp); 
return IoCallDriver(attachedDevice,Irp); 
} 


//
//以下开始准备开始构造重定向路径
RtlInitUnicodeString( &sourceName, L"\\\\globaluser.txt" ); 

RtlInitEmptyUnicodeString(&name,nameBuf,512); 
//检验IRP中文件对象文件名是否是我们需要重定向文件  当然 文件对象肯定也要检验下 不能为空
if (FileObject&&RtlCompareUnicodeString( &sourceName, &FileObject->FileName, TRUE ) == 0) 
{ 

RtlCopyUnicodeString(&name,&FileObject->FileName); 

DbgPrint("File Name: %ws",(&name)->Buffer); 

ExFreePool(FileObject->FileName.Buffer); 
FileObject->FileName.Length = 0; 
FileObject->FileName.MaximumLength = name.MaximumLength; 
FileObject->FileName.Buffer=(PWCHAR)ExAllocatePool(NonPagedPool, name.MaximumLength); 

RtlInitUnicodeString( &destinationName, L"\\\\??\\\\G:\\user\\globaluser.txt" ); 
RtlCopyUnicodeString(&FileObject->FileName, &destinationName); 

FileObject->FileName.Buffer[FileObject->FileName.Length/2] = UNICODE_NULL; 
//将文件对象的文件名替换为我们自己需要的路径名 其实主要要注意BUFFER的释放创建替换问题
//替换完毕后  状态返回REPARSE 重解析 直接完成IRP请求
Irp->IoStatus.Status = STATUS_REPARSE; 
Irp->IoStatus.Information = IO_REPARSE; 
IoCompleteRequest( Irp, IO_NO_INCREMENT ); 


return STATUS_REPARSE; 

} 
else 
{ 
IoSkipCurrentIrpStackLocation(Irp); 
return IoCallDriver(attachedDevice,Irp); 
} 

///
同样MINIFILTER也是从CREATE开始入手进行重定位的
代码相对来说是简单很多
但是不是简单的替换路径名 返回reparse那么简单了
根据我掌握的信息似乎不能跨分区跨卷进行重定位 
代码:
FileName = &(FileObject->FileName); //得到文件名
FileNameBuffer = ExAllocatePool( NonPagedPool,NewFileName.MaximumLength ); //分配一个UNICODE 准备路径替换
if (!FileNameBuffer) //处理分配不成功情况
{ 
// Not enough resources. Complete the IRP with the appropriate status. 
Data->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; 
Data->IoStatus.Information = 0; 
return FLT_PREOP_SUCCESS_WITH_CALLBACK; 
} 
ExFreePool( FileName->Buffer );// 释放原来文件名BUFFER
FileName->Buffer = FileNameBuffer; //替换
FileName->MaximumLength = NewFileName.MaximumLength; 
RtlCopyUnicodeString( FileName, &NewFileName ); 
FltSetCallbackDataDirty(Data); //操作中改变数据 需要调用此函数设置数据为dirty提醒系统进行数据更新

用MINIFILTER框架Passthrough写了个重定位的测试程序
见附件  MINIFILTER运行方法是 进入passThrough\objchk_wxp_x86\i386目录中右键点击INF文件选择安装  此后打开DOS窗口(CMD命令)输入"net start passthrough  "
看到"passthrough运行成功即可"

此后保证C盘下有test文件夹及test.txt即可  

驱动作用为将c:\test\test.txt定位到c:\test\testBack.txt
testBack.txt变为30K 但是test还是没有变化
此时读取 写入 等操作看到的也均是testBack.txt
重启后 读取test文件将发现还是原来的内容
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值