程序自删除方法大总结
程序自刪除方法大總結(jié)
程序的自刪除早已經(jīng)不是什么新鮮的話題了,對(duì)于各位大蝦來(lái)說(shuō)是更是比較容易的事情,但想想自己剛學(xué)時(shí)遇到的種種錯(cuò)誤,我覺(jué)得有必要把自己所知道的各種方法總結(jié)一下,希望對(duì)新手的學(xué)習(xí)能夠有所幫助。
程序的自刪除廣泛用于反安裝程序最后的自刪除(環(huán)保呀!),當(dāng)然更多見于木馬、病毒首次安裝的自動(dòng)銷毀^*^,至于用于何種用途就看你自己啦!
經(jīng)典自刪除
說(shuō)到程序的自刪除就不能不說(shuō)由 Gary Nebbett 等大蝦所寫的代碼,經(jīng)典之作呀!代碼采用C語(yǔ)言內(nèi)嵌匯編asm:
在Win9x下只要先對(duì)exe本身句柄執(zhí)行FreeLibrary操作即可解除exe IMAGE在內(nèi)存的映射,隨后就可以通過(guò)調(diào)用DeleteFile來(lái)刪除自身文件。
Win9x下的代碼如下[selfkill-9x.c]:
#include "windows.h"
int main(int argc, char *argv[])
{
char buf[MAX_PATH];
HMODULE module;
module = GetModuleHandle(0);
GetModuleFileName(module, buf, MAX_PATH);
__asm
{
lea eax, buf
push 0
push 0
push eax
push ExitProcess
push module
push DeleteFile
push FreeLibrary
ret
}
return 0;
}
在WinNT/2K下則需要先調(diào)用CloseHandle關(guān)閉exe文件本身對(duì)應(yīng)的IMAGE的句柄HANDLE[硬編碼為4],然后調(diào)用UnmapViewOfFile解除了另外一個(gè)對(duì)應(yīng)IMAGE的HANDLE,并且解除了程序本身在內(nèi)存的映射對(duì)象,最后就可以用DeleteFile刪除自身啦!(注意:本方法不適用于WinXP!)
WinNT/2K下的代碼如下[selfkill-nt.c]:
#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;
}
把上面用于Win9x及WinNT/2K下的代碼綜合起來(lái),即把兩種平臺(tái)用到的API代碼全部執(zhí)行一遍,雖然在一種平臺(tái)上可能會(huì)有幾個(gè)API運(yùn)行失敗,有幾個(gè)API會(huì)運(yùn)行成功,但最后的結(jié)果exe程序文件在退出前就刪除了自身!
Win9x和WinNT/2K下的代碼如下[selfkill-9x+nt.c]:
#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 module
push UnmapViewOfFile
push FreeLibrary
ret
}
return 0;
}
因?yàn)槲易约涸趯W(xué)習(xí)Win32下的匯編[MASM32],所以重新用匯編寫了一遍,但結(jié)果卻發(fā)現(xiàn)每次都執(zhí)行失敗,顯示如圖一的錯(cuò)誤,
=========== 在此插入圖一 ==============
通過(guò)反匯編比較發(fā)現(xiàn)原來(lái)由于MASM32編譯器對(duì)API調(diào)用的編碼和C編譯器的不同,導(dǎo)致使用FreeLibrary或UnmapViewOfFile解除程序在內(nèi)存的映射后,調(diào)用DeleteFile時(shí)又引用IMAGE映射地址內(nèi)的代碼[JMP DeleteFile],導(dǎo)致讀內(nèi)存執(zhí)行錯(cuò)誤。
錯(cuò)誤分析
普通程序進(jìn)行API調(diào)用時(shí),編譯器會(huì)將一個(gè)API調(diào)用語(yǔ)句編譯為幾個(gè)參數(shù)壓棧指令后跟一條間接調(diào)用語(yǔ)句(這是指Microsoft編譯器,Borland編譯器使用JMP DWORD PTR [XXXXXXXXh])形式如下:
push arg1
push arg2
……
call dword ptr[XXXXXXXXh]
地址XXXXXXXXh在程序映像的導(dǎo)入(Import Section)段中,當(dāng)程序被加載運(yùn)行時(shí),由裝入器負(fù)責(zé)向里面添入API函數(shù)的地址;
一:用MASM32編譯的程序其API函數(shù)調(diào)用格式為:
Call capi;
……
……
……
capi:
jmp dword ptr[XXXXXXXX];XXXXXXXX中存放著所調(diào)用的API函數(shù)真正地址
其中jmp dword ptr[XXXXXXXX]指令是由“編譯器”在程序所有代碼的后面自動(dòng)加上的這樣調(diào)用的好處是當(dāng)多次調(diào)用同一API時(shí)可以減少代碼體積,〈呵呵:)個(gè)人觀點(diǎn)!〉
二:用C編譯的程序其API函數(shù)調(diào)用格式為:
Call dword ptr [XXXXXXXX];XXXXXXXX地址中存放著所調(diào)用的API函數(shù)真正地址
正是由于上面API函數(shù)調(diào)用格式不同導(dǎo)致用MASM32編譯的程序自刪除失敗,因?yàn)楫?dāng)調(diào)用UnmapViewOfFile后其中代碼段的jmp dword ptr[XXXXXXXX]指令所處的代碼節(jié)變成了不可讀,后面的DeleteFile這個(gè)API的執(zhí)行就會(huì)失敗,程序出錯(cuò)!所以我們?nèi)绻肕ASM32編譯這種自刪除程序時(shí),應(yīng)該把push DeleteFile指令改為:
mov eax,DeleteFile
;取jmp dword ptr[XXXXXXXX]指令地址,機(jī)器碼FF25XXXXXXXX
inc eax
inc eax
mov eax,dword ptr[eax]
push dword ptr[eax]
這樣才是把DeleteFile的真正地址放入堆棧,當(dāng)然用動(dòng)態(tài)獲取API也行,但不如這樣代碼少,下面是我改好的MASM32代碼[selfkill9x-nt.asm]:
.386
.model flat, stdcall
option casemap :none
include windows.inc
include kernel32.inc
includelib kernel32.lib
.code
start:
mov ebp, esp
invoke GetModuleHandle,NULL ;獲取自身模塊句柄
mov ebx,eax
invoke GetModuleFileName,ebx,ebp,MAX_PATH ;獲取自身路徑
invoke CloseHandle,4 ;關(guān)閉exe文件本身對(duì)應(yīng)的IMAGE的句柄[硬編碼為4]
push 0;ExitProcess的參數(shù)
push 0
push ebp;DeleteFile的參數(shù)
mov eax,ExitProcess
inc eax
inc eax
mov eax,dword ptr[eax]
push dword ptr[eax];pushExitProcess
push ebx;UnmapViewOfFile的參數(shù)
mov eax,DeleteFile
inc eax
inc eax
mov eax,dword ptr[eax]
push dword ptr[eax];pushDeleteFile
push ebx;FreeLibrary的參數(shù)
mov eax,UnmapViewOfFile
inc eax
inc eax
mov eax,dword ptr[eax]
push dword ptr[eax];pushUnmapViewOfFile
push FreeLibrary;FreeLibrary不用改因?yàn)檎{(diào)用它時(shí)代碼節(jié)還可以讀
ret
endstart
遠(yuǎn)程線程插入自刪除
遠(yuǎn)程線程插入如今廣泛用于木馬和病毒的自我保護(hù)及隱蔽自身,同樣我們也可以把它用在程序的自刪除。
其中所插入的刪除自身的遠(yuǎn)程線程的代碼如下:
KREMOTE_CODE_START equ this byte
call @F
@@:
pop ebx
sub ebx,offset @B ;線程代碼重定位
push 500
call [ebx+_lpselfkillSleep] ;休眠0.5秒
lea eax,[ebx+offset _selfkillselfname]
push eax
call [ebx+_lpselfkillDeleteFile] ;刪除程序文件
ret
_lpselfkillSleep dd?; Sleep的硬編碼地址
_lpselfkillDeleteFile dd?; DeleteFile的硬編碼地址
_selfkillselfname: ; 程序自身文件名,主程序內(nèi)生成寫入
KREMOTE_CODE_END equ this byte
KREMOTE_CODE_LENGTH equ offset KREMOTE_CODE_END - offset KREMOTE_CODE_START
主程序中使用GetProcAddress來(lái)獲取Sleep和DeleteFile的硬編碼地址后寫入上面,并用GetModuleFileName獲取自身路徑存入_selfkillselfname處,供遠(yuǎn)程線程使用。
Win9x下的用于在KERNEL32.DLL中建立遠(yuǎn)程線程代碼如下:
Kernel32 db"KERNEL32.DLL",0
SzCreateKernelThread db 'CreateKernelThread',0
_RemoteCode9Xproc@_RmCodeStart,@_RmCodeLen
local lpThreadID
local lpCreateKernelThread
local hProcess
invoke GetModuleHandle,addr Kernel32
mov ebx,eax
invoke GetProcAddress,ebx,offset szCreateKernelThread
mov lpCreateKernelThread,eax ;取得CreateKernelThread的地址
; _findProcess是一個(gè)根據(jù)名稱查找進(jìn)程PID的函數(shù)過(guò)程,詳細(xì)代碼見[selfkill-R9x.asm]
invoke _findProcess,offset Kernel32 ;查找KERNEL32.DLL進(jìn)程
.if eax
invoke OpenProcess,PROCESS_ALL_ACCESS,TRUE,eax
mov hProcess,eax
invoke WriteProcessMemory,eax,80001100h,@_RmCodeStart,@_RmCodeLen,NULL
.if eax
xor eax,eax
lea ecx,lpThreadID
push ecx
push eax
push eax
push 80001100h
push eax
push eax
call lpCreateKernelThread ;創(chuàng)建KERNEL32.DLL線程
.endif
invokeCloseHandle,hProcess
.endif
ret
_RemoteCode9Xendp
函數(shù)的調(diào)用格式為:
push KREMOTE_CODE_LENGTH+MAX_PATH ;代碼長(zhǎng)度
push offset REMOTE_CODE ;代碼地址
call _RemoteCode9X
[注意:這里不使用
invoke _RemoteCode9X,offset REMOTE_CODE,KREMOTE_CODE_LENGTH+MAX_PATH
來(lái)調(diào)用函數(shù),因?yàn)槲覝y(cè)試時(shí)發(fā)現(xiàn)invoke調(diào)用會(huì)使KREMOTE_CODE_LENGTH+MAX_PATH的值變大!也許是編譯器的一個(gè)BUG?]
在_RemoteCode9X中首先使用GetProcAddress獲得CreateKernelThread這個(gè)用于在KERNEL32.DLL中建立遠(yuǎn)程線程的API地址[CreateKernelThread的參數(shù)和CreateThread類似,但有一點(diǎn)不同為lpStartAddress參數(shù)(線程開始執(zhí)行的地址)處于KERNEL32.DLL進(jìn)程中!],然后調(diào)用_findProcess過(guò)程查找KERNEL32.DLL進(jìn)程的PID,隨后以全部的權(quán)限打開此進(jìn)程,并用WriteProcessMemory把代碼寫入到KERNEL32.DLL進(jìn)程80001100h開始的空間內(nèi)[之所以選擇80001100h是因?yàn)榇颂幱写蠖慰赡芪词褂玫脙?nèi)存00h,這樣就不用像中國(guó)黑客那樣進(jìn)入0環(huán)啦!],最后調(diào)用CreateKernelThread創(chuàng)建KERNEL32.DLL線程來(lái)刪除自身!(Win9x下的遠(yuǎn)程線程插入自刪除完整代碼見selfkill-R9x.asm!)
Win2K/XP下的用于建立遠(yuǎn)程線程的代碼如下:
;用于在explorer.exe進(jìn)程中插入遠(yuǎn)程線程
szDesktopClassdb'Progman',0
szDesktopWindowdb'Program Manager',0
_RemoteCode2KXPproc @_RmCodeStart,@_RmCodeLen
local @hRmCodeMemory
local @hselfkillProcessID
local @hselfkillProcess
;查找文件管理器窗口并獲取進(jìn)程ID,然后打開進(jìn)程
invoke FindWindow,addr szDesktopClass , addr szDesktopWindow
lea ecx , @hselfkillProcessID
invoke GetWindowThreadProcessId , eax,ecx
invoke OpenProcess, PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or PROCESS_VM_WRITE , FALSE , @hselfkillProcessID
mov @hselfkillProcess , eax
;在進(jìn)程中分配空間并將寫入遠(yuǎn)程代碼,建立遠(yuǎn)程線程
invoke VirtualAllocEx , @hselfkillProcess , NULL , @_RmCodeLen , MEM_COMMIT , PAGE_EXECUTE_READWRITE
.ifeax
mov@hRmCodeMemory,eax
invoke WriteProcessMemory,@hselfkillProcess,eax,@_RmCodeStart,@_RmCodeLen,NULL
xor eax,eax
invokeCreateRemoteThread,@hselfkillProcess,eax,eax,@hRmCodeMemory,eax,eax,eax
invokeCloseHandle,eax
.endif
invokeCloseHandle,@hselfkillProcess
ret
_RemoteCode2KXPendp
函數(shù)的調(diào)用格式和_RemoteCode9X相同!
上面的函數(shù)_RemoteCode2KXP首先調(diào)用FindWindow和GetWindowThreadProcessId來(lái)獲得explorer.exe進(jìn)程的PID,然后用OpenProcess以允許寫其內(nèi)存和建立遠(yuǎn)程線程的權(quán)限打開進(jìn)程,隨后調(diào)用VirtualAllocEx、WriteProcessMemory在explorer.exe申請(qǐng)內(nèi)存寫入代碼,最后使用CreateRemoteThread建立遠(yuǎn)程線程并運(yùn)行。(Win2K/XP下的遠(yuǎn)程線程插入自刪除完整代碼見selfkill-Rnt.asm!)
批處理文件的自刪除
我們知道在批處理文件中可以使用 %x來(lái)獲取傳遞給批處理的參數(shù),而%0獲得的則是自身的路徑,用del %0就可以刪除實(shí)現(xiàn)批處理文件的自刪除。
我們可以把這個(gè)小技巧運(yùn)用在自己的程序當(dāng)中,程序中調(diào)用批處理文件刪除自身,達(dá)到自刪除的目的。
生成的相應(yīng)的批處理文件如下:
@echo off
:selfkill
attrib -a -r -s -h "c:/selfkill-bat.exe"
del "c:/selfkill-bat.exe"
if exist "c:/selfkill-bat.exe" goto selfkill
del %0
我對(duì)其進(jìn)行了修改,首先用@echo off來(lái)關(guān)閉輸出信息,這樣可以使批處理文件運(yùn)行完后的DOS窗口自動(dòng)關(guān)閉,然后使用attrib修改文件屬性,防止自身是只讀、隱藏、系統(tǒng)屬性時(shí),無(wú)法使用批處理來(lái)刪除,程序名稱使用雙引號(hào)引起來(lái),防止路徑中有空格出現(xiàn)。[用批處理文件刪除程序自身示例代碼見selfkill-bat.asm]
示例中在固定位置生成的批處理文件“c:/Autoexce.bat”,而不在當(dāng)前目錄生成,是為了防止自身所在目錄路徑中包含空格,導(dǎo)致批處理無(wú)法運(yùn)行,生成批處理后使用WinExec隱蔽運(yùn)行,不顯示DOS 窗口。
DOS虛擬機(jī)下的自刪除
這個(gè)方法乃好友“抑郁天使”所提供的(感謝!),代碼如下:
#include <stdio.h>
int main(int argc,char *argv[])
{
unlink(argv[0]);
return 0;
}
unlink相信學(xué) C語(yǔ)言的朋友比較熟悉吧,就是刪除指定文件,使用TC2.0把上面代碼編譯為dos下16位的程序,執(zhí)行看看,是不是在閃出一個(gè)dos 窗口后,程序不見啦?!
我們?cè)侔焉厦娴某绦蚋膶懸幌?#xff0c;使其可以接受參數(shù):
#include <stdio.h>
int main(int argc,char *argv[])
{
sleep(1); //休眠1秒
if(argc==2)
unlink(argv[1]); //刪除程序(參數(shù)一)
unlink(argv[0]); //刪除自身
return 0;
}
通過(guò)對(duì)其反匯編分析,結(jié)合測(cè)試,這個(gè)自刪除的原因應(yīng)該為DOS下的程序在Windows下是通過(guò)虛擬機(jī)執(zhí)行[Win2000下為16位MS-DOS子系統(tǒng)(NTVDM CPU)ntvdm.exe,Win98下應(yīng)該是Winoa386.mod]的,而當(dāng)DOS程序在虛擬機(jī)下執(zhí)行時(shí),因?yàn)橐驯惶摂M機(jī)讀入內(nèi)存,也相當(dāng)于是解釋執(zhí)行的(類似腳本的執(zhí)行),所以當(dāng)DOS程序加載后系統(tǒng)并沒(méi)有對(duì)其進(jìn)行保護(hù),所以可以在執(zhí)行中被刪除,你可以用如下方法來(lái)驗(yàn)證!
使用DEBUG建立一個(gè)死循環(huán)的DOS下的COM程序,命令如下:
debug
-a
0B22:0100 jmp 100
0B22:0102
-r cx
CX 0000
:02
-n dos16.com
-w
Writing 00002 bytes
-q
運(yùn)行生成的dos16.com,會(huì)產(chǎn)生一個(gè)DOS窗口,你手工刪除dos16.com下,成功沒(méi)?^*^
上面的C代碼生成的程序太大,用起來(lái)麻煩,給你來(lái)個(gè)匯編的,同樣采用DEBUG生成:
-a
0B22:0100 mov si,120
0B22:0103 mov dx,si
0B22:0105 mov ax,4301
0B22:0108 xor cx,cx
0B22:010A int 21
0B22:010C mov ah,41
0B22:010E int 21
0B22:0110 cmp al,5
0B22:0112 je 103
0B22:0114 lodsb
0B22:0115 or al,al
0B22:0117 jne 114
0B22:0119 cmp byte ptr [si],0
0B22:011C jne 103
0B22:011E int 20
0B22:0120 db 'kill.com',0
0B22:0129 db 'selfkill.exe',0,0
0B22:0137
-r cx
CX 0000
:37
-n kill.com
-w
Writing 00037 bytes
-q
上面代碼就是調(diào)用DOS中斷INT 21 的41號(hào)功能刪除自身的,至于Windows下的應(yīng)用程序如何使用此方法刪除自身的完整代碼見[selfkill-dos.asm]文件,和批處理的利用方式一樣以隱蔽運(yùn)行方式調(diào)用!
腳本自刪除
歡樂(lè)時(shí)光的泛濫,想必很多人對(duì)于VBS腳本有所了解啦,由于腳本是解釋執(zhí)行的,所以在運(yùn)行時(shí)可以被刪除,也就是說(shuō)腳本文件刪除自身后不影響后面的代碼執(zhí)行。
我們來(lái)做個(gè)實(shí)驗(yàn),把下面的腳本保存為selfkill.vbs或selfkill.vbe:
Set fso = CreateObject("Scripting.FileSystemObject")
f = fso.DeleteFile(WScript.ScriptName)
WScript.Echo( WScript.ScriptName)
然后運(yùn)行它,是不是發(fā)現(xiàn)selfkill.vbs神奇的消失啦?而后面的對(duì)話框卻被正常顯示出來(lái)噢^*^
上面的腳本調(diào)用FSO控件,使用WSH中Wscript對(duì)象得ScriptName屬性,得到腳本自身的文件名,并調(diào)用FSO的DeleteFile方法刪除自身!
把它稍微改寫一下:
On Error Resume Next '防止出現(xiàn)錯(cuò)誤
Set fso = CreateObject("Scripting.FileSystemObject")
WScript.Sleep 1000 '將腳本執(zhí)行掛起1秒
fso.DeleteFile(WScript.ScriptName) '刪除腳本自身
If fso.FileExists("c:/selfkill.exe") Then fso.DeleteFile("c:/selfkill.exe") '刪除程序
程序就可以動(dòng)態(tài)生成VBS自刪除腳本,并調(diào)用它刪除自身啦,方法同樣和批處理文件的自刪除相似!需要說(shuō)明的是由于病毒及蠕蟲對(duì)腳本的濫用,腳本刪除文件時(shí)可能會(huì)被被誤認(rèn)為惡意代碼!
[附自刪除js腳本:
try{fso = new ActiveXObject("Scripting.FileSystemObject");
WScript.Sleep(1000);//休眠1秒
fso.DeleteFile(WScript.ScriptName);//刪除腳本自身
fso.DeleteFile("c:/selfkill.exe");//刪除程序
}catch(e){}
]
當(dāng)然還有wsf腳本文件,和上面的基本上是一樣的!
特殊方式打開文件自刪除
這個(gè)方法我只在Win2000下當(dāng)文件處于FAT32(FAT)格式的分區(qū)時(shí)成功刪除,在NTFS分區(qū)下并不能成功刪除,不知是何原因,所以這個(gè)方法也許利用價(jià)值很低,但既然寫總結(jié),就一并稍微提一下。
代碼如下:
[自刪除.asm]
.386
.model flat, stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
.code
rdb"selfkill.exe",0
main:
;以FILE_FLAG_DELETE_ON_CLOSE方式打開selfkill.exe
invoke CreateFile,addr r,GENERIC_READ,FILE_SHARE_READ OR FILE_SHARE_WRITE , 0 , OPEN_EXISTING , FILE_FLAG_DELETE_ON_CLOSE,0
movesi,eax
invokeWinExec,addr r,1 ;運(yùn)行selfkill.exe
invokeSleep,500
invokeCloseHandle,esi
invoke ExitProcess, NULL
end main
[selfkill.asm]
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
.code
delexedb'自刪除.exe',0
start:
invokeSleep,1500
invokeDeleteFile,offset delexe
invokeMessageBox,NULL,offset delexe,offset delexe,MB_OK
invokeExitProcess,NULL
endstart
首先在“自刪除.asm”中使用CreateFile以FILE_FLAG_DELETE_ON_CLOSE(文件被關(guān)閉后立即被系統(tǒng)自動(dòng)刪除)方式打開selfkill.exe文件,然后運(yùn)行selfkill.exe,休眠0.5秒后關(guān)閉文件(也就是刪除selfkill.exe),在“selfkill.asm”中首先休眠1.5秒,然后刪除“自刪除.exe”。
文件編譯后,在Win2000下FAT分區(qū)內(nèi)運(yùn)行“自刪除.exe”,你會(huì)發(fā)現(xiàn)兩個(gè)文件全部被自動(dòng)刪除,而對(duì)話框卻仍然被正常顯示出來(lái)!
重起系統(tǒng)后自刪除
上面所說(shuō)的方法,都是運(yùn)行中就把程序直接刪除,并不需要重起系統(tǒng),程序自刪除還有下面重起系統(tǒng)后刪除自身的幾種方法。
一:WININIT.INI 自刪除
利用 WININIT.INI 的一些特性,在 WININIT.INI 文件里面有一個(gè)節(jié) [Rename] ,只要在里面寫入要 “Nul=要?jiǎng)h除的文件”,那么下次系統(tǒng)重新啟動(dòng)的時(shí)候,該文件就會(huì)被自動(dòng)刪除了,且Wininit.ini在每次被系統(tǒng)執(zhí)行完它其中的命令時(shí)就會(huì)被系統(tǒng)自動(dòng)刪除。以下是一個(gè)Wininit.ini例子:
[rename]
nul=c:/Selfkill.exe
利用這個(gè)特性,我們就可以在程序中用WritePrivateProfileString 對(duì)這個(gè) ini 文件進(jìn)行操作,實(shí)現(xiàn)重起后刪除自身。
二:文件移動(dòng)自刪除
在NT下,文件移動(dòng)API 函數(shù)MoveFileEx,當(dāng)移動(dòng)標(biāo)志指定為參數(shù)MOVEFILE_DELAY_UNTIL_REBOOT,目標(biāo)文件為空的情況下,下次啟動(dòng)系統(tǒng)是會(huì)刪除指定文件!代碼如下:
.386
.model flat, stdcall
option casemap :none
include windows.inc
include kernel32.inc
includelib kernel32.lib
.data?
selfname db MAX_PATH dup(?)
.code
start:
invoke GetModuleFileName,NULL,addr selfname,MAX_PATH
;下次啟動(dòng)時(shí)刪除自身
invoke MoveFileEx,addr selfname,NULL,MOVEFILE_DELAY_UNTIL_REBOOT
invoke ExitProcess,NULL
endstart
通過(guò)監(jiān)測(cè),發(fā)現(xiàn)當(dāng)MoveFileEx以MOVEFILE_DELAY_UNTIL_REBOOT方式運(yùn)行時(shí),會(huì)在注冊(cè)表中建立如下鍵值:
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Session Manager
"PendingFileRenameOperations"=hex(7):5c,00,3f,00,3f,00,5c,00,43,00,3a,00,5c,00,/
73,00,65,00,6c,00,66,00,6b,00,69,00,6c,00,6c,00,2e,00,65,00,78,00,65,00,00,/
00,00,00,00,00
PendingFileRenameOperations鍵值類型為REG_MULTI_SZ,在注冊(cè)表編輯器中值顯示為:/??/c:/selfkill.exe,是Unicode編碼格式。
直接讀寫硬盤自刪除
我們知道一般來(lái)說(shuō)刪除文件僅僅是把文件分配表(File Allocation Table)中被刪除文件的名稱改,
DIR(Directory 根目錄區(qū))
DIR位于第二個(gè)FAT表之后,記錄著根目錄下每個(gè)文件(目錄)的起始單元,文件的屬性等。定位文件位置時(shí),操作系統(tǒng)根據(jù)DIR中的起始單元,結(jié)合FAT表就可以知道文件在硬盤中的具體位置和大小了。
在NT和2000下,通過(guò)CreateFile來(lái)打開需要讀寫的驅(qū)動(dòng)器,ReadFile、WriteFile來(lái)進(jìn)行磁盤讀寫。
CreateFile(".//A:",
GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
眾所周知windows有FAT12,FAT16,FAT32,NTFS等文件格式,而FAT12,FAT16,FAT32文件格式可看作一類,簡(jiǎn)稱FAT格式,而NTFS文件格式又可看作一類
'//./vwin32''//./PHYSICALDRIVE0'
總結(jié)
以上是生活随笔為你收集整理的程序自删除方法大总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 你真的了解Python吗?这篇文章可以让
- 下一篇: Scikit-Learn 与 Tenso