In this post, I’ll provide an example of self-deleting programs, as well as the different ways it can be used, and finally a detailed explanation. The first example is for Windows (OS), which create a temporary file and use it to delete the original executable, The second example is Linux based simply uses built in functions to initiate the self-deletion process.
Example 01
This program can help make sure that any executables that are created are removed from the system once their job is complete.
int
CommitSuicide(char *szCmdLine)
{
HANDLE hTemp;
char szPath[MAX_PATH];
char szTemp[MAX_PATH];
static BYTE buf[1024];
STARTUPINFO si;
PROCESS_INFORMATION pi;
UINT ret;
//open a temporary file
GetTempPath(MAX_PATH, szTemp);
lstrcat(szTemp, "suicide.exe");
GetModuleFileName(0, szPath, MAX_PATH);
CopyFile(szPath, szTemp, FALSE);
hTemp = CreateFile(szTemp, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_DELETE, 0,
OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0);
//Create a process using the temporary executable. This will cause
//the file's handle count to increase, so we can close it.
ZeroMemory(&si, sizeof(STARTUPINFO));
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
lstrcat(szTemp, " ");
lstrcat(szTemp, szCmdLine);
ret = CreateProcess(0, szTemp, 0, 0, FALSE, NORMAL_PRIORITY_CLASS, 0, 0, &si, &pi);
//Close our handle to the new process. Because the process is
//memory-mapped, there will still be a handle held by the O/S, so
//it won't get deleted. Give the other process a chance to run..
Sleep(100);
CloseHandle(hTemp);
return 0;
}
- When it’s time to delete ourselves we first spawns a new process using that file, and then deletes the temporary file. Calling
szCmdLine
as its input parameter which creates a temporary file in the system’s tmp directory and copies the current executable file to that tmp file finally creates a new process using the temporary file, waits forSleep();
and then closes the handle to the tmp file
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, PSTR szCmdLine, int iCmdShow)
{
char szPath[MAX_PATH];
//
// Parse the command line
// Normally, we should not be run with any paramters
// We re-spawn ourselves with the current module's path
//
if(szCmdLine[0] == '\0')
{
// Spawn a duplicate process, and tell it to delete US
HMODULE hModule = GetModuleHandle(0);
GetModuleFileName(hModule, szPath, MAX_PATH);
CommitSuicide(szPath);
// Exit normally
return 0;
}
// This is where we pick up execution second time we run,
// When a filename has been specified on the command line
else
{
// Give the calling process time to exit...
Sleep(200);
// Delete the file specified on command line.
DeleteFile(szCmdLine);
// Exit normally. When we close, this executable will be automatically
return 0;
}
}
- Next, we check if any command line parameters have been passed we
Sleep();
and then deletes the file specified by the command line parameter if none we re-spawn the path of the current executable file as a command line parameter.
Example 02
This actually a simple one this function deletes the current executable by obtaining its path readlink
and calling the unlink
.
void
CommitSuicide() {
char path[256];
int status;
// Get the path of the current program
status = readlink("/proc/self/exe", path, sizeof(path) - 1);
if (status == -1) {
exit(EXIT_FAILURE);
}
path[status] = '\0';
// Copy the executable to a temporary file
char tmp_path[] = "/tmp/XXXXXX";
int fd = mkstemp(tmp_path);
if (fd == -1) {
exit(EXIT_FAILURE);
}
if (write(fd, path, status) != status) {
exit(EXIT_FAILURE);
}
close(fd);
// Launch the temporary executable as a new process
if (fork() == 0) {
execl(tmp_path, "", NULL);
}
// Delete the original executable
unlink(path);
// Exit the current process
exit(EXIT_SUCCESS);
}
int main() {
CommitSuicide();
return 0;
}
The general idea is to create a temporary copy of the executable file, launch it as a new process, and then delete the original executable before the new process terminates, This can be used as an anti-analysis technique since the executable file will no longer be available after CommitSuicide
function gets called.
That’s all for now. I hope you learned something from this. Please feel free to share any techniques or thought