自刪除(Self Deleting)最早的方法是由 Gary Nebbett 大蝦寫的,太經(jīng)典了,不能不提。程序如下:
#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 鉆了系統(tǒng)的一個漏洞,他的程序是關(guān)閉了 exe 文件的 IMAGE(硬編碼為4),然后用 UnmapViewOfFile 解除了 exe 文件在內(nèi)存中的映象,接著通過堆棧傳遞當(dāng)前程序的 Handle 給 DeleteFile() ,實現(xiàn)了程序的自刪除。
Gary Nebbett 果然不愧為 WIN 系統(tǒng)下頂尖的底層高手。那么是否還有其他的方法實現(xiàn)程序的自刪除呢?答案是肯定的。
在 Win9x/ME 下,還可以利用 WININIT.INI 的一些特性。在 WININIT.INI 文件里面有一個節(jié) [Rename] ,只要在里面寫入要 “Nul=要刪除的文件”,那么下次系統(tǒng)重新啟動的時候,該文件就會被自動刪除了。以下是一個例子:
[Rename]
NUL=c:SelfDelete.exe
利用這個特性,我們就可以在程序中對這個 ini 文件進行操作。值得注意的是,當(dāng)需要自刪除的文件多于一個的時候,就不能使用 WritePrivateProfileString 來實現(xiàn),因為這個 API 會阻止多于一個“NUL=”這樣的入口在同一個節(jié)里面出現(xiàn),所以最好還是自己手動實現(xiàn)。
第三種方法是利用批處理文件。先讓我們做一個試驗:
創(chuàng)建一個 a.bat ,給它寫入以下內(nèi)容:
del %0.bat
現(xiàn)在運行它吧,屏幕一閃而過,最后留下一串字符:“The batch file cannot be found”。這時候它已經(jīng)從你的硬盤中消失了。
這說明,批處理文件是可以刪除自己的,于是我們可以把這個小技巧運用在自己的程序當(dāng)中:
:Repeat
del "C:MYDIRSelfDelete.exe"
if exist "SelfDelete.exe" goto Repeat
rmdir "C:MYDIR"
del "DelUS.bat"
它會重復(fù)不斷地搜索是否有 SelfDelete.exe 這個文件,直到刪除了它為止;當(dāng)刪除完畢后,這個批處理文件就會把自己刪除。
(注:本方法可以支持所有的 Windows 版本,即 Win9x/Me/NT/2000/XP)
用批處理文件的方法有一個缺陷,就是會突然彈出一個 DOS 窗,冷不防的嚇人一跳,不過據(jù)我所知這是目前唯一可以在 WinXP 下起作用的方法。當(dāng)然,最理想的方法是用 Gary Nebbett 的那種,不過它的缺陷是沒法在 WinXP 下起作用。
(注:Gary Nebbett 的方法,hume已經(jīng)給出了例子,所以我就不重復(fù)了,請到他的網(wǎng)站 http://humeasm.yeah.net 下載。)
以上的方法都是前輩高人的研究總結(jié),可不是我原創(chuàng)的,不過最后我給出一個 Win32ASM 例子,演示一下用批處理文件刪除程序自身的方法。
;******************************************************
;程序名稱:程序自刪除示例,適用于Win9x/WinMe/Win2000/WinXP
;作者:羅聰
;日期:2002-10-23
;出處:http://www.luocong.com(老羅的繽紛天地)
;注意事項:如欲轉(zhuǎn)載,請保持本程序的完整,并注明:
;轉(zhuǎn)載自“老羅的繽紛天地”(http://www.luocong.com)
;******************************************************
.386
.model flat, stdcall
option casemap:none
include masm32includewindows.inc
include masm32includekernel32.inc
include masm32includeshell32.inc
include masm32includeuser32.inc
includelib masm32libuser32.lib
includelib masm32libkernel32.lib
includelib masm32libshell32.lib
DeleteExecutableBF PROTO
.code
main:
invoke DeleteExecutableBF
invoke ExitProcess, NULL
;********************************************
; 模塊功能:用批處理文件刪除自身
; 入口參數(shù):無
; 出口參數(shù):無
;********************************************
DeleteExecutableBF proc
LOCAL hFile

LOCAL len

LOCAL hHeap

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
; 創(chuàng)建一個批處理文件,用于刪除我們的exe文件。當(dāng)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 文件的內(nèi)容:
; :Repeat
; del "C:Win95ADGDelSelf.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
; 創(chuàng)建 bat 文件:
invoke lstrlen, pBatFile
mov len, eax
invoke WriteFile, hFile, pBatFile, len, addr len, NULL
invoke CloseHandle, hFile
; 現(xiàn)在在后臺執(zhí)行我們的 bat 文件:
invoke ShellExecute, NULL, addr szOpen, pszBatFilePathname, NULL, NULL, SW_HIDE
.endif
; 釋放堆:
invoke HeapFree, hHeap, NULL, pszUnsetupPath
return:
; 結(jié)束啦!
ret
DeleteExecutableBF endp
end main
;******************** over ********************
;by LC