首页
社区
课程
招聘
[求助]关于文件占坑的一点疑问,附代码加文件占坑文档。
发表于: 2011-6-5 01:55 11583

[求助]关于文件占坑的一点疑问,附代码加文件占坑文档。

2011-6-5 01:55
11583
想要保护某个文件不被删除,不被重命名,不能被移动。。。等一些操作,在网上找到了叫文件占坑的方法,并且进行了测试,确实有一定的效果:代码如下:
#include <windows.h>

BOOL OccupyFile( LPCTSTR lpFileName );


int main()
{
     OccupyFile("c:\\aaa111.txt");

     return 0;
}



void RaiseToDebugP()
{
     HANDLE hToken;
     HANDLE hProcess = GetCurrentProcess();
     if ( OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken) )
     {
         TOKEN_PRIVILEGES tkp;
         if ( LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid) )
         {
             tkp.PrivilegeCount = 1;
             tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
            
             BOOL bREt = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, 0) ;
         }
         CloseHandle(hToken);
     }    
}

BOOL OccupyFile( LPCTSTR lpFileName )
{
     BOOL     bRet;
    
     RaiseToDebugP();

     HANDLE hProcess = OpenProcess( PROCESS_DUP_HANDLE, FALSE, 4);     // 4为system进程号

     if ( hProcess == NULL )
     {
         hProcess = OpenProcess( PROCESS_DUP_HANDLE, FALSE, 8);         // 2K下是 8??
        
         if ( hProcess == NULL )
             return FALSE;
     }

     HANDLE hFile;
     HANDLE hTargetHandle;

     hFile = CreateFile( lpFileName, GENERIC_READ, 0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL, NULL);    


     if ( hFile == INVALID_HANDLE_VALUE )
     {
         CloseHandle( hProcess );
         return FALSE;
     }

     bRet = DuplicateHandle( GetCurrentProcess(), hFile, hProcess, &hTargetHandle, 
         0, FALSE, DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE);

     CloseHandle( hProcess );

     return bRet;
}


运行此代码中即使关闭掉该进程,位于C盘下的aaa111.txt文件也不能被删除不能被重命名不能移动等。因为代码中已经将此文件内核对象的句柄复制到了System进程中了。

我的疑问:把这个文件句柄复制到System中为什么就不能重命名、移动文件了呢?
起初想的原因是可能是System进程的权限太高导致的,于是换成了QQ的进程,但是发现仍然不能重命名、移动。。
于是我自己又做了一个实验:在桌面上建立了一个1.txt文件,双击打开此文件,然后我F2给这个文件重命名发现确可以进行重命名操作,于是又否定了:并非因为某个进程正在访问这个文件而不能进行重命名、移动等这些操作。
更何况,System进程只是获得了aaa111.txt的句柄,它连打开访问这个文件都没进行呢。。。
越来越想不明白到底这个是什么原因了,希望各位大哥大嫂们给小弟解释解释,先谢谢大家了。
我特意下载了这篇资料分享给大家。也算是对论坛的一点点回报吧。

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 0
支持
分享
最新回复 (20)
雪    币: 132
活跃值: (214)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
2
刚才想了想,还想咨询一下大家的意见:这样占坑把文件给保护了,那我如何去掉这个保护呢?不至于把System进程给结束掉吧,系统进程呢。。。。。。。
不晓得大家对这个有何高见呢
2011-6-5 02:24
0
雪    币: 23
活跃值: (31)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
这个技术挺有趣的 等待解答
2011-6-5 08:01
0
雪    币: 1981
活跃值: (771)
能力值: ( LV13,RANK:420 )
在线值:
发帖
回帖
粉丝
4
对系统来说,他可不管你有没有调用CreateFile来打开文件,只要有句柄还没关闭就不会销毁内核对象
2011-6-5 09:06
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
5
DuplicateHandle + DUP_CLOSE_SOURCE
2011-6-5 09:49
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
6
其实主要原因在于CreateFile的第三个参数~
2011-6-5 09:50
0
雪    币: 132
活跃值: (214)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
7
删除文件不行,但是我重命名啊移动文件等这些操作为什么也不行呢?
2011-6-5 11:04
0
雪    币: 132
活跃值: (214)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
8
按照你说的,第三个参数代表共享模式,我把0改成了(0表示不共享)FILE_SHARE_READ|FILE_SHARE_WRITE进行测试,发现该文件还是也不能删除也不能移动
请问你说的是这个意思吗,还是我理解错了,谢谢指点。。
2011-6-5 11:13
0
雪    币: 1981
活跃值: (771)
能力值: ( LV13,RANK:420 )
在线值:
发帖
回帖
粉丝
9
windows下一个文件被打开后不能重命名,不能移动,这是基本常识
2011-6-5 11:43
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
10
一个正在被打开的文件当然不能进行这些操作,但是这时对它进行读写是可以的~
2011-6-5 11:47
0
雪    币: 132
活跃值: (214)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
11
于是我自己又做了一个实验:在桌面上建立了一个1.txt文件,双击打开此文件,然后我F2给这个文件重命名发现确可以进行重命名移动等操作,于是又否定了:并非因为某个进程正在访问这个文件而不能进行重命名、移动等这些操作。

这样怎么就可以呢,不相信你可以测试一下的。
2011-6-5 11:56
0
雪    币: 249
活跃值: (71)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
12
用xuetr可以轻松删除,求进一步解释!
2011-6-5 12:07
0
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
关注。。。学习!
2011-6-5 12:12
0
雪    币: 1981
活跃值: (771)
能力值: ( LV13,RANK:420 )
在线值:
发帖
回帖
粉丝
14
为什么不自己写个程序试一下,要用notepad来做实验,notepad的代码是什么都看不到。
notepad在读取文件后就把文件给关闭了,你当然可以做这些操作。
2011-6-5 13:29
0
雪    币: 284
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
感谢楼主分享
2011-6-5 13:42
0
雪    币: 132
活跃值: (214)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
16
首先感谢你,你的话很有意味。按照你的思路进行了测试,果不其然,你说的应该是对的。
自己用代码写确实会有所收获。测试代码:
hFile=CreateFile(TEXT("C:\\123.txt"),GENERIC_READ,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
	CloseHandle(hFile);
	ShellExecute(NULL,TEXT("open"),TEXT("C:\\123.txt"),NULL,NULL,SW_SHOWNORMAL);

上面是模仿记事本的实现方式,并且进行了测试
当去掉
CloseHandle(hFile);
        ShellExecute(NULL,TEXT("open"),TEXT("C:\\123.txt"),NULL,NULL,SW_SHOWNORMAL);
这两句的时候不能对这个文件进行任何操作,保护移动、重命名。。。
加上CloseHandle就能够进行上述操作了。但是毕竟没有打开文件,因此我又想记事本可能是用ShellExecute打开的,进行了测试,因为这个函数中并没有涉及到文件内核句柄,因此即使打开此文件,也可以操作。
疑问还是有点的:内核对象的句柄为何就如此设计呢?核心编程中只说每个进程的进程句柄表中存放了内核对象的索引也就是句柄了,并没有交代其他进程不能访问此内核对象啊?应该是可以的,只要其他进程也拥有该内核对象的句柄就能访问。但是这里测试的结果却是:只要内核对象的句柄没有关闭,其他进程就不能操作此内核对象?这是不是有点矛盾呢?这里始终有点迷茫,还请你指点一下,谢谢先。
2011-6-5 16:50
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
17
记事本打开文件之后就MapViewOfFile,然后就把文件句柄关掉了。。。
2011-6-5 21:21
0
雪    币: 107
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
试试BMP WORD格式看看
2011-6-6 21:40
0
雪    币: 132
活跃值: (214)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
19
正如你所说,测试了一下EXCEL文件,的确是这样的,
测试代码:
	OFSTRUCT ofstruct;
	ofstruct.cBytes=sizeof(OFSTRUCT);
	OpenFile(TEXT("C:\\Documents and Settings\\Administrator\\桌面\\新建 Microsoft Office Excel 工作表.xlsx"),&ofstruct,OF_DELETE);
	cout<<GetLastError()<<endl;

当然前提是我已经手动打开了这个文件了。
返回32,表面此文件被进程占用,因此删除失败的。
一直很困惑,只要有一个进程在访问某个内核对象或者说没有访问该内核对象(只是拥有该内核对象的句柄,通过上述的复制),那其他进程都不能访问该文件了吗?是不是跟内核对象能被共享访问矛盾了?独占?共享?麻烦给解释解释这个迷雾,3Q!
2011-6-6 23:59
0
雪    币: 132
活跃值: (214)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
20
复制句柄到另外一个进程就实现了进程间共享内核对象了吗?
也就是说另外一个进程也能操作此内核对象了是吧(比如内核对象是个文件对象,那操作可以是移动文件,重命名文件,删除文件等等)?那如何验证是不是真的能操作(比如重命名文件等)呢?
2011-6-7 00:16
0
雪    币: 132
活跃值: (214)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
21
看记事本打开大文件的速度,不像是使用了内存映射文件机制吧,速度慢的很啊,你这里的意思是?求解释。。。
2011-6-7 12:14
0
游客
登录 | 注册 方可回帖
返回
//