melchior
驱动牛犊
驱动牛犊
  • 注册日期2002-07-09
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望15点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
  • 社区居民
阅读:2584回复:12

To:Coolice大侠,关于ZwQueryDirectoryFile

楼主#
更多 发布于:2003-03-11 12:00
上次你提到了实现文件隐藏保护中的一个思路:在某个情况下,在IRP_MJ_DIRECTORY_CONTROL完成例程中再次调用ZwQueryDirectoryFile来查询该文件夹以填写UserBuffer(这个问题是别人问的)。我试了,结果是MULTIPLE_IO_COMPLETION_REQUEST.
我怀疑ZwQueryDirectoryFile是不能重入的。

异常发生后的stack:

ZwQueryDirectoryFile->NtQueryDirectoryFile->Filem.text+XXX->ZwQueryDirectoryFile->NtQueryDirectoryFile->IoFreeIrp->KeDbgCheckEx
Filem是我的驱动。 :(
michaelgz
论坛版主
论坛版主
  • 注册日期2005-01-26
  • 最后登录2012-10-22
  • 粉丝1
  • 关注1
  • 积分150分
  • 威望1524点
  • 贡献值1点
  • 好评度213点
  • 原创分0分
  • 专家分2分
沙发#
发布于:2008-09-11 02:46
I think the best way for you to avoid re-entrance problem is to build your own query IRP and pass it down to stack.
goyejin
驱动牛犊
驱动牛犊
  • 注册日期2007-03-05
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分14分
  • 威望100点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2008-09-10 16:51
关于重入的问题很容易解决的,用一个TLS变量就可以了。由于只在调用线程的范围内改变TLS变量的值,所以改变当前线程的TLS变量不会改变其它线程中该TLS变量的值,ZwQueryDirectoryFile就可以根据该TLS变量的值来判断是否之前已经进入了一个ZwQueryDirectroyFile调用而且未返回。
而且TlsGetValue、TlsSetValue我跟踪过,其只是简单地利用段寄存器来区分对不同线程中该TLS变量的存取,并没有调用任何API,所以可以完全不用担心调用TlsGetValue、TlsSetValue会产生其它重入问题。
melchior
驱动牛犊
驱动牛犊
  • 注册日期2002-07-09
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望15点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
  • 社区居民
地板#
发布于:2003-03-13 12:01
今晚我把流程写下,麻烦您帮看看。
ZwQueryDirectoryFile重入我已经检测到了关键是重入后IRP_MJ_DIRECTORY_CONTROL Dispatch routine将IRP传到下个驱动就发生了问题。
Coolice
驱动小牛
驱动小牛
  • 注册日期2002-11-13
  • 最后登录2003-08-22
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-03-12 17:06
当然可以啊!
melchior
驱动牛犊
驱动牛犊
  • 注册日期2002-07-09
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望15点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
  • 社区居民
5楼#
发布于:2003-03-12 12:22
你确定ZwQueryDirectoryFile能重入吗? :(
Coolice
驱动小牛
驱动小牛
  • 注册日期2002-11-13
  • 最后登录2003-08-22
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-03-12 10:40
好象你提的这些都不是关键,估计还是处理流程上有什么问题。
melchior
驱动牛犊
驱动牛犊
  • 注册日期2002-07-09
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望15点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
  • 社区居民
7楼#
发布于:2003-03-12 09:15
有一点很关键,我忘记说了。我的驱动建立用于加入文件系统设备栈DeviceObject时,IoCreateDevice参数Exclusive设置为TRUE
melchior
驱动牛犊
驱动牛犊
  • 注册日期2002-07-09
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望15点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
  • 社区居民
8楼#
发布于:2003-03-12 00:59
我是通过PsGetCurrentThread获得的当前线程指针来判断重入。当驱动调用ZwQueryDirectoryFile产生重入后,驱动通过将PsGetCurrentThread获得地指针和上次保存地指针相比较。如果相同,则是重入。

我发现当驱动再次调用ZwQueryDirectoryFile时,该函数会有一个KeWaitForSingleObject调用。这是ZwQueryDirectoryFile
不能重入地原因。    
Coolice
驱动小牛
驱动小牛
  • 注册日期2002-11-13
  • 最后登录2003-08-22
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-03-11 15:32
你有没有做重入判断?
另外的一个方法可以参考这个帖子:
http://www.driverdevelop.com/forum/viewthread.php?tid=33748
melchior
驱动牛犊
驱动牛犊
  • 注册日期2002-07-09
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望15点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
  • 社区居民
10楼#
发布于:2003-03-11 15:07
我的代码没有并没有调用IoCompleteRequest.

关于那个堆栈状态,我写漏了一个IoBuildSynchronizeFSDRequest.在第一次NtQueryDirectoryFile之后有一个IoBuildSynchronizeFSDRequest的调用,但第二次调用(就是我的驱动再次调用)NtQueryDirectoryFile之后就没有IoBuildSynchronizeFSDRequest的调用了。
Coolice
驱动小牛
驱动小牛
  • 注册日期2002-11-13
  • 最后登录2003-08-22
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2003-03-11 13:57
另外上次我提到了一个不用ZwQueryDirectoryFile的方法更好些(ZwQueryDirectoryFile需要处理重入问题),你可以看看以前的帖子
Coolice
驱动小牛
驱动小牛
  • 注册日期2002-11-13
  • 最后登录2003-08-22
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2003-03-11 13:56
这是因为你调用了多次IoCompleteRequest,应该只调用一次
游客

返回顶部