exe自身操作code

Figure 1   ReplaceFileOnReboot


RFOR.H


/***********************************************************************
Module name: RFoR.h
Written by:  Jeffrey Richter
Note:        This function works on both Windows 95 and Windows NT.
************************************************************************/


BOOL WINAPI ReplaceFileOnReboot (LPCTSTR pszExisting, LPCTSTR pszNew);


/ End of File /

RFOR.C


/*****************************************************************************
Module name: RFoR.c
Written by:  Jeffrey Richter
Note:        This function abstracts the differences between Windows
95 and
             Windows NT for replacing/deleting a file when the system
reboots.
************************************************************************
******/


#define STRICT
#include <windows.h>





#include "RFoR.h"





BOOL WINAPI ReplaceFileOnReboot (LPCTSTR pszExisting, LPCTSTR pszNew)
{

   // First, attempt to use the MoveFileEx function.
   BOOL fOk = MoveFileEx(pszExisting, pszNew,
MOVEFILE_DELAY_UNTIL_REBOOT);
   if (fOk) return(fOk);

   // If MoveFileEx failed, we are running on Windows 95 and need to
add
   // entries to the WININIT.INI file (an ANSI file).
   // Start a new scope for local variables.
   {
   char szRenameLine[1024];

   int cchRenameLine = wsprintfA(szRenameLine,
#ifdef UNICODE
      "%ls=%ls/r/n",
#else
      "%hs=%hs/r/n",
#endif
      (pszNew == NULL) ? __TEXT("NUL") : pszNew, pszExisting);
      char szRenameSec[] = "[Rename]/r/n";
      int cchRenameSec = sizeof(szRenameSec) - 1;
      HANDLE hfile, hfilemap;
      DWORD dwFileSize, dwRenameLinePos;
      TCHAR szPathnameWinInit[_MAX_PATH];

      // Construct the full pathname of the WININIT.INI file.
      GetWindowsDirectory(szPathnameWinInit, _MAX_PATH);
      lstrcat(szPathnameWinInit, __TEXT("//WinInit.Ini"));

      // Open/Create the WININIT.INI file.
      hfile = CreateFile(szPathnameWinInit,
         GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);

      if (hfile == INVALID_HANDLE_VALUE)
         return(fOk);

      // Create a file mapping object that is the current size of
      // the WININIT.INI file plus the length of the additional string
      // that we're about to insert into it plus the length of the
section
      // header (which we might have to add).
      dwFileSize = GetFileSize(hfile, NULL);
      hfilemap = CreateFileMapping(hfile, NULL, PAGE_READWRITE, 0,
         dwFileSize + cchRenameLine + cchRenameSec, NULL);

      if (hfilemap != NULL) {

         // Map the WININIT.INI file into memory.  Note: The contents
         // of WININIT.INI are always ANSI; never Unicode.
         LPSTR pszWinInit = (LPSTR) MapViewOfFile(hfilemap,
            FILE_MAP_WRITE, 0, 0, 0);

         if (pszWinInit != NULL) {

            // Search for the [Rename] section in the file.
            LPSTR pszRenameSecInFile = strstr(pszWinInit, szRenameSec);


            if (pszRenameSecInFile == NULL) {

               // There is no [Rename] section in the WININIT.INI file.

               // We must add the section too.
               dwFileSize += wsprintfA(&pszWinInit[dwFileSize], "%s",
                                    szRenameSec);
               dwRenameLinePos = dwFileSize;

            } else {

               // We found the [Rename] section, shift all the lines
down
               PSTR pszFirstRenameLine = strchr(pszRenameSecInFile,
'/n');
               // Shift the contents of the file down to make room for

               // the newly added line.  The new line is always added
               // to the top of the list.
               pszFirstRenameLine++;   // 1st char on the next line
               memmove(pszFirstRenameLine + cchRenameLine,
pszFirstRenameLine,
                  pszWinInit + dwFileSize - pszFirstRenameLine);

               dwRenameLinePos = pszFirstRenameLine - pszWinInit;
            }

            // Insert the new line
            memcpy(&pszWinInit[dwRenameLinePos], szRenameLine,
cchRenameLine);

            UnmapViewOfFile(pszWinInit);

            // Calculate the true, new size of the file.
            dwFileSize += cchRenameLine;

            // Everything was successful.
            fOk = TRUE;
         }
         CloseHandle(hfilemap);
      }

      // Force the end of the file to be the calculated, new size.
      SetFilePointer(hfile, dwFileSize, NULL, FILE_BEGIN);
      SetEndOfFile(hfile);

      CloseHandle(hfile);
   }

   return(fOk);
}


/ End of File
/
Figure 2   DELEXE


DELEXE.H


/***********************************************************************
*******
Module name: DelExe.h
Written by:  Jeffrey Richter
Note:        This function works on Windows 95 but does NOT work on
Windows NT.
************************************************************************
******/


VOID WINAPI DeleteExecutable (DWORD dwExitCode, BOOL fRemoveDir);


/ End of File
/

DELEXE.C


/***********************************************************************
*******
Module name: DelExe.c
Written by:  Jeffrey Richter
Note:        This function works on Windows 95 but does NOT work on
Windows NT.
************************************************************************
******/


#define STRICT
#include <Windows.h>
#include <tchar.h>



///


#include "DelExe.h"



///


// Prototypes for functions that we explicitly import from Kernel32.
DLL
typedef BOOL (WINAPI *PROCFREELIBRARY)(HINSTANCE);
typedef BOOL (WINAPI *PROCDELETEFILE)(LPCTSTR);
typedef BOOL (WINAPI *PROCREMOVEDIRECTORY)(LPCTSTR);
typedef VOID (WINAPI *PROCEXITPROCESS)(DWORD);


// Data structure containing all the information we need to delete
ourselves,
// remove our containing directory, and terminate ourselves.
typedef struct {

   HINSTANCE hinstExe;
   PROCFREELIBRARY pfnFreeLibrary;

   PROCDELETEFILE pfnDeleteFile;
   TCHAR szFile[_MAX_PATH];

   PROCREMOVEDIRECTORY pfnRemoveDirectory;
   TCHAR szDir[_MAX_PATH];

   PROCEXITPROCESS pfnExitProcess;
   DWORD dwExitCode;
} DELEXEINFO, *PDELEXEINFO;

typedef VOID (WINAPI *PROCDELEXE)(PDELEXEINFO);



///


// Code to be injected into our own address space.
static void WINAPI DelExeInjCode (PDELEXEINFO pdei) {

      // Remove the EXE file from our address space
      pdei->pfnFreeLibrary(pdei->hinstExe);

      // Delete the EXE file now that it is no longer in use
      pdei->pfnDeleteFile(pdei->szFile);

      if (pdei->pfnRemoveDirectory != NULL) {
            // Remove the directory (which is now empty)
            pdei->pfnRemoveDirectory(pdei->szDir);
      }

      // Terminate our process
      pdei->pfnExitProcess(pdei->dwExitCode);
}



///


// This function just marks the end of the previous function
static void WINAPI AfterDelExeInjCode (void) {
}



///


void WINAPI DeleteExecutable (DWORD dwExitCode, BOOL fRemoveDir) {

      HINSTANCE hinstKrnl = GetModuleHandle(__TEXT("KERNEL32"));
      HANDLE hheap = GetProcessHeap();

      // Calculate the number of bytes in the DelExeInjCode function.
      const int cbFuncSize = ((LPBYTE)(DWORD)
      AfterDelExeInjCode - (LPBYTE)(DWORD) DelExeInjCode);

      DELEXEINFO dei;

      // From our process's default heap, allocate memory where we can

      // inject our own function.
      PROCDELEXE pfnDelExe = HeapAlloc(hheap, HEAP_ZERO_MEMORY,
cbFuncSize);

      // Inject the DelExeInjCode function into the memory block
      memcpy(pfnDelExe, DelExeInjCode, cbFuncSize);

      // Initialize the DELEXEINFO structure.
      dei.hinstExe = GetModuleHandle(NULL);
      dei.pfnFreeLibrary = (PROCFREELIBRARY)
      GetProcAddress(hinstKrnl, "FreeLibrary");

      // Assume that the subdirectory is NOT to be removed.
      dei.pfnRemoveDirectory = NULL;
#ifdef UNICODE
      dei.pfnDeleteFile = (PROCDELETEFILE)
      GetProcAddress(hinstKrnl, "DeleteFileW");
#else
      dei.pfnDeleteFile = (PROCDELETEFILE)
      GetProcAddress(hinstKrnl, "DeleteFileA");
#endif
      GetModuleFileName(dei.hinstExe, dei.szFile, _MAX_PATH);

   if (fRemoveDir) {

            // The subdirectory should be removed.
#ifdef UNICODE
            dei.pfnRemoveDirectory = (PROCREMOVEDIRECTORY)
            GetProcAddress(hinstKrnl, "RemoveDirectoryW");
#else
            dei.pfnRemoveDirectory = (PROCREMOVEDIRECTORY)
            GetProcAddress(hinstKrnl, "RemoveDirectoryA");
#endif
            lstrcpy(dei.szDir, dei.szFile);
            *_tcsrchr(dei.szDir, __TEXT('//')) = 0;
   }

      dei.pfnExitProcess = (PROCEXITPROCESS)
      GetProcAddress(hinstKrnl, "ExitProcess");
      dei.dwExitCode = dwExitCode;

      pfnDelExe(&dei);
      // We never get here because pfnDelExe never returns
}


/ End of File
/
Figure 3   DeleteExecutableBF


DELEXEBF.H


/***********************************************************************
*******
Module name: DelExeBF.h
Written by:  Jeffrey Richter
Note:        This function works on both Windows 95 and Windows NT.
************************************************************************
******/


VOID WINAPI DeleteExecutableBF (void);


/ End of File
/

DELEXEBF.C


/***********************************************************************
*******
Module name: DelExeBF.c
Written by:  Jeffrey Richter
Note:        This function works on both Windows 95 and Windows NT.
************************************************************************
******/


#define STRICT
#include <Windows.h>
#include <tchar.h>



///


#include "DelExeBF.h"



///


// The name of the temporary batch file
#define DELUNSETUPBAT     __TEXT("//DelUS.bat")



///


void WINAPI DeleteExecutableBF (void) {
   HANDLE hfile;
   STARTUPINFO si;
   PROCESS_INFORMATION pi;

   // Create a batch file that continuously attempts to delete our
executable
   // file.  When the executable no longer exists, remove its
containing
   // subdirectory, and then delete the batch file too.
   hfile = CreateFile(DELUNSETUPBAT, GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS,                             FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_SEQUENTIAL_SCAN, NULL);
   if (hfile != INVALID_HANDLE_VALUE) {

      TCHAR szBatFile[1000];
      TCHAR szUnsetupPathname[_MAX_PATH];
      TCHAR szUnsetupPath[_MAX_PATH];
      DWORD dwNumberOfBytesWritten;

      // Get the full pathname of our executable file.
      GetModuleFileName(NULL, szUnsetupPathname, _MAX_PATH);

      // Get the path of the executable file (without the filename)
      lstrcpy(szUnsetupPath, szUnsetupPathname);
      *_tcsrchr(szUnsetupPath, __TEXT('//')) = 0;     // Chop off the
name

      // Construct the lines for the batch file.
      wsprintf(szBatFile,
         __TEXT(":Repeat/r/n")
         __TEXT("del /"%s/"/r/n")
         __TEXT("if exist /"%s/" goto Repeat/r/n")
         __TEXT("rmdir /"%s/"/r/n")
         __TEXT("del /"%s/"/r/n"),
         szUnsetupPathname, szUnsetupPathname, szUnsetupPath,
DELUNSETUPBAT);

      // Write the batch file and close it.
      WriteFile(hfile, szBatFile, lstrlen(szBatFile) * sizeof(TCHAR),
         &dwNumberOfBytesWritten, NULL);
      CloseHandle(hfile);

      // Get ready to spawn the batch file we just created.
      ZeroMemory(&si, sizeof(si));
      si.cb = sizeof(si);

      // We want its console window to be invisible to the user.
      si.dwFlags = STARTF_USESHOWWINDOW;
      si.wShowWindow = SW_HIDE;

      // Spawn the batch file with low-priority and suspended.
      if (CreateProcess(NULL, DELUNSETUPBAT, NULL, NULL, FALSE,
         CREATE_SUSPENDED | IDLE_PRIORITY_CLASS, NULL, __TEXT("//"),
&si, &pi)) {

         // Lower the batch file's priority even more.
         SetThreadPriority(pi.hThread, THREAD_PRIORITY_IDLE);

         // Raise our priority so that we terminate as quickly as
possible.
         SetThreadPriority(GetCurrentThread(),
THREAD_PRIORITY_TIME_CRITICAL);
         SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);

         // Allow the batch file to run and clean-up our handles.
         CloseHandle(pi.hProcess);
         ResumeThread(pi.hThread);
         // We want to terminate right away now so that we can be
deleted
         CloseHandle(pi.hThread);
      }
   }
}


/ End of File
/
Figure 4    TDELEXE.C



/***********************************************************************
*******
Module name:  TDelExe.c
Written by:  Jeffrey Richter
Note:        This function tests the functions that delete our own
executable.

************************************************************************
******/


#define STRICT
#include <Windows.h>



///


#include "RFoR.h"       // to delete this executable file on reboot.
#include "DelExe.h"     // to delete this executable file using a
batch file.
#include "DelExeBF.h"   // to delete this executable file using code.



///


int WINAPI WinMain (HINSTANCE hinstExe, HINSTANCE hinstExePrev,
                    LPSTR lpszCmdLine, int nCmdShow) {

   int nId = MessageBox(NULL,
      __TEXT("Choose Yes to delete this executable file on reboot./n")
      __TEXT("Choose No to delete this executable file using a batch
file./n")
      __TEXT("Choose Cancel to delete this executable file using code.
/n"),
      __TEXT("Delete Executable"), MB_YESNOCANCEL);

   switch (nId) {
      case IDYES:
         {
         TCHAR szPathname[_MAX_PATH];
         GetModuleFileName(NULL, szPathname, _MAX_PATH);
         ReplaceFileOnReboot(szPathname, NULL);
         }
         break;

      case IDNO:
         DeleteExecutableBF();
         // We want to terminate right away so that we can be deleted
         break;

      case IDCANCEL:
        DeleteExecutable(0, TRUE);
        // DeleteExecutable never returns back to us.
         break;
   }

       return(0);
}


/ End of File /

------------------------------------------------------------------------
--------
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值