Windows平台内核级文件采访在windows平台下,应用程序一般来说用于API函数来展开文件采访,创立,关上,读取文件。从kernel32的CreateFile/ReadFile/WriteFile函数,到本地系统服务,再行到FileSystem及其FilterDriver,经历了很多层次。在每个层次上,都不存在着安全性防水软件,病毒或者后门不作监控或者过滤器的机会。
作为安全性产品开发者,我们必须比别人回头得很远,因此我们必须一个底层的“windows平台内核级文件采访”的方法来保证我们需要看见准确的整洁的文件系统。1/7必要采访FSD的内核级别文件采访FSD(FileSystemDriver)层是文件API函数经过本地系统服务层(nativeAPI)最后抵达的驱动层次。如果我们可以仿效操作系统,在我们自己的驱动程序里必要向FSD发送到IRP,就可以跨过那些nativeAPI和win32API了,也就可以跨过设置在这些层次上面的API钩子等监控措施。
文件的Create和Open文件的Create和Open可以通过发送到IRP_MJ_CREATE给FSD,或者调用IoCreateFile函数来已完成。Create和Open的区别实质上在于IoCreateFile/IRP_MJ_CREATE的一个参数Disposition的给定。通过发送到IRP_MJ_CREATE给FSD的方法与此类似于,可以参照IFSDDKdocument的IRP_MJ_CREATE解释。
不同于上面方法的是必须自己创立一个FILE_OBJECT,好于上面方法的是这种方法不必须一个HANDLE,HANDLE是线程倚赖的,FileObject则是线程牵涉到。2/7文件的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了。3/7接着要考虑到如果IRP无法及时已完成,不会异步的回到的情况,我们加装一个CompletionRoutine,在CompletionRoutine里面设置一个事件为已转录,通报我们的主线程加载或者载入操作者早已已完成。
现在可以发送到IRP了。如果不采行类似的措施的话,IRP发送到目标是FileObject对应的DeviceObject。发送到后,等候IRP的已完成并且获释资源,回到。
文件的DeleteDelete实质上是通过向FSD发送到IRP_MJ_SET_INFORMATION的IRP,并把IrpSp-Parameters.SetFile.FileInformationClass设置为FileDispositionInformation,用一个FILE_DISPOSITION_INFORMATION结构填满buffer来继续执行的。4/7文件的Rename类似于Delete,Rename是向FSD发送到IRP_MJ_SET_INFORMATION的IRP,把IrpSp-Parameters.SetFile.FileInformationClass设置为FileRenameInformation,填满buffer为FILE_RENAME_INFORMATION结构。综上,于是我们可以在驱动里面通过发送到IRP来必要采访文件系统了,跨过了nativeAPI和win32API层次。跨过文件系统过滤器驱动和钩子有了以上的内容,我们目前可以必要给FSD发送到催促操作者文件。
但是这还过于,因为有很多的杀毒软件或者监控工具用于FSDFilterDriver或者FSDHook的办法来监控文件操作者5/7对付文件系统过滤器驱动文件系统过滤器驱动Attach在长时间的文件系统之上,监控和过滤器我们的文件采访。文件系统驱动栈就是由这一连串的Attach一起的过滤器驱动构成。我们可以用IoGetRelatedDeviceObject这个函数来取得一个FileObject对应的最底层的那个功能驱动对象(FDO)。但是这样虽然跨过了那些过滤器驱动,却同时也跨过了长时间的FSD如Ntfs/Fastfat,因为长时间的FSD也是作为一个过滤器驱动不存在的。
磁盘文件对象的对应的最底层的FDO是Ftdisk.sys,它早已因为过分底层而无法处置我们投递的IRP催促。只不过长时间的FSD信息存储在一个Vpb结构中,我们可以用于IoGetBaseFileSystemDeviceObject这个未公开的内核函数来获得它。它就是我们发送到IRP的目标了。
6/7对付更换DispatchRoutine的FSDHook这是一种常用的FSDHook方式。我们必须获得原本的DispatchRoutine,向原本的DispatchRoutine发送到我们的IRP。这里获取一个思路:我们可以加载原本FSD驱动的.INIT段或者.TEXT段,查询其DriverEntry函数,在它的DriverEntry函数中认同设置了自己的DriverObject的各个DispatchRoutine。
在这个函数中我们就能寻找我们想的DispatchRoutine的地址。只必须用于特征码搜寻的方法就可以搜寻到这个值。
对付InlineHookDispatchRoutine函数本身的FSDHook这种Hook方法较为阴险,但不是十分多见于安全性产品中,一般应用于在木马和rootkit上,比如我自己写出的rootkit。它没变更DriverObject里面的DispatchRoutine的函数指针,而是向函数结尾载入编撰指令的JMP来函数调用函数。对付它的基本思路就是加载不存在磁盘上的FSD的文件,读取到内存一份整洁的备份,查看我们要调用的DispatchRoutine结尾的几个字节和这个整洁备份否完全一致。
7/7如果不完全一致,特别是在是不存在JMP,RET,INT3一类的编撰指令的时候,很有可能就是不存在了InlineHook。(但要充分考虑重定位的情况。
)如果不存在InlineHook,我们就把整洁的函数结尾拷贝过来覆盖面积丢弃被病毒感染的函数头。然后在发送到IRP,就会被InlineHook监控或伪造了。
怎么样?看完了后你有什么点子?对!就是用这种方法来突破主动防御类软件,现在主动防御早已是未来杀死硬的一个发展趋势了,而想要突破主动防御,必需要有坚实的编程功底,以后的免杀(指主动防御)再也不是菜鸟所能制作的了,所以各位知道想玩免杀死的话,以后编程就是必不可缺了!。
本文来源:沙巴官方-www.tushangjia.com