注意点
关于打开文件,很可能这类操作被hook了,尽量用更底层的函数去打开,比如IoCreateFile相对zw低一些。
关于被其他程序独占,遍历系统句柄表,尝试去找到这个句柄表zwQuerySystemInformation,然后把他独占这个文件的进程,句柄关掉。但是这种对于硬链接占坑的方法失效,值能使用xcb方法或者磁盘填零法。对于句柄表,怎么确定是我们要删除的文件,就是通过句柄表内核对象,然后查询内核对象的名字,然后匹配。
关于关闭句柄使用的是ZwDuplicateObject ,这个函数是导出但未文档化的,通过这个函数把要关掉的句柄拷贝到当前进程空间中来,同时加上DUPLICATE_CLOSE_SOURCE标志,就是同时关掉。
关于解决正在运行中的程序,因为操作系统会判断某些文件内核对象的比如SectionObjcetPointer成员是否为0,所以可以伪造。
防止方法
xcb思想
自己实现Nt系列操作文件的功能,重新加载内核。
对于硬链接关句柄无效
硬链接:mklink /h link.txt gb.txt link.txt是对gb.txt的一个alias,链接计数(删除减1),相当于别名,同一个空间,所以不能跨卷。
所以关句柄对硬链接无效,因为硬链接的文件根本没有句柄。
xcb可以对付硬链接。
xcb法的思路:以特权方式无法打开文件,就以低权限打开文件,然后获得FileObject;
pSCB=FileObject->FsContext
pCCB=FileObject->FsContext2;
伪造句柄完全被关闭,CleanUpCount针对于一个文件被打开句柄数,我们打开文件后这个值就是2,如果伪造成1,我们关闭自己适合,就变成零了
scb->CleanUpCount=1;
fcb->CleanUpCount=1;
ccb->CleanUpCount=1;
修改CleanUpCount之后,调用NtClose关闭句柄,这样在NtClose下次调用NtfsRemoveLink移除硬链接,然后NtfsDecrementCleanupCounts()将CleanupCount减1,这样引用计数降为0,释放所有关联SCB。然后调用IoRemoveShareAccess()将ShareAccess.OpenCount清零,解锁。
磁盘填0