首页 > 编程知识 正文

坑徒日记41,三坑日记下载

时间:2023-05-06 02:14:51 阅读:167093 作者:507

背景:

最近,某个项目需要IRP操作文件。 在那里,搜索硬盘,找到多年前的代码。 说到这个代码,需要感谢黑月教主achillis和火炉。 当时火炉把PsVoid开源了。

包含Irp操作文件。 但是,将其抄写后,win7蓝屏。 当时的水平太菜了。 在q必须得到教主的帮助。 教主帮助分析后,在网上。 那个经典的ULONG

UnKnow[41] .然后各博客转载…当然。 当时我自己也还存了一点,后来没用就扔在硬盘里了…直到这次使用…

过程:

代码的大致逻辑是: [与PS void相似]。 其实我在网上随便找IRP操作文件的投稿和源代码。 哪个都一样。

satus=IRPcreatefile(filepath,FILE_READ_ATTRIBUTES,FILE_ATTRIBUTE_NORMAL, file _ share _ read|file _ no _ intermediate _ buffering|file _ non _ directory _ file|file status=IRP readfile (文件对象,x,x……); 最后

IRP close (文件对象; 我简单地实验了一下,没有任何明显的错误。 因此,我们将准备windbg双机调试并进行一次,然后交付测试。 调试去的时候,我很好奇。 在IrpCreateFile之后! object FileObject .尝试了引用计数。

然后IRP close (文件对象)结束后再见! object FileObject .看起来…没有…Name。 但是,引用数量仍然是1。

这是典型的客体泄露啊……突然打起了精神。 这个代码几年前就有漏洞了吗? 当时没有在意…因为对象引用计数不平衡,所以想手动减少吧。

对象(文件对象;

悲惨的蓝屏生活拉开了帷幕。 [中途怀疑自己的代码写得有问题。 直接将PsVoid的源代码写入对象(file object ); 蓝屏的. ]

添加这一行后.在windowsXP SP3上测试时有时会出现蓝屏.但不是必然的.后来找到了必然的方法.下面是蓝屏时的堆栈.这两个堆栈交替出现.

或者

突然发呆了呢。 我追加了这一行。 存在NtFs如何制作CCB的问题…经过几次测试,确认必然可以在蓝屏上再现后…看来是制作CCB,或者从FCB中抓住什么锁带来的蓝屏。 那么,此时文件对象中的哪些成员已禁用呢? 是从FileObject拿了什么进入了蓝屏吗……所以我想带源代码进行调试……

我在找多情的小白菜开源的Ntfs源代码。 编译后进行了调换。 我不知道该怎么办。 接通电源的时候,一张巨大的卡片。 然后用kmd工具加载我的驱动程序的话,就会卡在路驱动程序上不回来……没办法。 已重新安装虚拟机。 虚拟机采用Fat32分区,从WDK7601中找到FastFat源代码(WXP版本),进行编译并更换为Windows。

这次加载驱动程序后,直接在. fastfat内断言了。(实际上已经到了发送IrpClose的Clean Irp的地方。分发后进行了断言。) )。

大致意思是.一个引用计数必须是0。 然后,看我在FCB内的参照计数。 输入“确实是0…”无视。 参照技术减1变为负。 (0xFFFFFFFFF )。

然后.为什么会变成0呢? 寻找引用,看看在那里初始化的东西.或者增加的东西。 遵循方向盘的模具。 打开时增加引用计数1 .关闭并减少1。 应该配对。 在这里推测也是一样的……

然后打开并找到FastFat源代码,查找对此变量的引用。 最后

很明显, file objectflags中只有这个标志位才会被赋予. 1。 我这个文件对象是自己做的。 flags中正好没有这个标志位.那么为什么不呢.系统怎么处理这个标志位.或者在那里初始化.要在WRK中搜索这个宏吗?

最后来到了. IopParseDevice内的以下片段。 很明显。 这在创建文件对象后,应该基于创建选项积极设置。 不在原来的代码内……于是.这个被引出了。 此IRP操作文件中的第一个错误.

[应该根据情况设定不同的Flags。 (实际上WRK考虑得很周到。 在这里,只是简单地解决了我追加的这个无现金读取的标志。 实际上还有其他事情要处理。 ) (文件对象- flags=fo _ synchronous _ io; ]

解决后,继续调试。 最后在FastFat上出现了蓝屏。 [不用说,中途会跟踪Clean进程和Close进程。 纯粹的体力F10]

与调试源代码不同,它直接说明了FatFreeCCB的位置是蓝屏。 此外,迭斯明显指出。 这是obdereferenceobject (文件)

eObject);引发的…
在这里.我走了不少弯路.那就是.分析FatFreeCCB为什么会蓝屏,跟着FastFat绕了好几圈.最后得出结论.蓝屏的时候的这个CCB值是无效的.
那这个CCB是从那来的.怎么就无效了呢…通过代码内查找引用.发现
[ TypeOfOpen = FatDecodeFileObject( FileObject, &Vcb, &Fcb, &Ccb ); 从FileObject的FsContext2取出CCB然后传递给FatCommonClose释放的.]
FatFreeCCB就一句话.

那么FileObject的CCB怎么就无端端的无效了呢… 或者说FileObject->FsContext2.怎么就无效了.于是又跟了一圈.这次对FileObject的
FsContext2下硬断点.看看是怎么回事.最后得到如下堆栈.

看到这.和上边蓝屏的堆栈一结合.顿时明白了.内存重复释放了…而这个重复释放第一次释放是我们自己的代码.IrpClose内.发IRP_贤惠的心情_CLOSE.引发的.
第二次.是ObDereferenceObject(FileObject);引发的…
当时在这个时候.潜意识里一直在想.IrpCreateFile完了就应该IrpClose.是ObDereferenceObject(FileObject)引发了问题…直到我去根据蓝屏堆栈.在WRK找到内IopDeleteFile…彻底明白了… ObDereferenceObject把对象减到0.自动触发对象删除例程.然后在这个例程内.做一些判断…然后就会调用IopCloseFile来发IRP_贤惠的心情_CLEANUP.后回到IopDeleteFile继续发IRP_贤惠的心情_CLOSE…这才是正常流程…
而我们自己发IRP_贤惠的心情_CLEANUP.和IRP_贤惠的心情_CLOSE. 让文件系统提前把相对应的信息释放了.等文件对象销毁的时候再给文件系统发IRP的时候.内存被重复释放.最终引发蓝屏… 脉络清楚之后.解决起来就非常简单了.
一句话.IrpCreateFile之后.不要调用IrpClose.直接一句ObDereferenceObject(FileObject); 搞定…系统自动把CLEANUP和CLOSE全发了.
修改之后,再次测试.Ntfs上也不再蓝屏.Bug解决.

备注:
再说三个BUG.但这三个BUG就不用再细说了.一来.简单.二来网上的IRP操作文件代码也已经解决了.
1.ObCreateObject时候FileObject大小.VISTA以前和以后是不一样的.不过这个不同版本DDK或者WDK的WDM.H头文件内有详细定义照抄即可.
2.创建出来的FileObject内的FileName的Buffer.最好是动态申请的.至于申请出来的Buffer需不需要自己释放.这个可以自由选择.但如果像代码过Verifer的话.
最好.在我上边说的ObDereferenceObject(FileObject);前主动释放掉.[如果不自己释放,IopDeleteFile内也会检测到来释放.]
3.黑月教主当年分析出结构大小需要添加ULONG Unknow[41].但随着操作系统版本升级.win8以后还是相对小了.仍然有几率蓝屏… 最保险起见
ULONG Unknow[100].(当然了.我这里是偷懒了,准确的方法是沿着黑月教主当年的思路分析一下SeCreateAccessState.)

填完以上BUG之后.目前暂时未发现新的蓝屏点.但其中仍然有许多不足.
例如Read Write时候.IRP Flags的设置等.可能也需要参照WRK设置…(猜的.下一步用到再验证.但思路都差不多.)

补充:
IrpCreateFile打开文件后,如果要进行Read.或者Write等.那么IrpCreateFile的时候FILE_NO_INTERMEDIATE_BUFFERING标志需要设置.这样
ObDereferenceObject(FileObject);完才会立即销毁文件对象并发送CLEANUP和CLOSE.否则.Read的时候缓存增加了对象引用计数.会延迟销毁.[这个后续还需要再研究.]

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。