天下网吧 >> 网吧天地 >> 网吧技术 >> 网吧软件 >> 正文

Windows平台内核级文件访问

2010-9-21不详佚名

背景

在windows平台下,应用程序通常使用API函数来进行文件访问,创建,打开,读写文件。从kernel32的 CreateFile/ReadFile/WriteFile函数,到本地系统服务,再到FileSystem及其FilterDriver,经历了很多 层次。在每个层次上,都存在着安全防护软件,病毒或者后门作监视或者过滤的机会。作为安全产品开发者,我们需要比别人走得更远,因此我们需要一个底层的“windows平台内核级文件访问”的方法来确保我们能够看到正确的干净的文件系统。

直接访问FSD的内核级别文件访问

FSD(FileSystemDriver)层是文件API函数经过本地系统服务层(native API)最后到达的驱动层次。如果我们可以模仿操作系统,在我们自己的驱动程序里直接向FSD发送IRP,就可以绕过那些native API 和win32 API了,也就可以绕过设置在这些层次上面的API钩子等监控措施。

文件的Create和Open

文件的Create和Open可以通过发送IRP_MJ_CREATE给FSD,或者调用IoCreateFile函数来完成。Create和Open的区别实际上在于IoCreateFile/IRP_MJ_CREATE的一个参数Disposition的取值。

通过发送IRP_MJ_CREATE给FSD的方法与此类似,可以参考IFSDDK document的IRP_MJ_CREATE说明。不同于上面方法的是需要自己创建一个FILE_OBJECT,好于上面方法的是这种方法不需要一个 HANDLE,HANDLE是线程依赖的,FileObject则是线程无关。

文件的Read和Write

我们通过给FSD发送IRP_MJ_READ来读取文件,给FSD发送IRP_MJ_WRITE来改写文件。

如果我们是通过一个HANDLE来执行(如使用IoCreateFile打开的文件),就要先用ObReferenceObjectByHandle函数来获得这个Handle对应的FileObject。我们只能给FileObject发送IRP。

之后我们使用IoAllocateIrp分配一个IRP。根据FileObject->DeviceObject->Flags的值,我们判断目标文件系统使用什么样的IO方式。

对每种不同的IO方式使用不同的地址传递方式。随后我们填充IRP内的各个参数域,就可以发送IRP了。

接着要考虑如果IRP不能及时完成,会异步的返回的情况,我们安装一个CompletionRoutine,在CompletionRoutine里面设置一个事件为已激活,通知我们的主线程读取或者写入操作已经完成。

现在可以发送IRP了。如果不采取特殊的措施的话,IRP发送目标是FileObject对应的DeviceObject。发送后,等待IRP的完成并且释放资源,返回。

文件的Delete

Delete实际上是通过向FSD发送IRP_MJ_SET_INFORMATION的IRP,并把 IrpSp->Parameters.SetFile.FileInformationClass设置为 FileDispositionInformation,用一个FILE_DISPOSITION_INFORMATION结构填充buffer来执行 的。

文件的Rename

类似于Delete,Rename是向FSD发送IRP_MJ_SET_INFORMATION的IRP,把 IrpSp->Parameters.SetFile.FileInformationClass设置为 FileRenameInformation,填充buffer为FILE_RENAME_INFORMATION结构。

综上,于是我们可以在驱动里面通过发送IRP来直接访问文件系统了,绕过了native API 和win32 API层次。

绕过文件系统过滤驱动和钩子

有了以上的内容,我们目前可以直接给FSD发送请求操作文件。但是这还不够,因为有很多的杀毒软件或者监视工具使用FSD Filter Driver或者FSD Hook的办法来监控文件操作

对付文件系统过滤驱动

文件系统过滤驱动Attach在正常的文件系统之上,监视和过滤我们的文件访问。文件系统驱动栈就是由这一连串的Attach起来的过滤驱动组 成。我们可以用IoGetRelatedDeviceObject这个函数来获得一个FileObject对应的最底层的那个功能驱动对象(FDO)。但 是这样虽然绕过了那些过滤驱动,却同时也绕过了正常的FSD如Ntfs/Fastfat,因为正常的FSD也是作为一个过滤驱动存在的。磁盘文件对象的对 应的最底层的FDO是Ftdisk.sys,它已经因为过于底层而不能处理我们投递的IRP请求。

其实正常的FSD信息存储在一个Vpb结构中,我们可以使用IoGetBaseFileSystemDeviceObject这个未公开的内核函数来得到它。它就是我们发送IRP的目标了。

对付替换DispatchRoutine的FSD Hook

这是一种常用的FSD Hook方式。我们需要得到原本的DispatchRoutine,向原本的DispatchRoutine发送我们的IRP。这里提供一个思路:我们可 以读取原本FSD驱动的.INIT段或者.TEXT段,查找其DriverEntry函数,在它的DriverEntry函数中肯定设置了自己的 DriverObject的各个DispatchRoutine。在这个函数中我们就能找到我们想要的DispatchRoutine的地址。只需要使用 特征码搜索的方法就可以搜索到这个值。

对付Inline Hook DispatchRoutine函数本身的FSD Hook

这种Hook方法比较狠毒,但不是非常常见于安全产品中,一般应用在木马和rootkit上,比如我自己写的rootkit。它没有更改 DriverObject里面的DispatchRoutine的函数指针,而是向函数开头写入汇编指令的JMP来跳转函数。对付它的基本思路就是读取存 在磁盘上的FSD的文件,加载到内存一份干净的备份,察看我们要调用的DispatchRoutine开头的几个字节和这个干净备份是否一致。如果不一 致,尤其是存在JMP,RET,INT3一类的汇编指令的时候,很可能就是存在了Inline Hook。(但要充分考虑重定位的情况。)如果存在Inline Hook,我们就把干净的函数开头拷贝过来覆盖掉被感染的函数头。然后在发送IRP,就不会被Inline Hook监视或篡改了。

怎么样?看完了后你有什么想法?对!就是 用这种方法来突破主动防御类软件,现在主动防御已经是未来杀软的一个发展趋势了,而想突破主动防御,必须要有扎实的编程功底,以后的免杀(指主动防御)再 也不是菜鸟所能制作的了,所以各位真的想玩免杀的话,以后编程就是必不可缺了!

本文来源:不详 作者:佚名

声明
声明:本站所发表的文章、评论及图片仅代表作者本人观点,与本站立场无关。文章是出于传递更多信息之目的。若有来源标注错误或侵犯了您的合法权益,请作者持权属证明与本网联系,我们将及时更正、删除,谢谢。 Email:support@txwb.com,系统开号,技术支持,服务联系微信:_WX_1_本站所有有注明来源为天下网吧或天下网吧论坛的原创作品,各位转载时请注明来源链接!
天下网吧·网吧天下
  • 本周热门
  • 本月热门
  • 阅读排行