xzjfile
禁止发言
禁止发言
  • 注册日期2001-12-14
  • 最后登录2018-07-12
  • 粉丝0
  • 关注0
  • 积分6970分
  • 威望50721点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
  • 社区居民
阅读:2427回复:15

可怕的IFS重入问题,分页。

楼主#
更多 发布于:2002-11-30 17:30
用户被禁言,该主题自动屏蔽!

最新喜欢:

cyliucyliu
sijun
驱动牛犊
驱动牛犊
  • 注册日期2001-07-31
  • 最后登录2007-06-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-12-02 10:30
问题出在\"用ring0I/O打开另一个文件\",这时你又会收到FS_OpenFile,然后\"用ring0I/O打开另一个文件\",然后。。。。 这样会出现死循环。
处理的办法大概有两个:1。不用ZwCreateFile打开文件而是直接构造IRP往下层传 2。用特别的方法识别FS_OpenFile是由自己的ZwCreateFile产生的,比如传给ZwCreateFile的文件名加入特殊的标志(当然在处理FS_OpenFile时还得改回正常文件名)
创造无限
Coolice
驱动小牛
驱动小牛
  • 注册日期2002-11-13
  • 最后登录2003-08-22
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-12-02 13:09
这个问题当初也一样困扰了我两三个月,我把我的心得写出来和大家共享一下,希望能有用(有用的话别忘了给分:)

先说说sijun提到的两种方法:

1. 直接构造IRP,只适用于2000/XP,这个方法我一直没有成功:(

2. 在CreateFile时加入特殊标志。
通常是在文件名后面跟特殊标记,例如($:MYFILE),缺点是文件名过长时会引起不必要的麻烦,而且该方法会导致和很多防毒软件冲突。另外修改OPENFILE的标志位,比较简单,但是也不可靠(如果大家的驱动都用这个标志...)

3. 创建自己的用户线程或者系统线程来CreateFile,在OpenFile中判断是否是自己的线程(ID)在打开文件,如果是的话,当然直接PASS
(强烈推荐)

4. 在收到FS_OpenFile时,记下当前线程ID,然后打开文件,当第二个FS_OpenFile重入时,发现该线程已被记录,就PASS(简单易行)

方法3、4也不是完美的方法,实际使用时发现也会和某个特定的软件冲突。
在2000下还得考虑CACHE的问题,不能随便PASS有危险的Create

另外在Xp下,微软终于加入了针对FileObject的Context字段,可以有限解决Read/Write可能引起的死锁以及其它经常做Filter碰到的问题,可惜2000和98都没有这个功能。
Coolice
驱动小牛
驱动小牛
  • 注册日期2002-11-13
  • 最后登录2003-08-22
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-12-02 13:16
另外你指的paging是swapperfile吗?如果是的话,在OpenFile里判断有没有R0_SWAPPER_CALL标志,有的话,千万要PASS哦!
xzjfile
禁止发言
禁止发言
  • 注册日期2001-12-14
  • 最后登录2018-07-12
  • 粉丝0
  • 关注0
  • 积分6970分
  • 威望50721点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
  • 社区居民
地下室#
发布于:2002-12-02 14:32
用户被禁言,该主题自动屏蔽!
Coolice
驱动小牛
驱动小牛
  • 注册日期2002-11-13
  • 最后登录2003-08-22
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-12-02 17:58
怎么会得出这个结论的:
>> IFS在同步调用时是不可重入的
>> 所以,如果我在FS_OpenFile的时候不管通过任何方法都无法调用到IFS提供的ring0 Service了.

IFS明显可以重入,而且FS_OpenFile里调用ring0完全可以啊,另外你挂住FS_OpenFile,等用户层处理?有什么理由非得这样做吗?
xzjfile
禁止发言
禁止发言
  • 注册日期2001-12-14
  • 最后登录2018-07-12
  • 粉丝0
  • 关注0
  • 积分6970分
  • 威望50721点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
  • 社区居民
6楼#
发布于:2002-12-02 19:12
用户被禁言,该主题自动屏蔽!
xzjfile
禁止发言
禁止发言
  • 注册日期2001-12-14
  • 最后登录2018-07-12
  • 粉丝0
  • 关注0
  • 积分6970分
  • 威望50721点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
  • 社区居民
7楼#
发布于:2002-12-02 21:44
用户被禁言,该主题自动屏蔽!
Coolice
驱动小牛
驱动小牛
  • 注册日期2002-11-13
  • 最后登录2003-08-22
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-12-03 12:17
...弄了半天怎么又回来了...前面不是很详细地给你回答了吗。
xzjfile
禁止发言
禁止发言
  • 注册日期2001-12-14
  • 最后登录2018-07-12
  • 粉丝0
  • 关注0
  • 积分6970分
  • 威望50721点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
  • 社区居民
9楼#
发布于:2002-12-03 12:48
用户被禁言,该主题自动屏蔽!
Coolice
驱动小牛
驱动小牛
  • 注册日期2002-11-13
  • 最后登录2003-08-22
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-12-03 13:29
>> 1.直接构造是可能的.使用未公开的ifsreq,104h大小.Stan Michelle也确实做到了,但正如他自己说的那样,在取的入口点上好像是很存在问题的.我不准备这样做,太麻烦了.
 
直接构造是最不推荐的方法

>> 2.改文件名,这没用.要改回去,不是一个ppath的问题.

可以的,我试过

>> 3.使用线程ID.可问题是,ioreq中使用的pid,并不是线程ID.我并不肯定这种做法,如果可以这恐怕是个好方法了.

Get_Cur_Thread_Handle 不就可以了啊,在自己的线程中先调用一下,然后在FS_OpenFile里也调用,比较一下就可以了,Norton Anti-Virus就是这样做的

>> 4.记录线程ID的方法是不行的.实际上,你可以看到打开操作在有的时候会接连打开两次到三次(原因是什么,我也不知道).这样,我想你不能说下面一个打开操作就是你发出的吧.

我的很多Driver都是这样做的,冲突的软件最少,也最简单(记住,同一个线程怎么可能会同时有两次操作?你能在一个线程里同时处理两件事吗?所以第二次以后就必然是重入的,PASS就行啦,当然这个重入也可能是其它的Filter重入,但是没有关系的,他们有自己的处理)

同时记得FS_OpenFile处理结束时,这个线程就不要再跟踪了。

>> 实际上,我试了使用未使用的标志位的方法,是可以的.但正如你说的,我怕会有冲突.
还在研究中.

在ME下改标志位问题最多,所以非常不推荐

>> 另,关于第三种方法,能否说明详细点?谢谢.

创建自己的系统线程,挂着等待事件。FS_OpenFile时,激活事件,把需要的参数传递给系统线程,等待系统线程处理完毕。同时FS_OpenFile入口如果发现当前线程是自己的系统线程,就PASS。

>> BTW,已经给了大大你分啊!!!呵呵

谢啦:)
xzjfile
禁止发言
禁止发言
  • 注册日期2001-12-14
  • 最后登录2018-07-12
  • 粉丝0
  • 关注0
  • 积分6970分
  • 威望50721点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
  • 社区居民
11楼#
发布于:2002-12-03 14:39
用户被禁言,该主题自动屏蔽!
rayyang2000
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2012-09-13
  • 粉丝3
  • 关注0
  • 积分1036分
  • 威望925点
  • 贡献值3点
  • 好评度823点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2002-12-03 16:56
4的方法我也常用。

但假设,如果某人写了一个非常烂的程序,先发了一个ReadFile,driver返回pending,而这个程序又不WaitForSingleObject,直接就发了另外一个ReadFile,这时候启不是一个线程发了2个ioreq?

不过,实际测试中没有碰到过,但愿这种程序不要出现才好啊! :D
天天coding-debugging中----超稀饭memory dump file ======================================================== [b]Windows Device Driver Development and Consulting Service[/b] [color=blue][url]http://www.ybwork.com[/url][/color] ========================================================
Coolice
驱动小牛
驱动小牛
  • 注册日期2002-11-13
  • 最后登录2003-08-22
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2002-12-04 09:50
driver既然返回pending,这个线程就取消记录了,所以没有问题的。异步的ReadFile如果没有完成再次调用ReadFile本身就会出问题,就算没有Filter存在,98下也常会死机。
ppl
ppl
驱动小牛
驱动小牛
  • 注册日期2001-06-13
  • 最后登录2006-05-21
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2002-12-08 12:45
4的方法我也常用。

但假设,如果某人写了一个非常烂的程序,先发了一个ReadFile,driver返回pending,而这个程序又不WaitForSingleObject,直接就发了另外一个ReadFile,这时候启不是一个线程发了2个ioreq?

不过,实际测试中没有碰到过,但愿这种程序不要出现才好啊! :D

虽说人家这种程序很烂了?应该是很高级才对嘛。
异步IO还是很有用的嘛。
服务器软件应该用得很多。
omo
omo
驱动牛犊
驱动牛犊
  • 注册日期2002-08-07
  • 最后登录2004-11-16
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2003-01-08 18:16
我也遇到了该死的同样的问题,谢谢你们的讨论,让我茅塞顿开,实在太感谢了!
钱就是驱动,驱动就是钱。
游客

返回顶部