当前位置:天才代写 > tutorial > C语言/C++ 教程 > 如何简朴实现可执行文件的自我删除

如何简朴实现可执行文件的自我删除

2017-11-04 08:00 星期六 所属: C语言/C++ 教程 浏览:981

副标题#e#

可执行文件即 EXE 文件在运行进程中,由系统打点其打开的句柄。此时对该 文件的一些操纵是被系统克制的,好比删除操纵。然而在某些场所,大概必要程 序有自我删除的成果,也就是措施运行竣事后删除自身。基于这个想法,可以有 一种很简朴的要领来实现这个根基成果。

本要领基于两点来实现删除成果。一是操作 windows 的 command program 的 删除文件操纵;再者就是启动新的历程来执行这个删除操纵。下面就仔细说明。

Windows 中的 command program 是一个系统的 shell program. 在 windows95/98/Me 中,其文件名为 command.com ,而在 NT/2000/XP 中则是 cmd.exe 。我们可以通过情况变量 COMSPEC 获得其全路径名。

假定今朝我们所利用的是 XP ,在呼吁行中输入 :

cmd.exe /?

即获得 command shell 的利用要领;个中 /c 的寄义是:执行字符串指定的 呼吁然后终断,这正是我们所必要的。这样操作 command shell 删除一个文件的 呼吁如下:

cmd.exe /c del mypro.exe

这里要留意一点,文件名应该是随笔件名(文件名不得高出 8 个字符 , 后缀 不高出 3 个字符)。假如实际文件是长文件句,那么措施中我们可以用 GetShortPathName 这个 API 函数来转换。

接下来我们要做是如安在一新的历程中乐成的执行这一指令。起来一个新历程 的呼吁主要有 ShellExecute 和 CreateProcess 。

先利用 ShellExecute 为例。在措施的竣事处利用如下语句:

ShellExecute(NULL, "open","cmd.exe", "/c del mypro.exe ", NULL, SW_HIDE);

编译后运行文件发明执行乐成,文件运行完后被删除。可是后头做多次尝试后 ,发明有时文件执行完后并不会被删除。通过阐明,认为在删除操纵执行时,可 执行文件还未封锁。也就是说只有在执行文件的历程封锁后,执行删除操纵的进 程才气完成操纵。这样就有了一个问题,系统认真历程和线程的调治执行,我们 无法工钱划定历程或线程以某种秩序执行。

对此我的办理步伐是,成立执行删除操纵的历程时设定其为挂起状态,从而为 其的设定一个低优先级别,同时提高执行文件的历程级别,然后才正式起动新进 程。这样根基可以担保两个历程的先后执行。这样新的办理要领就是用 CreateProcess以CREATE_SUSPEND符号来成立新历程,然后用SetPriorityClass来 设定相应的优先级,主历程的优先级是HIGH_PRIORITY_CLASS,而执行删除操纵的 历程的优先级是IDLE_PRIORITY_CLASS。颠末数百次的测试,删除操纵都是乐成的 。


#p#副标题#e#

下面是一个封装了删除操纵的函数,函数内起动一个历程执行command shell的 del呼吁。在措施最后竣事处挪用它,就可以简朴的实现措施的自删除成果。 #include <windows.h>
#include <shellapi.h>
#include <stdio.h>
int DeleteMyExe()
{
  TCHAR tcsExename[MAX_PATH];
  TCHAR tcsParam[MAX_PATH * 2];
  TCHAR tcsCmd[MAX_PATH];
  HANDLE hProcess = NULL;
  // get exe filename and command shell program
  if( 0 == GetModuleFileName(NULL, tcsExename, MAX_PATH)
    || 0 == GetEnvironmentVariable(_T("COMSPEC"), tcsCmd, MAX_PATH))
    FAILRET;
  // get short filename for command shell program
  if( 0 == GetShortPathName(tcsExename, tcsExename, MAX_PATH))
    FAILRET;

  // create a command process, set its priority, then start it.
  STARTUPINFO si;
  PROCESS_INFORMATION pi;
  ZeroMemory( &si, sizeof(si) );
  si.cb     = sizeof(si);
  si.dwFlags   = STARTF_USESHOWWINDOW;
  si.wShowWindow = SW_HIDE;
  ZeroMemory( &pi, sizeof(pi) );
  _stprintf(tcsParam, _T("%s /c del %s"), tcsCmd, tcsExename);
  if(!CreateProcess(NULL,
           tcsParam,
           NULL,
           NULL,
           FALSE,
           CREATE_SUSPENDED,
           NULL,
           NULL,
           &si,
           &pi))
  {
    return GetLastError();
  }
  // heigthen priority of the current process
  SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
  // set file attribute to normal
  SetFileAttributes(tcsExename, FILE_ATTRIBUTE_NORMAL);
  // depress priority of command process, then start it
  SetPriorityClass(pi.hProcess, IDLE_PRIORITY_CLASS);
  ResumeThread(pi.hThread);
  return 0;
}

(全文完)

 

    关键字:

天才代写-代写联系方式