Last active
May 27, 2024 15:00
-
-
Save vsetka/f10d94c03750a46e126604e7c6fe813e to your computer and use it in GitHub Desktop.
Self deleting executable - Windows
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef CLEANUP_H | |
#define CLEANUP_H | |
#include <windows.h> | |
#include <tchar.h> | |
#include <string> | |
#include <iostream> | |
#include <conio.h> | |
#endif | |
extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID); | |
extern "C" __declspec(dllexport) void CALLBACK SelfDel(HWND, HINSTANCE, LPTSTR lpCmdLine, int); | |
extern "C" __declspec(dllexport) void CALLBACK UninstallMSI(HWND, HINSTANCE, LPTSTR lpCmdLine, int); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Cleanup.h" | |
#include <windows.h> | |
#include <stdio.h> | |
#include <tchar.h> | |
HMODULE g_hmodDLL; | |
std::string trueRootDirectory; | |
int DeleteDirectory(const std::string &refcstrRootDirectory, bool bDeleteSubdirectories = true) | |
{ | |
bool bSubdirectory = false; // Flag, indicating whether subdirectories have been found | |
HANDLE hFile; // Handle to directory | |
std::string strFilePath; // Filepath | |
std::string strPattern; // Pattern | |
WIN32_FIND_DATA FileInformation; // File information | |
strPattern = refcstrRootDirectory + _T("\\*.*"); | |
hFile = ::FindFirstFile(strPattern.c_str(), &FileInformation); | |
if(hFile != INVALID_HANDLE_VALUE) | |
{ | |
do | |
{ | |
if (hFile == INVALID_HANDLE_VALUE) | |
break; | |
if(FileInformation.cFileName[0] != '.') | |
{ | |
strFilePath.erase(); | |
strFilePath = refcstrRootDirectory + _T("\\") + FileInformation.cFileName; | |
if(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) | |
{ | |
if(bDeleteSubdirectories) | |
{ | |
// Delete subdirectory | |
int iRC = DeleteDirectory(strFilePath, bDeleteSubdirectories); | |
if(iRC) | |
return iRC; | |
} | |
else | |
bSubdirectory = true; | |
} | |
else | |
{ | |
if (strFilePath.find(_T("Cleanup.dll")) == std::string::npos) // Do not delete self, we'll do that later | |
{ | |
// Set file attributes | |
if(::SetFileAttributes(strFilePath.c_str(), FILE_ATTRIBUTE_NORMAL) == FALSE) | |
return ::GetLastError(); | |
// Delete file | |
if(::DeleteFile(strFilePath.c_str()) == FALSE) | |
return ::GetLastError(); | |
} | |
} | |
} | |
} while(::FindNextFile(hFile, &FileInformation) == TRUE); | |
// Close handle | |
::FindClose(hFile); | |
DWORD dwError = ::GetLastError(); | |
if(dwError != ERROR_NO_MORE_FILES) | |
{ | |
return dwError; | |
} | |
// Do not delete the root directory | |
else if (trueRootDirectory != refcstrRootDirectory) | |
{ | |
if(!bSubdirectory) | |
{ | |
// Set directory attributes | |
if(::SetFileAttributes(refcstrRootDirectory.c_str(), FILE_ATTRIBUTE_NORMAL) == FALSE) | |
return ::GetLastError(); | |
// Delete directory | |
if(::RemoveDirectory(refcstrRootDirectory.c_str()) == FALSE) | |
return ::GetLastError(); | |
} | |
} | |
} | |
return 0; | |
} | |
extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID) | |
{ | |
if (reason == DLL_PROCESS_ATTACH) | |
g_hmodDLL = hinstDLL; | |
return TRUE; | |
} | |
extern "C" __declspec(dllexport) void CALLBACK UninstallMSI(HWND, HINSTANCE, LPTSTR productCode, int) | |
{ | |
// delete the executable file that created this process | |
Sleep(5000); | |
STARTUPINFO si; | |
PROCESS_INFORMATION pi; | |
ZeroMemory( &si, sizeof(si) ); | |
si.cb = sizeof(si); | |
ZeroMemory( &pi, sizeof(pi) ); | |
TCHAR windir[255]; | |
TCHAR directory[255]; | |
TCHAR filename[255]; | |
TCHAR np_name[255]; | |
GetSystemWindowsDirectory(windir, 148); | |
_stprintf(np_name, _T("%s\\system32\\msiexec.exe /x %s /q"), windir,productCode); | |
/*::MessageBoxA(NULL,np_name,"",MB_OK);*/ | |
LPTSTR szCmdline = _tcsdup(np_name); | |
CreateProcess(NULL, szCmdline,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi); | |
free(szCmdline); | |
// Name of self | |
TCHAR filenameDLL[MAX_PATH]; | |
GetModuleFileName(g_hmodDLL, filenameDLL, sizeof(filenameDLL)); | |
// Assembler magic to unload from rundll32 | |
__asm | |
{ | |
lea eax, filenameDLL | |
push 0 | |
push 0 | |
push eax | |
push ExitProcess | |
push FreeLibrary | |
ret | |
} | |
} | |
extern "C" __declspec(dllexport) void CALLBACK SelfDel(HWND, HINSTANCE, LPTSTR lpCmdLine, int) | |
{ | |
// delete the executable file that created this process | |
Sleep(5000); | |
trueRootDirectory = std::string(lpCmdLine); | |
int iRC = DeleteDirectory(lpCmdLine); | |
if(iRC) | |
{ | |
std::cout << "Error " << iRC << std::endl; | |
return; | |
} | |
// Name of self | |
TCHAR filenameDLL[MAX_PATH]; | |
GetModuleFileName(g_hmodDLL, filenameDLL, sizeof(filenameDLL)); | |
// Assembler magic to delete itself and unload from rundll32 | |
__asm | |
{ | |
lea eax, filenameDLL | |
push 0 | |
push 0 | |
push eax | |
push ExitProcess | |
push g_hmodDLL | |
push DeleteFile | |
push FreeLibrary | |
ret | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment