\device\harddiskvolume1,其实这样是不对的,虽然大部分情况下是这样,但是也有C盘对
应\device\harddiskvolume2的情况,而自己实现路径解析显然不现实。我直接在内核层打
开\??\c:\my.txt,并且用IopQueryName函数获取my.txt的NT格式的绝对路径。
2. 在驱动层中获取绝对路径时候,要检测object的pointercount和handlecount这2个域,
因为我们在用户层获取的系统句柄是具有暂时性的,就是说在我们检测这个文件对象的时
候,它可能已经被释放了。这是继续调用IopQueryName函数获取路径会蓝屏的(刚开始没注
意,蓝了几次)。具体代码我打包了,参考我上期的《详解句柄与对象》。
如果找到目标句柄,如何关闭呢?
1. 插入远程线程到目标句柄所在的进程中,调用closehandle关闭
2. 调用DuplicateHandle关闭句柄。
我们来看第二种。
DuplicateHandle声明如下:
[code]
WINBASEAPI
BOOL
WINAPI
DuplicateHandle(
__in HANDLE hSourceProcessHandle,
__in HANDLE hSourceHandle,
__in HANDLE hTargetProcessHandle,
__deref_out LPHANDLE lpTargetHandle,
__in DWORD dwDesiredAccess,
__in BOOL bInheritHandle,
__in DWORD dwOptions
);
[/code]
Duplicatehandle本来是复制源句柄到目标进程的,但是我们不需要复制,只要关闭源句柄
就可以了。所以调用duplicatehandle有个很巧妙的方法,hTargetProcessHandle设为0,
dwOptions设为DUPLICATE_CLOSE_SOURCE可以直接关闭源句柄,而不需要将源句柄复制到本
进程,再关闭。
首先提升本进程权限为debug,然后调用duplicatehandle直接关闭。
代码如下:
[code]
//这段代码提升进程权限为debug
OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&htoken);
LookupPrivilegeValue(0,SE_DEBUG_NAME,&tok.Privileges[0].Luid);
tok.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
tok.PrivilegeCount=1;
AdjustTokenPrivileges(htoken,FALSE,&tok,0,0,0);
handlenumber=*(PULONG)p; //系统句柄总数
p=(ULONG)p+4;
while(i<handlenumber)
{
if(p->ObjectTypeNumber==0x1c) //0x1c表示是文件句柄
{
flags=0; //清除标志位
if(DeviceIoControl(hdev,
DEV_CONTROL_CHECKOBJECT,
&p->Object,
4,
&flags,
4,
&length,
0)) //如果内核层检测符合的话,会设置
flags=1
if(flags)
{
hsourceprocess=OpenProcess(PROCESS_DUP_HANDLE,FALSE,p->Processid);
if(hsourceprocess!=INVALID_HANDLE_VALUE)
{
//一句话关闭源句柄
if(DuplicateHandle(hsourceprocess,p->Handle,0,&length,0,0,DUPLICATE_CLO
SE_SOURCE));
{
printf("handle is close\n");
getch();
}
CloseHandle(hsourceprocess);
}
}
}
i++;
p++;
}
CloseHandle(hdev);
CloseHandle(htoken);
[/code]

然后加载duphandle.sys,并且运行queryhandle.exe。

现在可以在资源管理器中删除my.txt了。
关于hardlink硬链接占坑文件防删除等会介绍。先介绍第三种。
当文件是PE文件且被加载到内存中,我们也是无法通过explorer删除的,因为在删除运 |