Windows文件自删除的两种方法
可执行模块的自删除技术已经被讨论的很多, 有很多极富创意的思路和想法被提出, 但有些似是而非的方案往往使人误入歧途. 举个例子来说, 很多文章认为下面的一小段代码可以实现自删除:
void main(void)
{
TCHAR szCMD[NAME_LENGTH] = {0};
strcpy(szCMD, "cmd /c del ");
strcat(szCMD, ::GetProgramName());
::WinExec(szCMD, 0);
}
初看起来, 这段代码表面上没有什么问题, 运行测试发现很好很奏效, 又简单又明了, 难道存在隐藏的错误? 是的! 可以很肯定的告诉大家, 这段代码从原则上来说是错误的! 它的错误可以归结为一句话: 不能无条件地假设多个进程在特定时刻的运行顺序!
编写上面例子代码的时候, 不知不觉的陷入了一个假相陷阱: cmd进程会在当前程序退出后开始执行(假设了cmd进程与当前应用程序进程的执行顺序). 我们可以加入一条Sleep语句来验证这个假相陷阱, 代码如下:
void main(void)
{
TCHAR szCMD[NAME_LENGTH] = {0};
strcpy(szCMD, "cmd /c del ");
strcat(szCMD, ::GetProgramName());
::WinExec(szCMD, 0);
::Sleep(1000);
}
结果发现程序现在不能自删除了. 为什么? 就是因为cmd进程开始运行时, 当前应用程序进程仍然存在, 系统不能释放当前应用程序的可执行文件句柄, 导致文件不能被删除. 有些朋友会说: 没关系, 我在调用::WinExec(szCMD, 0);后什么也不做就退出, 这样不就OK啦? 真的这样就OK了? 实际上你无法保证在调用::WinExec(szCMD, 0);后进程立即退出且释放当前应用程序的可执行文件句柄. 因为在很多情况下, 应用程序的退出是一个相对缓慢的过程(像卸载大量的dll, 释放各种资源, C++全局对象的析构etc.)
现在给大家介绍几种简单可行的Windows可执行模块安全自删除技术
1) MoveFileEx() API, 在NT以后的Windows平台上被引入. 它的原型是
BOOL MoveFileEx(
LPCTSTR lpExistingFileName,
LPCTSTR lpNewFileName,
DWORD dwFlags
);
如果传NULL给lpNewFileName并置dwFlags为MOVEFILE_DELAY_UNTIL_REBOOT, 那么系统重启后lpExistingFileName所指定的文件就会被删除.
而在9x下, 需要修改win.ini, 给出类似 "filename= "这样的字段, 那么系统重启后"filename"所指定的文件会被删除.
它们的共同点就是Windows系统保证文件的正确删除, 非常简单, 而且对于一些系统级,驱动级文件来说是唯一可靠的方法, 缺点是要求系统重启才能真正删除指定的文件.
2) 利用文件的FILE_FLAG_DELETE_ON_CLOSE属性实现安全自删除
当创建文件时如果指定了FILE_FLAG_DELETE_ON_CLOSE属性, 系统会在该文件的所用句柄被关闭后立刻自动删除该文件.
步骤:
1) 使用CreateFile() API创建一个新文件, 指定FILE_FLAG_DELETE_ON_CLOSE属性.
2) 使用一个可执行文件映象填充这个新文件.
3) 使用CreateProcess() API启动新文件进程.
4) 借助任意的进程间通信机制保证新文件进程在当前程序退出后安全的删除可执行文件.
5) 新文件进程结束后系统将自动删除新文件, 至此, 自删除顺利完成.
很多我的朋友使用这种方式后, 感觉很简单明了也有很强的适应性. 他们写出了各式各样的应用方法, 实践证明这种方式是可靠安全的.
最后大家可以使用以上介绍的方法自己动手尝试, 就不再给出例子啦, 自己动手最可靠, 嘿嘿. 有任何问题, 错误请指出, 谢过先.
Windows文件自删除的两种方法的更多相关文章
- mybatis 根据id批量删除的两种方法
原文:https://blog.csdn.net/qq_40010745/article/details/81032218 mybatis 根据id批量删除的两种方法 第一种,直接传递给mappe ...
- oracle多表关联删除的两种方法
oracle多表关联删除的两种方法 第一种使用exists方法 delete from tableA where exits ( select 1 from tableB Where tableA.i ...
- vba判断文件是否存在的两种方法(转)
方法1. 用VBA自带的dir()判断,代码如下: 在 Microsoft Windows 中, Dir 支持多字符 (*)和单字符 (?) 的通配符来指定多重文件 Function IsFileEx ...
- VC++实现获取文件占用空间大小的两种方法(非文件大小)
// GetFileSpaceSize.cpp : Defines the entry point for the console application. // /***************** ...
- Windows添加启动项的两种方法
方案1直接将脚本放到启动文件夹里面 C:\Users\XXX\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup 方案2 Win ...
- SpringBoot从入门到精通十一(SpringBoot文件上传的两种方法)
前言 在企业级项目开发过程中,上传文件是最常用到的功能.SpringBoot集成了SpringMVC,当然上传文件的方式跟SpringMVC没有什么出入. 本章目标 使用SpringBoot项目完成单 ...
- C#实现Web文件上传的两种方法
1. C#实现Web文件的上传 在Web编程中,我们常需要把一些本地文件上传到Web服务器上,上传后,用户可以通过浏览器方便地浏览这些文件,应用十分广泛. 那么使用C#如何实现文件上传的功能呢?下面笔 ...
- 清除SQLServer日志的两种方法
日志文件满而造成SQL数据库无法写入文件时,可用两种方法:一种方法:清空日志.1.打开查询分析器,输入命令DUMP TRANSACTION 数据库名 WITH NO_LOG2.再打开企业管理器--右键 ...
- Delphi Windows API判断文件共享锁定状态(OpenFile和CreateFile两种方法)
一.概述 锁是操作系统为实现数据共享而提供的一种安全机制,它使得不同的应用程序,不同的计算机之间可以安全有效地共享和交换数据.要保证安全有效地操作共享数据,必须在相应的操作前判断锁的类型,然后才能确定 ...
随机推荐
- android 设置textview中划线效果
textView.getPaint().setFlags(Paint. UNDERLINE_TEXT_FLAG ); //下划线 textView.getPaint().setAntiAlias( ...
- svn报错:privious operation has not finshed;run 'cleanup' if it was interrupted
在更新svn的过程中,可能中途会取消,取消之后再次更新时可能提示,如下图: 下载sqlite3工具,进入此下载地址:https://www.sqlite.org/download.html 将sqli ...
- bzoj 2326: [HNOI2011]数学作业【dp+矩阵快速幂】
矩阵乘法一般不满足交换律!!所以快速幂里需要注意乘的顺序!! 其实不难,设f[i]为i的答案,那么f[i]=(f[i-1]w[i]+i)%mod,w[i]是1e(i的位数),这个很容易写成矩阵的形式, ...
- 手机端实现6位短信验证码input输入框效果(样式及代码方法)
微信移动端4位.6位.多位验证码密码输入框功能的实现代码,实现思路: 方案1: 写一个简单的input框. 评估:样式不好看,待定. 方案2: 就是用6个input框,每输入一个数字之后,切换到下一个 ...
- 数据结构RMQ
RMQ算法介绍 RMQ算法全称为(Range Minimum/Maximum Query)意思是给你一个长度为n的数组A,求出给定区间的最值的下标.当然我们可以采用枚举,但是我们也可以使用线段树来优化 ...
- border-1px的实现(stylus)
当样式像素一定时,因手机有320px,640px等.各自的缩放比差异,所以设备显示像素就会有1Npx,2Npx.为保设计稿还原度,解决就是用media + scale. // stylus语法 bor ...
- AFNetworking2.5使用-转
来自:http://blog.csdn.net/daiyelang/article/details/38434023 官网下载2.5版本:http://afnetworking.com/ 此文章是基于 ...
- 重写java.lang.String IndexOf()方法,实现对字符串以ASCII规则截取
/** * 根据元数据和目标ascii位数截取字符串,失败返回-1 * @param sourceStr 元数据字符串 * @param endIndex 截取到第几位 * @return 结果字符串 ...
- CF932C Permutation Cycle
思路: 构造. 实现: #include <bits/stdc++.h> using namespace std; ]; int main() { int n, a, b; while ( ...
- mac系统 usr/ 目录下无法新建文件夹???
这个问题是在操作mongodb的时候遇到的,很苦恼.目前已经解决,将解决方法分享给各位遇到同样问题的你们. 1.重启电脑,开始关机就立马按住command+R,进入macOS恢复功能界面,进入的时间可 ...