• Windows——实现exe自删除


    作者:小 琛
    欢迎转载,请标明出处

    该博文给出两种exe自删的方法,需要的可自取

    进程优先级法(慎用)

    这是一种比较高端的方法,利用Windows底层的实现的cpu优先级调用实现的
    思想是:启动一个cmd进程,cmd进程执行删除操作;设置当前exe进程为最高优先级,新启动的cmd进程为低优先级,则exe进程一定会比cmd进程先结束,因此可以将exe进程删除掉

    下面给出一个例子

    void deleteOwnProcess() {
    	SHELLEXECUTEINFO sei;
    	TCHAR szModule[MAX_PATH], szComspec[MAX_PATH], szParams[MAX_PATH];
    	// Get its own file name Get the full path file name of CMD
    	if ((GetModuleFileName(0, szModule, MAX_PATH) != 0) &&
    		(GetShortPathName(szModule, szModule, MAX_PATH) != 0) &&
    		(GetEnvironmentVariable(L"COMSPEC", szComspec, MAX_PATH) != 0)) {
    		lstrcpy(szParams, L"/c del ");
    		lstrcat(szParams, L"\"");
    		lstrcat(szParams, szModule);
    		lstrcat(szParams, L"\"");
    		lstrcat(szParams, L" > nul");
    
    		sei.cbSize = sizeof(sei);
    		sei.hwnd = 0;
    		sei.lpVerb = L"Open";
    		sei.lpFile = szComspec;
    		sei.lpParameters = szParams;
    		sei.lpDirectory = 0; sei.nShow = SW_HIDE;
    		sei.fMask = SEE_MASK_NOCLOSEPROCESS;
    //----------------------------下面是核心--------------------------------------
    		if (ShellExecuteEx(&sei)) {
    			// Set the execution level of CMD process to idle execution
    			SetPriorityClass(sei.hProcess, NORMAL_PRIORITY_CLASS);
    			// Set the priority of its own process high
    			SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
    			SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
    			// Notify the windows resource 
    			SHChangeNotify(SHCNE_DELETE, SHCNF_PATH, szModule, 0);
    		} else {
    			MyLogger::Log::error("delete self error,open process unsuccessful");
    		}
    	} else {
    		MyLogger::Log::error("get environment variable error");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    代码的核心从if之后开始,注意:

    1. 这里设置新启动的进程为NORMAL_PRIORITY_CLASS很多网络上的例子都将该值设置为IDLE_PRIORITY_CLASS,这可能会导致当操作系统有普通进程一直在进行,该进程则一直会处于饥饿状态,操作系统对于优先级的判断:线程优先级+进程优先级,因此只要保证该进程优先级高于新进程即可
    2. 但这种把命运交给操作系统的方法,一定要吹毛求疵,还是有问题,例如:有一个比NORMAL_PRIORITY_CLASS高的进程还在执行,即使操作系统会因为永不饥饿原则(某进程一段时间没有获得cpu,则先执行它)而最终执行,但仍需3-4秒,这个时间对于一些软件是不可接受的
    3. 最后,对于我们这些没有将操作系统完全吃透的人,这种命运别人掌握的方法永远可能出现各种问题,我在做测试的时候就发现,某些时候就是删不掉,调试也发现不了问题,因此这种方法还是慎用比较好。

    .bat法(推荐)

    exe自删困难在于,运行的进程是无法进行清除工作的,但是.bat即脚本却可以做到自删除,因此我们可以利用这个特征,在exe结束前:

    1. open一个.bat文件
    2. 将清除工作的语句写入
    3. .bat内部,执行循环操作,判断待删除文件是否存在,若存在跳回第一步
    4. 当判断待删除文件不存在即被删除后,自删即可

    下面给出一个例子:

    void deleteOwnProcessBat() {
    	char buf[0xFF];
    	HMODULE hMod = GetModuleHandleA(NULL);
    	GetModuleFileNameA(hMod, buf, 0xFF);
    	PathStripPathA(buf);
    
    	std::fstream fileBat;
    	fileBat.open("selfDel.bat", std::ios::out); 
    	std::string data = std::string(":startExe\r\nif not exist ") + buf + " goto done\r\ndel /f /q " 
    		+ buf + "\r\ngoto startExe\r\n:done\r\ndel /f /q %0";
    	fileBat.write(data.data(), data.size());
    	fileBat.close();
    	auto ret = ShellExecuteA(NULL, "open", "selfDel.bat", NULL, NULL, SW_HIDE);
    	if ((INT_PTR)ret <= 32) {
    		MyLogger::Log::error("open bat error");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    代码解析:

    1. 首先获取当前exe的路径
    2. open一个bat,将语句写入,语句的逻辑是:第一步判断该程序的exe是否存在;第二步若存在则删除该exe,回退到第一步(为了防止exe没有退出导致删除失败);若不存在,到第三步,执行自删操作
    3. 启动一个新进程,来运行该脚本

    值得注意的是:该方法,一定要保证对应的exe会正常退出,否则该脚本则会死循环无法退出

  • 相关阅读:
    SpringCloud接入nacos配置中心
    解决cloudflare pages部署静态页面发生404错误的问题
    笔试强训第十九天 (最长公共子串+汽水瓶)
    搭载紫光展锐V510平台 移远通信RG500U-EA 5G模组获全球首个GCF认证
    《数字图像处理-OpenCV/Python》连载(44)图像的投影变换
    信创云:打造自主可控云基础设施 | 厂商征集
    FreeRTOS的学习(四)—— 信号量之间的优先级翻转问题和互斥信号量
    实用工具JRebel & XRebel【2023】配置和使用的详解
    大家都在用的福昕阅读器 foxit 你还不知道吗? 祛除水印&PDF转换&全功能解锁…
    AE-如何让一副静止的画变成动态图
  • 原文地址:https://blog.csdn.net/qq_44745063/article/details/126491227