zhjie374
驱动小牛
驱动小牛
  • 注册日期2004-10-27
  • 最后登录2012-01-17
  • 粉丝2
  • 关注1
  • 积分17分
  • 威望144点
  • 贡献值1点
  • 好评度21点
  • 原创分0分
  • 专家分0分
阅读:3301回复:19

共享我写的:本地目录的只读控制(禁止写、删除、新建))

楼主#
更多 发布于:2005-04-26 13:47
2005.4.26

几句废话:
这是我在驱网发的第二篇文章,第一篇是关于利用过滤驱动将U盘设置为只读的。
这篇是利用文件系统过滤驱动将一个目录(本地硬盘)设置为只读,包括禁止修改
文件,禁止删除文件,禁止新建文件等。 我最终的目的是想实现 利用文件过滤驱动
将任意盘(包括移动,A等)设置为只读。因此我的路还很长,还需要各位的帮助。

正文:
0 准备工作:
  由于是对文件、目录的拦截。首先要知道如何得到路径、文件名、盘符等等。否则
你没有办法去做判断。我使用IFS 中的sfilter修改。因此没有filemon那样有直接的
函数取得。
  在驱动中取得盘符和路径是分开的。取得盘符使用RtlVolumeDeviceToDosName (file->DeviceObject,&dosname); 取得路径的方法是:
  irpSp = IoGetCurrentIrpStackLocation( Irp );
  file = irpSp->FileObject;
  RtlCopyUnicodeString(&name,&file->FileName);
  DbgPrint(\"%ws\",(&name)->Buffer);// 这个地方直接用name.Buffer什么也打印不出来,奇怪
  但是这里要注意的是并不是每一个IRP中的irpSp->FileObject都有,很多时候是NULL。这个值有
文件系统来填写。所以在取路径前一定要做相应的判断,否则会蓝屏。

1 禁止访问目录:
  实现禁止访问目录是比较简单的,有很多的方法。我是在IRP_MJ_DIRECTORY_CONTROL
中判断是不是要禁止的目录,然后拦截。拦截的操作我就不多说了,基本一样:
Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
Irp->IoStatus.Information = 0;
status = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;

2 设置目录为只读
  由于禁止目录访问的方法很容易,所以很容易让人觉得禁止写是不是就是在IRP_MJ_WRITE中
判断目录路径然后直接拦截了。我测试后发现不能这样实现,论坛上的人告我将目录设置为只读
实际上是把目录下所有文件设置为只读,即有一目录C:\\Jason你想设置为只读,实际的操作是:
对于该目录下任一文件xx.xx,当该文件想进行写的时候,驱动会得到路径\\Jason\\xx.xx,此时
判断文件的父目录是不是\\Jason并拦截之,即可实现\\Jaosn\\xx.xx的只读控制。
   到目前我实现就是使用这样的方法,是不是可以直接对目录进行拦截,我不知道。

   有了这个概念,还需要一些技巧去实现。主要是在实现父目录匹配的字符串比较上。这个调
试一下就可以解决了。

3 禁止删除
  禁止删除也还算简单,但是如果你象我一样是一个人瞎搞,也许不会知道这个方法。在此感谢
joshua_yu 告诉我这个方法。
  在IRP_MJ_SET_INFORMATION中,
  PIO_STACK_LOCATION     irpSp = IoGetCurrentIrpStackLocation(Irp);
  irpSp->Parameters.SetFile.FileInformationClass == FileDispositionInformation
  核心的就是判断irpSp->Parameters.SetFile.FileInformationClass 是不是等于
FileDispositionInformation。
  但是我一直很奇怪就是这些技术我怎么没有看到,而别人看的到?看的什么资料??


4 禁止创建文件
  这里主要就是要区别一下新建文件和打开文件。对于这个过程,joshua_yu有他自己的理解:
“我是这样认为的:
当我们调用CreateFile并且希望创建一个文件的时候,系统会首先发送一个标志为FILE_OPEN的请求,并且判断底层文件系统的返回值,如果返回成功,则表明文件存在并且已经成功打开,否则如果返回结果是NO SUCH FILE,则紧接着创建一个FILE_OPEN_IF请求,得以将文件创建,所以如果我们在Create的Options当中发现了FILE_CREATE,FILE_OPEN_IF和FILE_OVERWRITE_IF三个标志,则表明一定是在创建而不是打开。”

原理就是这样,代码实现我是这样做的:
CreateDisposition = (irpSp->Parameters.Create.Options>> 24) & 0x000000ff;
if(CreateDisposition==FILE_CREATE||CreateDisposition==FILE_OPEN_IF
||CreateDisposition==FILE_OVERWRITE_IF)
{
DbgPrint(\"It is a CREATE FILE operation\\n\");
Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
Irp->IoStatus.Information = 0;
status = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}


5 一些其他问题:
  由于这个是一点一点改好的,所以我能想到的主要技术就是这么多了。如果有问题,请和我交流
zhjie374@hotmail.com

  顺便问个问题:移动设备动态插拔我怎么才能拦截到它的IRP?

6 最后还是要说一句: 本人毕业于排名300开外的大学,水平有限,有错误之处请各位批评指正。

Jason Zhang   SCT_SH  2005.4.26
  
























最新喜欢:

rhpengrhpeng yuzheyuzhe
zhjie374
驱动小牛
驱动小牛
  • 注册日期2004-10-27
  • 最后登录2012-01-17
  • 粉丝2
  • 关注1
  • 积分17分
  • 威望144点
  • 贡献值1点
  • 好评度21点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2005-04-26 17:10
补充一下:
上面删除其实不用这么细致。直接拦截对应目录的SET_INFERMATION
即可。这样删除、文件属性修改就全部禁止了。
michaelgz
论坛版主
论坛版主
  • 注册日期2005-01-26
  • 最后登录2012-10-22
  • 粉丝1
  • 关注1
  • 积分150分
  • 威望1524点
  • 贡献值1点
  • 好评度213点
  • 原创分0分
  • 专家分2分
板凳#
发布于:2005-04-27 03:55
设置目录为只读:
I don\'t think IRP_MJ_WRITE is the place. You should do it in MJ_CREATE.

READ ONLY means you cannot create new file, you cannot open file for write/append/truncate.
zhjie374
驱动小牛
驱动小牛
  • 注册日期2004-10-27
  • 最后登录2012-01-17
  • 粉丝2
  • 关注1
  • 积分17分
  • 威望144点
  • 贡献值1点
  • 好评度21点
  • 原创分0分
  • 专家分0分
地板#
发布于:2005-04-27 09:25
you cannot open file for write/append/truncate

只读,我认为目录下的文件是可以读的。否则你拒绝用户访问目录好了
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
地下室#
发布于:2005-04-27 10:32
如何禁止复制,粘贴操作??
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
zhjie374
驱动小牛
驱动小牛
  • 注册日期2004-10-27
  • 最后登录2012-01-17
  • 粉丝2
  • 关注1
  • 积分17分
  • 威望144点
  • 贡献值1点
  • 好评度21点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2005-04-27 10:37
我昨天在群里面也问了,如何能禁止把目录下的文件复制出去。

他们说不可能。

但是我想要复杂实现也可以,就是先把目录下文件名建个表。然后新建立文件的时候看是不是和这些名字一样,然后去拦截。好象想法比较幼稚。。
zhjie374
驱动小牛
驱动小牛
  • 注册日期2004-10-27
  • 最后登录2012-01-17
  • 粉丝2
  • 关注1
  • 积分17分
  • 威望144点
  • 贡献值1点
  • 好评度21点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2005-04-27 10:45
而且这样。还不如在应用层屏蔽复制操作。比如HOOK一些按键。
隐藏一些菜单项
michaelgz
论坛版主
论坛版主
  • 注册日期2005-01-26
  • 最后登录2012-10-22
  • 粉丝1
  • 关注1
  • 积分150分
  • 威望1524点
  • 贡献值1点
  • 好评度213点
  • 原创分0分
  • 专家分2分
7楼#
发布于:2005-04-28 00:37
\"只读,我认为目录下的文件是可以读的。否则你拒绝用户访问目录好了\"

If you only disable MJ_WRITE, how can you prevent user from creating new files???

Again READ ONLY means you cannot create new file, you cannot open file for write/append/truncate.A user can open a file for read only.



[编辑 -  4/28/05 by  michaelgz]
zhjie374
驱动小牛
驱动小牛
  • 注册日期2004-10-27
  • 最后登录2012-01-17
  • 粉丝2
  • 关注1
  • 积分17分
  • 威望144点
  • 贡献值1点
  • 好评度21点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2005-04-28 09:26
Create new file is blocked in IRP_MJ_CREATE.

Please read it carefully,OK?
michaelgz
论坛版主
论坛版主
  • 注册日期2005-01-26
  • 最后登录2012-10-22
  • 粉丝1
  • 关注1
  • 积分150分
  • 威望1524点
  • 贡献值1点
  • 好评度213点
  • 原创分0分
  • 专家分2分
9楼#
发布于:2005-04-28 23:37
I read your original post again.

You did mentioned blocking creating new files in MJ_CREATE (you didn\'t mention it in section \"设置目录为只读\"). But still the problem is you are not blocking users from opening file for update/append/truncate.

For example, if a user opens a file for overwrite, the file size will be truncated to zero. There\'s no MJ_WRITE involved when a file is truncated at this moment. So your solution is still not correct. Since you\'ve already do something in MJ_CREATE, why not do something more in the same place.

Also there\'s different error messages returned to client by blocking MJ_WRITE and blocking MJ_CREATE.Access denied by CREATE is more appropriate than write error.

To me READ ONLY means a file can only be opened for read. So I still insist that to make a file read only, do it in MJ_CREATE.





[编辑 -  4/29/05 by  michaelgz]
qiangguo64
驱动牛犊
驱动牛犊
  • 注册日期2005-01-12
  • 最后登录2009-08-28
  • 粉丝0
  • 关注0
  • 积分144分
  • 威望15点
  • 贡献值1点
  • 好评度14点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2005-05-12 15:40
关于禁止删除,可能不只IRP_MJ_SETINFORMATION这一条途径,IRP_MJ_CREATE 的irpStack->Parameters.Create.Options带有
FILE_DELETE_ON_CLOSE时,IRP_MJ_CLOSE以后,也会删除文件

还有一个问题,可以把文件从被保护的目录移动到别的目录,然后再删除

不过有这样一片总结性的文章,还是挺好的
qiangguo64
驱动牛犊
驱动牛犊
  • 注册日期2005-01-12
  • 最后登录2009-08-28
  • 粉丝0
  • 关注0
  • 积分144分
  • 威望15点
  • 贡献值1点
  • 好评度14点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2005-05-12 15:43
而且这样。还不如在应用层屏蔽复制操作。比如HOOK一些按键。
隐藏一些菜单项


我开一个cmd窗口,copy,del就防不住了,或者自己写个小程序,也防不住,还是在底层做合适
qiangguo64
驱动牛犊
驱动牛犊
  • 注册日期2005-01-12
  • 最后登录2009-08-28
  • 粉丝0
  • 关注0
  • 积分144分
  • 威望15点
  • 贡献值1点
  • 好评度14点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2005-05-12 15:51
我昨天在群里面也问了,如何能禁止把目录下的文件复制出去。

他们说不可能。

但是我想要复杂实现也可以,就是先把目录下文件名建个表。然后新建立文件的时候看是不是和这些名字一样,然后去拦截。好象想法比较幼稚。。
 


复制无非是打开源文件,读源文件,在别的目录创建新文件,写新文件,如果阻值读源文件,那源文件就没有存在的意义了,不能读也不能写

有没有可能在读被保护目录下的源文件的时候,找一个或者几个特定的offset,存一部分数据,比如50个字节,在写目的文件的时候,对这些数据进行比较,如果全部一样,就认为是拷贝被保护的文件,直接禁止就性了

一个粗浅的想法,有时间我自己也试试
fnnx_lsm
驱动牛犊
驱动牛犊
  • 注册日期2005-12-15
  • 最后登录2014-03-31
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望112点
  • 贡献值0点
  • 好评度40点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2007-04-26 15:26
别的啥也不说了!,


谢谢嗬!~~
bluebirdbxj
驱动牛犊
驱动牛犊
  • 注册日期2006-03-15
  • 最后登录2010-06-01
  • 粉丝0
  • 关注0
  • 积分80分
  • 威望9点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2007-04-27 09:01
我也试试
shenhui
驱动小牛
驱动小牛
  • 注册日期2006-05-11
  • 最后登录2023-02-10
  • 粉丝14
  • 关注11
  • 积分142分
  • 威望1314点
  • 贡献值1点
  • 好评度146点
  • 原创分0分
  • 专家分1分
  • 社区居民
15楼#
发布于:2007-04-27 12:09
我感觉5楼和11楼的想法也有点问题,不论是做在应用层还是做在底层,如果我在cmd里面用copy命令,还是可以完成拷贝,因为copy的源文件名和目的文件名是可以不一样的。

另外,我觉得在sfwrite里面通过拦截IRP_MJ_WRITE消息来达到只读效果还存在一个问题,那就是我不能再创建新的文件了,因为创建新文件的时候也要通过SfWrite。
作一名真实,诚实,优秀的科技工作者!
yaolixing
驱动小牛
驱动小牛
  • 注册日期2006-06-27
  • 最后登录2010-07-15
  • 粉丝1
  • 关注0
  • 积分991分
  • 威望135点
  • 贡献值0点
  • 好评度124点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2007-05-01 22:03
if someone can read a file,and can also find somewhere to write,he must can copy the file.:)
jesse3453
驱动小牛
驱动小牛
  • 注册日期2006-03-15
  • 最后登录2010-04-13
  • 粉丝0
  • 关注0
  • 积分1001分
  • 威望111点
  • 贡献值0点
  • 好评度100点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2007-05-31 14:58
其实也可以利用文件过滤驱动的HOOK技术实现只读控制,
切入点:
ZwCreateFile
ZwSetInformationFile
冰枫化古
zjwsns
驱动牛犊
驱动牛犊
  • 注册日期2007-12-23
  • 最后登录2009-09-12
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望37点
  • 贡献值0点
  • 好评度25点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2008-07-09 10:06
请问
这样实现目录的创建控制代码能跑么
katon
驱动牛犊
驱动牛犊
  • 注册日期2006-06-22
  • 最后登录2014-09-23
  • 粉丝1
  • 关注0
  • 积分26分
  • 威望150点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
19楼#
发布于:2008-12-09 18:03
引用:
4 禁止创建文件
这里主要就是要区别一下新建文件和打开文件。对于这个过程,joshua_yu有他自己的理解:
“我是这样认为的:
当我们调用CreateFile并且希望创建一个文件的时候,系统会首先发送一个标志为FILE_OPEN的请求,并且判断底层文件系统的返回值,如果返回成功,则表明文件存在并且已经成功打开,否则如果返回结果是NO SUCH FILE,则紧接着创建一个FILE_OPEN_IF请求,得以将文件创建,所以如果我们在Create的Options当中发现了FILE_CREATE,FILE_OPEN_IF和FILE_OVERWRITE_IF三个标志,则表明一定是在创建而不是打开。”

原理就是这样,代码实现我是这样做的:
CreateDisposition = (irpSp->Parameters.Create.Options>> 24) & 0x000000ff;
if(CreateDisposition==FILE_CREATE||CreateDisposition==FILE_OPEN_IF
||CreateDisposition==FILE_OVERWRITE_IF)
{
DbgPrint(\"It is a CREATE FILE operation\\n\");
Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
Irp->IoStatus.Information = 0;
status = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}

这样好像不行吧?
但CreateDisposition==FILE_CREATE的时候有可能是打开文件夹操作,还有这几个动作不是同一时间发生的。
游客

返回顶部