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两种方法)
一.概述 锁是操作系统为实现数据共享而提供的一种安全机制,它使得不同的应用程序,不同的计算机之间可以安全有效地共享和交换数据.要保证安全有效地操作共享数据,必须在相应的操作前判断锁的类型,然后才能确定 ...
随机推荐
- javascript 省、市、地县三级联动
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML><HEAD&g ...
- UVA - 1401 Remember the Word(trie+dp)
1.给一个串,在给一个单词集合,求用这个单词集合组成串,共有多少种组法. 例如:串 abcd, 单词集合 a, b, cd, ab 组合方式:2种: a,b,cd ab,cd 2.把单词集合建立字典树 ...
- Python: PS 图像调整--亮度调整
本文用 Python 实现 PS 图像调整中的亮度调整,具体的算法原理和效果可以参考之前的博客: http://blog.csdn.net/matrix_space/article/details/2 ...
- HDU1402:A * B Problem Plus(FFT与大数乘法)
Calculate A * B. Input Each line will contain two integers A and B. Process to end of file. Note: th ...
- c++爬虫子
Larbin是一个用C++开发的开源网络爬虫,有一定的定制选项和较高的网页抓取速度. 下图表示了一般爬虫抓取网页的基本过程. 抓取以/Larbin.conf中的startUrl做为种子URLs开始. ...
- 【转】使用git将项目上传到github(最简单方法)
原文地址:http://www.cnblogs.com/cxk1995/p/5800196.html 首先你需要一个github账号,所有还没有的话先去注册吧! https://github.com/ ...
- Linux - 常用命令索引
文件和目录操作 pwd - 显示当前所在的位置 cd - 切换目录 文件过滤及内容编辑 ... 文本处理三剑客 ... 系统信息查询与搜索文件 ... 文件备份与压缩 ... 用户管理与信息查询 .. ...
- bzoj2581 [USACO 2012 Jan Gold] Cow Run【And-Or Tree】
传送门1:http://www.usaco.org/index.php?page=viewproblem2&cpid=110 传送门2:http://www.lydsy.com/JudgeOn ...
- String Mark Codeforces - 895D
一看好像会做的样子,就去做了一下,结果 猝不及防地T掉了 赶紧查了一下,没有死循环,复杂度也是对的,无果,于是翻了题解 题解没看懂,但是找到了标程,然后发现我被卡常了... 而且好像当时还过了前10个 ...
- 为HttpClient和HttpURLConnection添加中国移动代理
转自: http://www.2cto.com/kf/201111/112100.html 在android中,一般需要联网的时候前,都要做一次网络的判断,判断当前的网络状态!然后开始请求网络 当我们 ...