浅谈重启删除型安全工具的编写
文/图 willy123 [小毅]
相信大家一定都有过这样的经历,删除一个文件时提示无法删除,这一般都是由于所删除的文件正在使用导致的(如果是在Unix/Linux下则可以删除正在运行的程序)。这时候很多新手都会一筹莫展,四处发贴询问如何解决,有点经验的老鸟都会推荐几款工具,如KillBox、PowerRmv等,一般都可以轻易解决问题,但不知道有没有人认真思考过这些工具为什么能有效地删除顽固程序呢?我们自己能不能也开发出类似的工具呢?
本文就想和大家简要探讨一下这类工具的实现原理并给出程序实例,希望对大家有所启发。我们先来测试看看这些工具有什么特点,用PowerRmv锁定无法删除的程序,点“杀灭”后,文件并没有被删除,反而弹出了一个对话框,如图1所示,提示目标正在被调用,但采用替换功能可以在下次电脑重启时自动删除锁定文件。再看看我们锁定的文件,其文件名已经被改成了“I am a trojan.dll.0DEL.VIR”,虽然还在运行,重启后却会发现文件的确被删除了。把PowerRmv用PEiD侦察一下,提示“Nullsoft PiMP Stub [Nullsoft PiMP SFX] *”,原来是Nullsoft installison打包的,下了个7z解压缩后一下子冒出了五个文件和一个文件夹,exe程序是VC编写的,简单跟了下,发现主要原理是在MoveFileEx这个API函数上做的文章。查阅MSDN,得到其定义如下。图1
BOOL MoveFileEx(
LPCTSTR lpExistingFileName, // file name
LPCTSTR lpNewFileName, // new file name
DWORD dwFlags // move options
);第一个参数是要操作的文件名,第二个参数是新文件名,最后一个参数决定是重启删除还是重命名。如果设置为MOVEFILE_DELAY_UNTIL_REBOOT就可以在重启时删除文件。这个函数虽然很简单,但作用却很大,简单的说,这个函数可以在系统里注册一个延迟删除或重命名的操作,并且在注册表“HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerPending FileRenameOperations”下修改键值,让操作系统在下一次启动,AutoChk运行后页面交换文件未建立前,将指定文件删除。操作系统再次启动的时候会调用smss.exe读取该键值并完成指定操作,这个时候Win32子系统并未启动,所以理论上可以替换删除Win32子系统下的程序。
OK,理论讲完了,下面我们来编程实践。这里我只简要分析一段最简单的代码。
Private Declare Function MoveFileEx Lib "kernel32" Alias "MoveFileExA" (ByVal lpExistingFileName As String, ByVal lpNewFileName As String, ByVal dwFlags As Long) As Long
Private Const MOVEFILE_DELAY_UNTIL_REBOOT = &H4
Private Const MOVEFILE_REPLACE_EXISTING = &H1
API声明
Dim res As Long
Res=MoveFileEx(Textpath.text, vbNullString, MOVEFILE_DELAY_UNTIL_REBOOT)
重启后强制删除文件,这里的第二个参数设置为空字符串表示使用删除,第三个文件表示重启后执行
If res <> 0 Then
Formtest.Caption ="执行重启删除成功"
Else: formtest.Caption = "执行重启删除失败"
End If 返回值不为空,说明操作成功
呵呵,很简单吧?可别高兴得太早,现在的木马病毒要是这么容易就被搞定了的话,那也太没有面子了不是。以一种很简单的进程守护技术来说吧,假设 A、B两个程序互相保护,你重启删除了A程序,却不小心漏了B程序,B程序开机运行时发现A程序不见了,哪会善罢甘休,立马释放一个A并运行之。如果是一个木马群呢?漏了一个,以前的所有努力可就白费了。那我们该怎么办呢?别急,山人自有妙计。如果你够仔细的话,会发现PowerRmv程序界面下还有个“是否抑制杀灭对象生成”的选项,勾选后,重启会发现原来的程序没有了,取而代之的是一个同名文件夹,妙!原来是通过建立同名文件夹来达到免疫目的的,那么我们的思路就清晰了。首先利用MoveFileEx函数对正在运行的程序重命名,如virus.exe这个程序,将其命名为 virusKill.exe,然后再建立一个名为virus.exe的同名文件夹,最后再利用MoveFileEx函数对virusKill.exe(注意这里是virusKill.exe而不是virus.exe)执行重启删除操作,这样重启删除程序并且免疫的目的就同时达到了。下面是核心代码片段(API声明同上)。
MoveFileEx Textpath.Text, Textpath.Text & "Kill", MOVEFILE_REPLACE_EXISTING
对正在运行的程序重命名
MkDir Textpath.Text
建立一个同名文件夹来抑制对象生成
MoveFileEx Textpath.Text&"Kill", vbNullString, MOVEFILE_DELAY_UNTIL_REBOOT 对重命名后的程序执行重启删除操作
在以上介绍的原理基础上,我编写了一个用来删除顽固文件的小工具并随文提供了,感兴趣的朋友可以自己改得更加强大,比如加入同时删除多个文件,删除文件前的备份等功能。其实很多貌似很高深的东西,自己琢磨琢磨就会发现原理其实很简单,关键还是看你够不够细心
补充:综合编程 , 安全编程 ,