watermelon 发表于 2018-6-7 15:53:09

自删除EXE程序

之前小弟在网上查看论坛的时候,发现了一个帖子,是一个exe程序的运行完成后的自己删除,感觉佷感兴趣,于是想自己来写一个调用WindowsAPI和用C语言写的这个程序

我们知道Windows中当有文件处于运行状态下的时候是不能被删除的,那么一个exe程序怎么删除自己呢?

一般exe自我删除程序有很多用途,比如常见的软件的安装包,在安装完成后可以实现自己的删除,还有远一点的东西比如一些计算机病毒在实行自身的功能进行破坏后,对自身exe的删除

但是exe如何进行自我删除呢,我当时想的是自己的一个创建一个cmd进程,然后用cmd命令行的del来删除文件,但是我当时就有点萌比,怎么来创建cmd后来在cmd中模拟键盘输入命令呢,

网上百度了一些东西,其中偶有SendMessage这个函数,但是用的效果不理想,最后在换一种方式百度,发现可以直接创建一个类似"cmd echo Hello World"的进程。。额,好吧,其中一个问题解决了。

然后就是程序要运行完成后才能删除,这个东西我想到了多线程,但是这里显然不行,我上网上百度发现还有多进程,多进程好,但是我想挂起创建的cmd子进程的时候发现没有反应,也没有

GetLastError也没有显示,最后我在下午吃完了一块西瓜以后,想到了线程和进程的关系,进程的执行要靠线程,我不能挂起进程,那我挂起cmd子进程的主线程就可以了啊,ok,问题解决

代码中的程序由于是我的测试,所以什么都是可见的,要是设置成不可见的删除,那么改动三个参数就可以了,分别是去掉CREATE_NEW_CONSOLE,cmd /c ,还有去掉
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = TRUE;
这两句代码。

#include <stdlib.h>
#include <stdio.h>
#include <windows.h>

void DeleteSelf(HANDLE *hProcess,HANDLE *hThread)
{
      CHAR szExePath;
      GetModuleFileName(NULL, szExePath, MAX_PATH);                        //获取模块的完整路径,也就是exe的路径
      CHAR szCmdOrder;
      lstrcpy(szCmdOrder, "cmd /k del ");      //这里的命令行要是"cmd /c del "的话是不显示cmd窗口
      lstrcat(szCmdOrder, szExePath);

      STARTUPINFO si = { sizeof(si) };
      PROCESS_INFORMATION pi;

      si.dwFlags = STARTF_USESHOWWINDOW;
      si.wShowWindow = TRUE;
      BOOL bRet = CreateProcess(
                NULL,
                szCmdOrder,
                NULL,
                NULL,
                FALSE,
                CREATE_NEW_CONSOLE | CREATE_SUSPENDED,                //选择挂起主线程
                NULL,
                NULL,
                &si,
                &pi);
      if (!bRet)
      {
                printf("CreateProcess error:%d\n", GetLastError());
                CloseHandle(pi.hThread);
                CloseHandle(pi.hProcess);
                return;
      }
      
      //CloseHandle(pi.hThread);
      //CloseHandle(pi.hProcess);
      *hProcess = pi.hProcess;                        //址传递
      *hThread = pi.hThread;
}

int main(void)
{
      for (int i = 0; i < 3; i++)
      {
                printf("Hello World!\n");
      }


      HANDLE hProcess;
      HANDLE hThread;
      DeleteSelf(&hProcess,&hThread);
      SetPriorityClass(hProcess, IDLE_PRIORITY_CLASS);                        //设置空闲时刻执行
      
      //设置本程序立刻执行
      SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
      SetPriorityClass(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);

      Sleep(3 * 1000);                                                //睡上3秒
      
      if (!ResumeThread(hThread))                              //主进程执行完毕后开始执行主线程
      {
                printf("ResumeThread %d\n", GetLastError());
      }

      CloseHandle(hProcess);                                        //关闭进程句柄
      CloseHandle(hThread);                                        //关闭主线程句柄


      printf("程序运行完毕.\n");
      return 0;
}

系统消息 发表于 2019-9-24 12:14:40

我来几点建议吧:
1. 不建议写死cmd.exe(据说Win2000上是command.exe),也不要用相对路径(防止要自删的exe同目录下有个假的cmd.exe导致自删失败),使用系统提供的环境变量%ComSpec%来获取cmd.exe的完整路径。
2. CreateProcess 的参数最好使用 CREATE_NO_WINDOW(直接不创建控制台窗口),而不是通过 STARTUPINFO 去隐藏。
3. CreateProcess 失败就不会返回句柄给你,因此你在 DeleteSelf 中 CloseHandle操作完全是多余的(还会导致覆盖 GetLastError 的错误码)。
4. main 函数中定义的 hProcess 和 hThread 没有初始化,而 DeleteSelf 函数又没有提供失败检查机制,这样会在创建进程失败时得到未初始化的句柄值。

sml2 发表于 2018-6-8 12:59:47

:)给大佬递茶...

watermelon 发表于 2018-6-8 14:34:19

sml2 发表于 2018-6-8 12:59
给大佬递茶...

感谢大佬支持:lol

系统消息 发表于 2019-11-11 10:41:06

还有一种自删大法是往系统的进程里面注入线程,线程的入口函数就是 DeleteFile,线程的入口参数是路径。

Golden Blonde 发表于 2020-1-15 04:47:37

输出如下批处理并在ExitProcess之前执行:ping 127.0.0.1
del /q xxx.exe

Mouri_Naruto 发表于 2020-1-21 21:10:41

系统消息 发表于 2019-9-24 12:14
我来几点建议吧:
1. 不建议写死cmd.exe(据说Win2000上是command.exe),也不要用相对路径(防止要自删的e ...

Windows NT 架构的系统都是 cmd.exe
而且也没有 command.exe 只有 command.com,这个是 Windows 9x 内核(DOS-based)的默认命令解释器

系统消息 发表于 2020-1-23 22:47:11

Mouri_Naruto 发表于 2020-1-21 21:10
Windows NT 架构的系统都是 cmd.exe
而且也没有 command.exe 只有 command.com,这个是 Windows 9x 内核 ...

记得好像Win2000也是command吧,不过反正用%ComSpec%不会有错。

clhenyan 发表于 2021-6-21 07:18:58

谢谢分享
页: [1]
查看完整版本: 自删除EXE程序