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两种方法)
一.概述 锁是操作系统为实现数据共享而提供的一种安全机制,它使得不同的应用程序,不同的计算机之间可以安全有效地共享和交换数据.要保证安全有效地操作共享数据,必须在相应的操作前判断锁的类型,然后才能确定 ...
随机推荐
- 四.OC基础--1.文档安装和方法重载,2.self和super&static,3.继承和派生,4.实例变量修饰符 ,5.私有变量&私有方法,6.description方法
四.OC基础--1.文档安装和方法重载, 1. 在线安装 xcode-> 系统偏好设置->DownLoads->Doucument->下载 2. 离线安装 百度xcode文档 ...
- 【HDU 2167】 Pebbles
[题目链接] 点击打开链接 [算法] 状压DP 先搜出一行符合的情况,然后,f[i][j]表示第i行,状态为j,能够取得的最大值,DP即可 [代码] #include<bits/stdc++.h ...
- MySQL基础操作——转
原文: [培训]MySQL yum安装mysql:yum -y install mysql*- 或者 yum -y install mysql* 启动数据库服务:/etc/init.d/mysqld ...
- 搭建CARDBOARD+ANDROID+unity3d的VR开发环境
一.下载最新unity3d(u3d官网) 二.下载最新cardboardsdkforunity(https://github.com/googlesamples/cardboard-unity) 三. ...
- bzoj 2561: 最小生成树【最小割】
看错题了以为多组询问吓得不行-- 其实还挺好想的,就是数据范围一点都不网络流.把U作为s,V作为t,以最小生成树为例,(U,V,L)要在最小生成树上,就要求所有边权比L小的边不能连通(U,V)所在的联 ...
- BZOJ 1001 [BeiJing2006]狼抓兔子 (UVA 1376 Animal Run)
1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec Memory Limit: 162 MBSubmit: 24727 Solved: 6276[Submit][ ...
- 【杂谈】小记一个ios11的bug
前段时间,除了apple发布了新的硬件之外,同步还发布了新的操作系统,IOS11,当大家都将注意力聚焦在那个奇怪的刘海该如何适配的时候,笔者的项目在适配IOS11却出现了其他的问题. 众所周知,IOS ...
- 数据结构 - 链栈的实行(C语言)
数据结构-链栈的实现 1 链栈的定义 现在来看看栈的链式存储结构,简称为链栈. 想想看栈只是栈顶来做插入和删除操作,栈顶放在链表的头部还是尾部呢?由于单链表有头指针,而栈顶指针也是必须的,那干吗不让它 ...
- 【洛谷4769】[NOI2018] 冒泡排序(动态规划_组合数学)
题目: 洛谷 4769 博客页面左下角的嘴嘴瓜封神之战中的题目 分析: 一个排列交换次数为 \(\frac{1}{2}\sum_{i=1}^{n}|i-p_i|\) 的充要条件是这个排列不存在长度为 ...
- JSON(2)JSONObject解析Josn和创建Jsonf示例
1.解析Json /* * test.josn内容如下: { "languages":[ {"id":"1","name" ...