Exe程序的自删除
下载本节例子程序和源代码
(3.16 KB)
程序的自删除已经不是什么新鲜的话题了,它广泛运用于木马、病毒中。试想想,当你的程序还在运行中(通常是完成了驻留、感染模块),它就自动地把自己从磁盘中删掉,这样一来,就做到了神不知鬼不觉,呵呵,是不是很cool呢?
自删除(Self Deleting)最早的方法是由 Gary Nebbett 大虾写的,太经典了,不能不提。程序如下:
#include
"windows.h"
int
main
(
int
argc
,
char
*
argv
[
]
)
{
char
buf
[
MAX_PATH
]
;
HMODULE module
;
module
=
GetModuleHandle
(
0
)
;
GetModuleFileName
(
module
,
buf
,
MAX_PATH
)
;
CloseHandle
(
(
HANDLE
)
4
)
;
__asm
{
lea eax
,
buf
push
0
push
0
push eax
push ExitProcess
push module
push DeleteFile
push UnmapViewOfFile
ret
}
return
0
;
}
试试编译它,运行。怎么样?从你的眼皮底下消失了吧?是不是很神奇?
Gary Nebbett 钻了系统的一个漏洞,他的程序是关闭了 exe 文件的 IMAGE(硬编码为4),然后用 UnmapViewOfFile 解除了 exe 文件在内存中的映象,接着通过堆栈传递当前程序的路径名缓冲区指针给 DeleteFile() ,实现了程序的自删除。
Gary Nebbett 果然不愧为 WIN 系统下顶尖的底层高手。那么是否还有其他的方法实现程序的自删除呢?答案是肯定的。
在 Win9x/ME 下,还可以利用 WININIT.INI 的一些特性。在 WININIT.INI 文件里面有一个节 [Rename] ,只要在里面写入要 “Nul=要删除的文件”,那么下次系统重新启动的时候,该文件就会被自动删除了。以下是一个例子:
[Rename]
NUL=c:\SelfDelete.exe
利用这个特性,我们就可以在程序中对这个 ini 文件进行操作。值得注意的是,当需要自删除的文件多于一个的时候,就不能使用 WritePrivateProfileString 来实现,因为这个 API 会阻止多于一个“NUL=”这样的入口在同一个节里面出现,所以最好还是自己手动实现。
第三种方法是利用批处理文件。先让我们做一个试验:
创建一个 a.bat ,给它写入以下内容:
del %0.bat
现在运行它吧,屏幕一闪而过,最后留下一串字符:“The batch file cannot be found”。这时候它已经从你的硬盘中消失了。
这说明,批处理文件是可以删除自己的,于是我们可以把这个小技巧运用在自己的程序当中:
:Repeat
del "C:\MYDIR\SelfDelete.exe"
if exist "SelfDelete.exe" goto Repeat
rmdir "C:\MYDIR"
del "\DelUS.bat"
它会重复不断地搜索是否有 SelfDelete.exe 这个文件,直到删除了它为止;当删除完毕后,这个批处理文件就会把自己删除。
(注:本方法可以支持所有的 Windows 版本,即 Win9x/Me/NT/2000/XP)
用批处理文件的方法有一个缺陷,就是会突然弹出一个 DOS 窗,冷不防的吓人一跳,不过据我所知这是目前唯一可以在 WinXP 下起作用的方法。当然,最理想的方法是用 Gary Nebbett 的那种,不过它的缺陷是没法在 WinXP 下起作用。
(注:Gary Nebbett 的方法,hume已经给出了例子,所以我就不重复了,请到他的网站
http://humeasm.yeah.net
下载。)
以上的方法都是前辈高人的研究总结,可不是我原创的,不过最后我给出一个 Win32ASM 例子,演示一下用批处理文件删除程序自身的方法。
;******************************************************
;程序名称:程序自删除示例,适用于Win9x/WinMe/Win2000/WinXP
;作者:罗聪
;日期:2002-10-23
;出处:http://www.luocong.com(老罗的缤纷天地)
;注意事项:如欲转载,请保持本程序的完整,并注明:
;转载自“老罗的缤纷天地”(http://www.luocong.com)
;******************************************************
.
386
.
model
flat
,
stdcall
option
casemap
:
none
include
\masm32\include\windows.inc
include
\masm32\include\kernel32.inc
include
\masm32\include\shell32.inc
include
\masm32\include\user32.inc
includelib
\masm32\lib\user32.lib
includelib
\masm32\lib\kernel32.lib
includelib
\masm32\lib\shell32.lib
DeleteExecutableBF
PROTO
.
code
main
:
invoke
DeleteExecutableBF
invoke
ExitProcess
,
NULL
;********************************************
; 模块功能:用批处理文件删除自身
; 入口参数:无
; 出口参数:无
;********************************************
DeleteExecutableBF
proc
LOCAL
hFile
:
DWORD
LOCAL
len
:
DWORD
LOCAL
hHeap
:
DWORD
LOCAL
pszUnsetupPathname
:
DWORD
LOCAL
pszUnsetupPath
:
DWORD
LOCAL
pszBatFilePathname
:
DWORD
LOCAL
pBatFile
:
DWORD
jmp
nextcode
szBatFileName
BYTE
"DelUS.bat"
,
0
szOpen
BYTE
"open"
,
0
szBKSlash
BYTE
"\"
,
0
L1
BYTE
":Repeat"
,
13
,
10
,
0
L2A
BYTE
"del """
,
0
L2B
BYTE
""""
,
0
L3A
BYTE
13
,
10
,
"if exist """
,
0
L3B
BYTE
""" goto Repeat"
,
13
,
10
,
0
L4
BYTE
"rmdir """
,
0
L5
BYTE
""""
,
13
,
10
,
"del """
,
0
L6
BYTE
""""
,
13
,
10
,
0
nextcode
:
; 为字符串分配堆:
invoke
GetProcessHeap
mov
hHeap
,
eax
invoke
HeapAlloc
,
hHeap
,
NULL
,
4
*
MAX_PATH
+
1000
mov
pszUnsetupPath
,
eax
add
eax
,
MAX_PATH
mov
pszUnsetupPath
,
eax
add
eax
,
MAX_PATH
mov
pszUnsetupPathname
,
eax
add
eax
,
MAX_PATH
mov
pszBatFilePathname
,
eax
add
eax
,
MAX_PATH
mov
pBatFile
,
eax
; 创建一个批处理文件,用于删除我们的exe文件。当exe文件被删除后,这个批处理文件会自动删除自己,以及它所在的目录。
; 得到 temp 目录的路径:
invoke
GetTempPath
,
MAX_PATH
,
pszBatFilePathname
invoke
lstrcat
,
pszBatFilePathname
,
addr
szBatFileName
invoke
CreateFile
,
pszBatFilePathname
,
GENERIC_WRITE
,
0
,
NULL
,
CREATE_ALWAYS
,
FILE_ATTRIBUTE_NORMAL
or
FILE_FLAG_SEQUENTIAL_SCAN
,
NULL
mov
hFile
,
eax
.
if
(
hFile
!
=
INVALID_HANDLE_VALUE
)
; 得到我们的 exe 文件的全路径(包括文件名):
invoke
GetModuleFileName
,
NULL
,
pszUnsetupPathname
,
MAX_PATH
; 得到我们的 exe 文件的路径(不包括文件名):
invoke
lstrcpy
,
pszUnsetupPath
,
pszUnsetupPathname
; 找到路径最后的 ’\’ 并把它改成0
mov
edx
,
pszUnsetupPath
mov
ecx
,
edx
.
repeat
mov
al
,
byte
ptr
[
edx
]
.
if
al
=
=
92
; "\"
mov
ecx
,
edx
.
endif
inc
edx
.
until
al
=
=
0
mov
byte
ptr
[
ecx
+
1
]
,
0
; Bat 文件的内容:
; :Repeat
; del "C:\Win95ADG\DelSelf.exe"
; if exist "DelSelf.exe" goto Repeat
; rmdir "C:\Win95ADG"
; del "c:\%temppath%\DelUS.bat"
invoke
lstrcat
,
pBatFile
,
addr
L1
invoke
lstrcat
,
pBatFile
,
addr
L2A
invoke
lstrcat
,
pBatFile
,
pszUnsetupPathname
invoke
lstrcat
,
pBatFile
,
addr
L2B
invoke
lstrcat
,
pBatFile
,
addr
L3A
invoke
lstrcat
,
pBatFile
,
pszUnsetupPathname
invoke
lstrcat
,
pBatFile
,
addr
L3B
invoke
lstrcat
,
pBatFile
,
addr
L4
invoke
lstrcat
,
pBatFile
,
pszUnsetupPath
invoke
lstrcat
,
pBatFile
,
addr
L5
invoke
lstrcat
,
pBatFile
,
pszBatFilePathname
invoke
lstrcat
,
pBatFile
,
addr
L6
; 创建 bat 文件:
invoke
lstrlen
,
pBatFile
mov
len
,
eax
invoke
WriteFile
,
hFile
,
pBatFile
,
len
,
addr
len
,
NULL
invoke
CloseHandle
,
hFile
; 现在在后台执行我们的 bat 文件:
invoke
ShellExecute
,
NULL
,
addr
szOpen
,
pszBatFilePathname
,
NULL
,
NULL
,
SW_HIDE
.
endif
; 释放堆:
invoke
HeapFree
,
hHeap
,
NULL
,
pszUnsetupPath
return
:
; 结束啦!
ret
DeleteExecutableBF
endp
end
main
;******************** over ********************
;by LC
老罗
2002-10-23
版权所有 转载请注明出处
Home
/
Index
罗聪