如何讓exe自己刪除自己??

我們都知道,當一個exe程序在啓動之後,操作系統會把這個可執行文件加載到內存中去,在程序處於運行狀態時,如果我們想要把這個文件刪除,那就會出現以下情況:
在這裏插入圖片描述
那我們將不得不等到程序執行完畢之後,手動的來刪除這個文件,但是有沒有一種辦法可以直接在程序退出的時候,就自動刪除這個可執行文件呢??
加入我們想要用我們的程序做一些“壞事”,比如說是我們要實現一個IATHook,我們需要一個啓動進程,在目標進程地址空間中申請空間,進而實現dll的注入,啓動dll。
當我們的啓動進程完成對目標進程的注入這些事情之後,能不能功成身退,拂袖而去,不帶走一片雲彩呢?
請收看小白先生今日測試血淚史:
我前兩天還寫了啓動進程的各種方法,今日果然用到了,大體思路就是:

  • 填充SHELLEXECUTEINFO結構體的各個字段
  • 調用ShellExecuteEx啓動進程
  • 調用SetPriorityClass設置進程優先級
  • 調用SetThreadPriority設置當前線程優先級
  • 調用SHChangeNotify通知Windows資源管理器
  • 完成工作

但是我在測試的過程中,碰了一鼻子灰,運行之後出現了以下情況:
在這裏插入圖片描述
看似刪除成功了,刷新文件夾之後,灰太狼又回來了??
在這裏插入圖片描述
因爲我啓動cmd隱藏刪除該文件,網上查找資料之後,說是cmd要刪除的文件必須是未被佔用的,當我的程序執行完自殺函數之後,我的主程序並沒有退出,當一個運行中的應用程序被刪除之後,操作系統會自動重建,所以會出現上面那種情況。導致主程序沒有被真正刪除,只是SHChangeNotify通知資源管理器,說我把文件刪除了,纔會出現假刪除現象。。
測試到這裏的時候,居然還有點小小的激動,感覺自己的Demo像一個流氓軟件一樣,刪也刪不掉,hhhhhh。
自動重建這個現象同樣也會發生在dll身上,我之後也測試了將dll自刪除,發現那是根本不可能的,因爲dll已經被目標程序加載,如果自己刪除自己,還是會重建。
解決辦法:將getchar()那句攔截代碼刪除掉,這樣在代碼中設置的優先級纔有意義嘛。。。我可真是夠蠢的,一開始在代碼中設置優先級,就是爲了主程序完美退出之後,再去執行cmd程序。。
下面附上最終測試結果:
在這裏插入圖片描述
運行之後,程序閃退,然後就被刪除了。。
我這個測試只是一個簡單的測試,我也在自己的IATHook的啓動程序中測試了,沒有什麼問題,可以直接刪除啓動程序,不帶走任何一片雲彩!
附上測試源碼:

//.h
#pragma once
#include<iostream>
#include<Windows.h>
#include<tchar.h>
using namespace std;


BOOL SelfDelete();
//cpp
#include"Demo.h"
#include<Shlobj.h>//SHChangeNotify使用

void _tmain()
{
	
	printf("Current Process Id:%d\r\n", GetCurrentProcessId());

	if (SelfDelete())
	{
		printf("Success\r\n");
	}
}
BOOL SelfDelete()
{
	SHELLEXECUTEINFO ShellExecuteInfo;
	TCHAR ModuleName[MAX_PATH], CmdPath[MAX_PATH], Paramdters[MAX_PATH];

	// 獲得文件名.
	if ((GetModuleFileName(0, ModuleName, MAX_PATH) != 0) &&
		(GetShortPathName(ModuleName, ModuleName, MAX_PATH) != 0) &&
		(GetEnvironmentVariable("COMSPEC", CmdPath, MAX_PATH) != 0))
	{
		// 設置命令參數.
		lstrcpy(Paramdters, "/c del ");
		lstrcat(Paramdters, ModuleName);
		lstrcat(Paramdters, " > nul");

		// 設置結構成員.
		ShellExecuteInfo.cbSize = sizeof(ShellExecuteInfo);
		ShellExecuteInfo.hwnd = 0;
		ShellExecuteInfo.lpVerb = "Open";
		ShellExecuteInfo.lpFile = CmdPath;
		ShellExecuteInfo.lpParameters = Paramdters;
		ShellExecuteInfo.lpDirectory = 0;
		ShellExecuteInfo.nShow = SW_HIDE;
		ShellExecuteInfo.fMask = SEE_MASK_NOCLOSEPROCESS;

		// 執行shell命令.
		if (ShellExecuteEx(&ShellExecuteInfo))
		{
			//設置命令行進程的執行級別爲空閒執行,使本程序有足夠的時間從內存中退出. 
			SetPriorityClass(ShellExecuteInfo.hProcess, IDLE_PRIORITY_CLASS);
			//設置當前進程爲實時進程
			SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
			SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);

			//通知Windows資源瀏覽器,本程序文件已經被刪除.相當於一個刷新文件夾的作用
			SHChangeNotify(SHCNE_DELETE, SHCNF_PATH, ModuleName, 0);
			return TRUE;
		}
	}
	return FALSE;
}

今天正好是母親節,祝我親愛的媽媽節日快樂,身體健康!祝福全天下的母親永遠年輕快樂,身體健康!

“生活像一把無情刻刀,改變了我們模樣。”–老男孩
參考書籍:
《Windows應用程序捆綁核心》

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