WinXP程序刪除自身的方法

    大家都知道,一般的程序運行的時候,可執行文件本身是被操作系統保護的,不能用改寫的方式訪問,更別提在本身還在運行的時侯刪除自己了。
    網上流傳了一些刪除自己的代碼,但基本上是在win9x的系統下才可行,2000/XP下這樣的代碼基本沒有,因爲window2000/XP對這方面進行修補。所以甚至有人放言,2000/XP(Ring3下)下不可能刪除自己(當然不是採取批處理,也不是機器重啓後刪除的辦法),真的是這樣嗎?沒有任何辦法嗎?筆者經過一段時間的研究,終於獲得瞭解決,方法是來自Windows編程的經典之作《Windows核心編程》的啓發。
    實現代碼難度不大,研習過《Windows核心編程》的讀者均可理解。基本方法是採用創建遠程線程的方法實現。首先爲explorer.exe創建遠程線程,來執行DeleteFile函數,程序自己立即退出,這時可執行文件已經不被操作系統保護,聯繫方式:[email protected]

    本程序全部源代碼如下:(win9x下無效,xp上運行成功)
// EXIT.cpp : Defines the entry point for the console application.
//
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>

//獲取explorer.exe進程的ID
DWORD GetWinProcessID()
{
    HANDLE hProcessSnap=NULL;
    PROCESSENTRY32 pe32={0};
    hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    if(hProcessSnap==INVALID_HANDLE_VALUE) return 0;
    pe32.dwSize=sizeof(PROCESSENTRY32);
    if(Process32First(hProcessSnap,&pe32))
    {
        MODULEENTRY32 me32={0};
        do
        {
   if(strcmp(pe32.szExeFile,"explorer.exe")==0)
   {
    CloseHandle(hProcessSnap);
    return pe32.th32ProcessID;
   }
        }
        while(Process32Next(hProcessSnap,&pe32));
    }
    CloseHandle(hProcessSnap);
    return 0;
}

//刪除文件
//dwProcessId --- 創建遠程線程的目標進程ID
//filename    --- 要刪除文件的完整文件名
void DeleteSelf(DWORD dwProcessId,char *filename)

 HANDLE hProcess=NULL,hThread=NULL;
 char *add=NULL;//爲目標進程分配的地址
 hProcess=OpenProcess(
  PROCESS_QUERY_INFORMATION |
  PROCESS_CREATE_THREAD     |   // 爲 CreateRemoteThread
  PROCESS_VM_OPERATION      |   // 爲 VirtualAllocEx/VirtualFreeEx
  PROCESS_VM_WRITE          ,   // 爲 WriteProcessMemory
  FALSE,dwProcessId);//打開進程
 int strnum=strlen(filename)+1;//文件名長度
 add=(char *)VirtualAllocEx(hProcess,NULL,strnum,MEM_COMMIT,PAGE_READWRITE);//爲將要寫入的文件名分配空間
 WriteProcessMemory(hProcess,add,(PVOID)filename,strnum,NULL);//將文件名寫入目標進程的地址空間
 PTHREAD_START_ROUTINE pfnThreadRtn=(PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")),"DeleteFileA");//獲得DeleteFileA函數的地址
 hThread=CreateRemoteThread(hProcess,NULL,0,pfnThreadRtn,add,0,NULL);//爲目標創建遠程線程 
 exit(0);//進程強制結束(既然已經結束,當然也無法釋放空間、關閉句柄了)
}

int main(int argc, char* argv[])
{
 DWORD WinID=GetWinProcessID();
 char filename[256];
 GetModuleFileName(NULL,filename,256);//獲取本可執行文件名
 DeleteSelf(WinID,filename);
 return 0;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章