首页
社区
课程
招聘
[原创]
发表于: 2014-7-27 11:36 4929

[原创]

2014-7-27 11:36
4929
今天看到一段代码:
HANDLE hFile = ::CreateFile( L"NUL", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
刚开始还以为是作者写错了文件名,把“NULL”写成了"NUL"。可是经过查询才知道原来这段代码的作用是代开系统中的所有文件的句柄。然后往下继续所有资料,发现同过这种方式可以解除文件独占的锁定。具体方法:
BOOL GetVolumeNameByHandle(HANDLE hFile, LPTSTR szVolumeName, UINT cchMax)
{
	BOOL bResult = FALSE;
	TCHAR szBuf[500] = { 0 };
	TCHAR * pIter = szBuf;
	int i =0;
	BY_HANDLE_FILE_INFORMATION stFileInfo = { 0 };

	do
	{
		if(FALSE == GetFileInformationByHandle(hFile, &stFileInfo)) {
			break;
		}

		if(0== GetLogicalDriveStrings(_countof(szBuf), szBuf)) {
			break;
		}

		for(; pIter; pIter+=4)
		{
			DWORD dwVolumeSerialNumber =0;

			if(GetVolumeInformation(pIter, NULL, 0, &dwVolumeSerialNumber, 
				NULL, NULL, NULL, 0))
			{
				if(dwVolumeSerialNumber == stFileInfo.dwVolumeSerialNumber)
				{
					lstrcpyn(szVolumeName, pIter, cchMax);
					bResult = TRUE;
					break;
				}
			}
		}

	} while (FALSE);

	return bResult;
}


BOOL GetFilePathFromHandleW(HANDLE hFile, LPTSTR lpszPath, UINT cchMax)
{
	BOOL bResult = FALSE;
	TCHAR szValue[MAX_PATH] = { 0 };

	IO_STATUS_BLOCK isb = { 0 };
	FILE_NAME_INFORMATION fni = { 0 };
	HANDLE hNtDll = NULL;
	PFN_ZwQueryInformationFile pfn_ZwQueryInformationFile = NULL;

	do
	{
		if (INVALID_HANDLE_VALUE==hFile || NULL==lpszPath ||0==cchMax) {
			break;
		}

		hNtDll = GetModuleHandle(TEXT("ntdll.dll")); 
		if (NULL == hNtDll) {
			break;
		}

		pfn_ZwQueryInformationFile = (PFN_ZwQueryInformationFile)
			GetProcAddress(hNtDll, TEXT("ZwQueryInformationFile"));
		if (NULL == pfn_ZwQueryInformationFile) {
			break;
		}

		// 9 == FileNameInformation
		if (0!= pfn_ZwQueryInformationFile(hFile, &isb, &fni, sizeof(fni), 9)) {
			break;
		}

		if (FALSE == GetVolumeNameByHandle(hFile, szValue, _countof(szValue))) {
			break;
		}

		PathAppend(szValue, fni.FileName);

		lstrcpyn(lpszPath, szValue, cchMax);

		bResult = TRUE;
	} while (FALSE);
	return bResult;
}


BOOL DeleteLockedFile(DWORD dwProcessID, HANDLE hFile)
{
	TCHAR szTargetName[MAX_PATH] = { 0 };
	HANDLE hTargeFile = INVALID_HANDLE_VALUE;
	HANDLE hProcess = NULL;
	BOOL bResult = FALSE;

	do 
	{
		hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID);
		if (NULL == hProcess) {
			break;
		}

		if (FALSE == DuplicateHandle(hProcess, hFile, 
			GetCurrentProcess(), &hTargeFile, 
			0, FALSE, DUPLICATE_SAME_ACCESS)) 
		{
			break;
		}

		if (INVALID_HANDLE_VALUE==hTargeFile || NULL==hTargeFile) {
			break;
		}

		if (FALSE == GetFilePathFromHandle(hTargeFile, 
			szTargetName, _countof(szTargetName))) 
		{
			break;
		}

		CloseHandle(hTargeFile);
		hTargeFile = INVALID_HANDLE_VALUE;

		if (0 == lstrlen(szTargetName)) {
			break;
		}

		if (FALSE == DuplicateHandle(hProcess, hFile, 
			GetCurrentProcess(), &hTargeFile, 
			0, FALSE, 
			DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE))
		{
			break;
		}

		if (INVALID_HANDLE_VALUE==hTargeFile || NULL==hTargeFile) {
			break;
		}

		CloseHandle(hTargeFile);
		hTargeFile = INVALID_HANDLE_VALUE;

		bResult = DeleteFile(szTargetName);
	} while (FALSE);

	if (INVALID_HANDLE_VALUE != hTargeFile && NULL != hTargeFile) {
		CloseHandle(hTargeFile);
	}

	if (hProcess) {
		CloseHandle(hProcess);
	}
	return bResult;
}


1.任何运行中的程序或DLL都可以被删除,包括FileKill360本身
系统文件也可以删除,不过系统的文件检查会将其自动恢复,若关闭自动恢复或将dllcache中文件一起删除,也可以删除之
2.被独占打开的文件,被独占(拒绝读写共享)的文件,也可以删除

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

收藏
免费 0
支持
分享
最新回复 (11)
雪    币: 6
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
不错不错``涨知识了
2014-7-27 11:55
0
雪    币: 71
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
真的不错

谢谢
2014-7-27 12:38
0
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
太厉害了,以前都不知道还有这样的用法
2014-7-27 13:27
0
雪    币: 72
活跃值: (74)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
ztj
5
你贴的代码和
HANDLE hFile = ::CreateFile( L"NUL", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
这个有什么关系

你的主要功能是 DUPLICATE_CLOSE_SOURCE 这个参数吧
2014-7-27 16:59
0
雪    币: 185
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
+10086
2014-7-27 17:03
0
雪    币: 11
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
为什么连250安全卫士的文件粉碎机的介绍都要抄
2014-7-27 17:43
0
雪    币: 967
活跃值: (1138)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
8
MARK
2014-7-27 18:13
0
雪    币: 3533
活跃值: (1803)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
9
没懂 NUL是什么 我查了下
NULL is a macro defined in several standard headers, 0 is an integer constant, '\0' is a character constant, and nul is the name of the character constant. All of these are not interchangeable:

NULL is to be used for pointers only since it may be defined as ((void *)0), this would cause problems with anything but pointers.

0 can be used anywhere, it is the generic symbol for each type's zero value and the compiler will sort things out.

'\0' should be used only in a character context.

nul is not defined in C or C++, it shouldn't be used unless you define it yourself in a suitable manner, like:

#define nul '\0'

既然没有定义 怎么直接使用的 ? 有些迷惑 麻烦说下 谢谢!
2014-7-27 19:33
0
雪    币: 5299
活跃值: (5340)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
这么强悍? 是从哪里发现的这份代码啊??
2014-7-27 20:30
0
雪    币: 144
活跃值: (718)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
mark
2014-7-27 20:36
0
雪    币: 13
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
mark
2014-7-27 20:54
0
游客
登录 | 注册 方可回帖
返回