MOVEFILE_WRITE_THROUGH:只有当文件完全到达目的文件的时候函数才返回,缓冲区也不能有未留的数据
MoveFileEx这个函数调用的时候有几个需要的点 , 第一个就是当dwFlags为MOVEFILE_DELAY_UNTIL_REBOOT时 , 需要为system或administrartor权限才能执行 , 第二个点就是如果要移动目录需要保证目录不存在才可以 , 第三个点就是不能在不同的盘符下移动目录 。
那么我们这里实现自删除的话 , 就是好需要设置dwFlags为MOVEFILE_DELAY_UNTIL_REBOOT , 这里为什么要system或者administrator权限呢 , 是因为MoveFileEx是通过写入HKEY_LOCAL_macHINESYSTEMCurrentControlSetControlSession ManagerPendingFileRenameOperations这个注册表路径来达到移动或删除的目的 , 我们可以看到这个键是位于HKEY_LOCAL_MACHINE的 , 而不是USER , 所以必须要administrator权限进行修改
这里我们看一下这个键值 , 它的类型是REG_MULTI_SZ , 那么意味着这个键值能够写入多个字符串

文章插图
经过探究后发现 , MoveFileEx这个api在执行删除操作写入File到PendingFileRenameOperations , 而如果是执行移动操作则是把FileOtherFile写入PendingFileRenameOperations

文章插图
那么如何用MoveFileEx实现自删除呢 , 首先提两个概念 , AUTOCHK和页面文件 。
这里说下何为AUTOCHK:
在msdn的官方解释中 , AUTOCHK的含义是:Runs when the computer is started and prior to Windows Server starting to verify the logical integrity of a file system.
也就是说AUTOCHK其实是用来验证文件系统的逻辑完整性的 , 那么再说说页面文件:
页面文件 , 是指操作系统反映构建并使用虚拟内存的硬盘空间大小而创建的文件 。要整理页面文件 , 首先将页面文件从原先所在的驱动器移动到其他驱动器 , 然后对原来驱动器进行整理 , 最后再将页面文件移回到原驱动器上 , 此时页面文件就会存放在连续的磁盘空间中了 。具体来说 , 在 windows操作系统下(Windows 2000/XP)pagefile.sys这个文件 , 它就是系统页面文件(也就是大家熟知的虚拟内存文件) , 它的大小取决于打开的程序多少和你原先设置页面文件的最小最大值 , 是不断变化的 , 有时可能只有几十MB , 有时则达到几百甚至上千MB 。那么这两个概念有什么关联呢 , 有一个时间节点就是 , 用户在启动计算机时 , 执行了AUTOCHK , 但是还没有创建页面文件 , 在这个时间节点下 , 可以说话用户是还没有完全进入操作系统的 , 那么这时候就可以删除在正常情况下删除不了的文件 , 我的理解是在没有创建页面文件的时候 , 其实操作系统是还没有启动完全的 , 所以这时候可执行文件其实是没有完全加载好的 。
那么我们知道了原理 , 这里实现一下 , 其实代码相比于批处理方式少了很多 , 但是涉及到的知识点却是一点都不少 。我们在前面发现在PendingFileRenameOperations键的数值数据中 , 路径前面都有?? , 但是这里并不是加上?? , 在MoveFileEx的函数定义中删除文件的路径开头需要加上\?

文章插图
所以我们在缓冲区前面先加上\?
char szTemp[MAX_PATH] = "\\?\";因为我们要把路径写在缓冲区后面 , 就要使用到lstrcat::lstrcat(szTemp, szFileName);然后调用MoveFileEx实现自删除BOOL bRet = ::MoveFileEx(szTemp, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);完整代码如下BOOL MoveDel(char* szFileName){char szTemp[MAX_PATH] = "\\?\";::lstrcatA(szTemp, szFileName);BOOL bRet = ::MoveFileExA(szTemp, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);if (bRet == NULL){printf("[!] MoveFileExA failed, error is : %dnn", GetLastError());return FALSE;}else{printf("[*] MoveFileExA successfully!nn");}return TRUE;}这里我们直接执行一下 , 发现报错5 , 对应GetLastError的报错属性是权限不够 , 这里我们之前提到过需要修改注册表 , 所以直接用user权限启动是拒绝访问的
推荐阅读
- 厉害了!推荐一个 Web 端自动化神器 - Automa
- win10系统自带的截图快捷键有多香
- 2021年Android开发新技术动向,未来的路该怎么走?
- 仿古门窗制造技术简介
- 粉底液|别再说自己不会化妆了,这次我手把手教你
- 护肤|居家自救护肤攻略~护肤千万不可以偷懒
- 自己煮水果茶的配方,煮水果茶的禁忌是什么
- 中蜂觅蜂堂是合法的吗,中蜂是怎样自然分蜂的
- 上海市|上海一女大学生面试时被严重猥亵,女生讲述不堪细节,对方称自愿的
- |人在职场,有哪些事是在“作废”自己?
