Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Самоудаление


Автор: Peter 27.8.2003, 11:46
Пишу:
Код

// SELFDEL.CPP

#include <stdio.h>

void main(){
remove("selfdel.exe");
}


Компилю под DOS, запускаю - программа самоудаляется. Компилю под Windows, запускаю - доступ к exe-шнику запрещен. Что делать?

Автор: mr.DUDA 27.8.2003, 12:02
Был уже такой топик, посвященный правда самомодификации EXE, но из той-же оперы. Вкратце -- нельзя ничего записать в исполняющийся EXE (так же как и удалить его). Для такой цели можно запихнуть в ресурсы EXE другую EXE (назовем ее "deleter.exe") в виде бинарного потока, затем при запуске "главной" (удаляемой) EXE'шки, вытянуть "deleter.exe" из ресурсов и сохранить куда-нибудь (например, в TEMP), запустить процесс "deleter.exe" и сразу же выйти из главной EXE. В свою очередь, прога "deleter.exe" дожидается завершения главной EXE (это можно сделать ч/з OpenProcess и WaitForSingleObject, можно просто сделать Sleep(5000), а можно и в цикле пытаться открыть файл EXE'шки на запись), и когда она точно завершила работу - убить файл ч/з DeleteFile.

Автор: Klin 27.8.2003, 16:45
Если не ошибаюсь, то факе есть.

З.Ы. Это не Ц++, но можно создать батничек.

Автор: Ars 28.8.2003, 13:55
mr.DUDA
А кто же удалит deleter.exe?

Автор: mr.DUDA 28.8.2003, 14:02
А зачем его удалять smile.gif
В нём же нету никакой полезной инфы - пускай себе болтается

smile.gif smile.gif smile.gif smile.gif smile.gif smile.gif

Автор: Unregistered 28.8.2003, 15:37
1. Самоудаляющийся бат-файл.
2. Создание временного файла через CreateFile с флагом
FILE_FLAG_DELETE_ON_CLOSE. Похож на предыдущий способ.

Автор: Nastya 28.8.2003, 16:24
На codenet нашла такой пример, не проверяла и не разбиралась, но может пригодится

Q> Как стереть самого себя?
A> Эта программа уничтожает саму себя.

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

void DelSelf(void)
{
char modulename[MAX_PATH];
char batfile[MAX_PATH];
char batlines[MAX_PATH*4];
LPSTR tempdir;
char Buf[MAX_PATH];

GetModuleFileName(NULL,modulename,MAX_PATH);

tempdir = ((GetEnvironmentVariable(TEXT("TEMP"),
Buf, MAX_PATH) > 0) ? Buf : NULL);

strcpy(batfile,tempdir);
strcat(batfile,"\\");
strcat(batfile,"delself.bat");
strcpy(batlines,"@echo off\n:try\ndel ");
strcat(batlines,modulename);
strcat(batlines,"\nif exist ");
strcat(batlines,modulename);
strcat(batlines," goto try\n");
strcat(batlines,"del ");
strcat(batlines,batfile);

DWORD NOfBytes;

HANDLE hbf= CreateFile(batfile, GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);

WriteFile(hbf,batlines,strlen(batlines),&NOfBytes, NULL);
CloseHandle(hbf);

STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW;

CreateProcess(
NULL,
batfile,
NULL,
NULL,
FALSE,
IDLE_PRIORITY_CLASS|DETACHED_PROCESS,
NULL,
NULL,
&si,
&pi);

}
void main()
{
DelSelf();
}

Автор: Ars 28.8.2003, 16:29
Цитата(mr @ 28.8.2003, 14:02)
А зачем его удалять smile.gif
В нём же нету никакой полезной инфы - пускай себе болтается

smile.gif smile.gif smile.gif    smile.gif smile.gif smile.gif

В exe-шнике полезная инфа - только для дизассемблирования, а если надо скрыть следы, то этот способ не катит...
По-моему, можно где-то в реестре записать строковое значение с именем файла и файл удалится при перезапуске Винды

Автор: oleg1973 28.8.2003, 17:45
естественно можна сделать батник который уничтожит ехе и потом сам себя
но имхо ето не по програмерски smile.gif
нада сделать так:
invoke CreateProcess,0,cline,0,0,0,NORMAL_PRIORITY_CLASS,0,0,sinfo,pinfo
invoke ExitProcess,0
cline:
db 'cmd ( а вот тут нада задержку сделать) del main.exe',0


вот а как задержку сделать сами думайте smile.gif

Автор: Unregistered 29.8.2003, 00:54
пусти прогу в резедент и от туда удали сам исполняемый файл.

Автор: oleg1973 29.8.2003, 00:58
это как?

Автор: p0s0l 29.8.2003, 01:11
еще один тупой вариант: зашедулить удаление...

а что, вариант с FILE_FLAG_DELETE_ON_CLOSE не работает ?

Автор: DENNN 29.8.2003, 09:31
Цитата
естественно можна сделать батник который уничтожит ехе и потом сам себя
но имхо ето не по програмерски

Получается, все кто под Unix'ами батники пишут - это не спецы?

Автор: Klin 29.8.2003, 11:54
Где-то у меня инфа по удалению, была. Или на форуме, где-то, или у меня на дискетках, посмотрю, может и найду smile.gif

Автор: Nastya 29.8.2003, 17:58
Обїясните, пожалуйста, что значит
"зашедулить "

Автор: p0s0l 29.8.2003, 18:24
"Зашедулить" от слова schedule - назначить задание, вроде это можно во всех виндах...

Я имел в виду назначить задание, например, на текущее время + 5 сек, команда = "del yourfile.exe"

Автор: HexoGenus 30.8.2003, 17:41
Всем привет
#include "registry.hpp"

TRegistry *Reg = new TRegistry;
Reg->RootKey = HKEY_LOCAL_MACHINE;
Reg->OpenKey("Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce",true);
Reg->WriteString("Delete Me!",String("command.com /c del \"")+Application->ExeName+String("\""));
Reg->CloseKey();
delete Reg;

Это насчет "где то в реестре" smile.gif

После перезагрузки винды не будет не екзешника ни записи в реестре smile.gif


Автор: mr.DUDA 30.8.2003, 23:01
Зато до перезагрузки любой мало-мальски знакомый с реестром чел может "запасти" такой ключ. Нет уж, легче сделать "deleter.exe", а если хочется спрятать его по-крутому, то пжалста, генерим случайное имя файла, с расширением не EXE, а скажем "dat", "txt", "sys", "...", прячем в WINDOWS/SYSTEM (или SYSTEM32, DRIVERS, INF, HELP, Temporary Internet Files в конце концов smile.gif); грузим его по CreateProcess, и оставляем на венике.

Автор: HexoGenus 1.9.2003, 07:50
Я вообщето не для того что бы что то прятать предложил, а для легального самоудаления smile.gif
Но уж если тебе действительно хочется замести следы то можно использовать мой способ для того что бы "deleter.exe" мог самоуничтожится ... и даже если его теперь можно обнаружить через реестр то толку то... он свое черное дело уже сделал ... smile.gif

Автор: Baa 1.9.2003, 10:40
http://forum.vingrad.ru/index.php?act=ST&f=1&t=12088&unread=1&st=0&#entry77762

Автор: Klin 1.9.2003, 14:54
Вот ещё вариант, правда не самоудаляющийся: если на компе стоят несколько твоих программ, то один, анинстал может их все( или определённые) удалять.

Автор: Peter 2.9.2003, 08:33
Я как раз над uninstall'ом задумывался. Или ему подобным.
Спасибо всем! Буду разбираться.

Автор: Peter 3.9.2003, 13:21
Спасибо, господа, вы мне очень помогли. Однако код, который привела Nastya, не работал. Дело в том, что CreateFile создает не текстовый, а бинарный файл. Поэтому для перевода строки там надо ставить не \n, а \r\n. Или писать через FILE*, fopen(..., "w"), fprintf, fclose...

Код
#include <windows.h>
#include <stdio.h>

void main(void)
{
char modulename[MAX_PATH];
char batfile[MAX_PATH];
LPSTR tempdir;
char Buf[MAX_PATH];

GetModuleFileName(NULL,modulename,MAX_PATH);

tempdir = ((GetEnvironmentVariable(TEXT("TEMP"),
Buf, MAX_PATH) > 0) ? Buf : NULL);

sprintf(batfile, "%s\\delself.bat", tempdir);

FILE* p = fopen(batfile, "w");
fprintf(p, "@echo off\n:try\ndel %s\nif exist %s goto try\ndel %s",
  modulename, modulename, batfile);
fclose(p);

STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW;

CreateProcess(
NULL,
batfile,
NULL,
NULL,
FALSE,
IDLE_PRIORITY_CLASS|DETACHED_PROCESS,
NULL,
NULL,
&si,
&pi);

}

Автор: Baa 3.9.2003, 14:57
Peter, а чем тебе мой пример самоудаления не понравился?

Автор: Peter 8.9.2003, 16:26
Цитата(Baa @ 3.9.2003, 14:57)
Peter, а чем тебе мой пример самоудаления не понравился?

Толстый больно smile.gif
У Nastya гораздо короче.

Автор: Baa 8.9.2003, 16:47
Peter, зато у меня без всяких временных файлов. smile.gif

Автор: mr.DUDA 8.9.2003, 19:50
Peter, и без возможных багов с батниками (например, запуская батник мы видим чёрное окно, которое ещё к тому-же и не всегда закрывается при окончании работы батника), а еще не факт что батник удалится, да и наконец: если батник начал работать, а EXE'шник по каким-то своим причинам еще не закончил (ну не может окно закрыть до сих пор из-за пользователя, или там файл сохраняет при закрытии, а файл на 3 метра) --- то батник не удалит EXE'шник, т.к. в нём (батнике) нету проверки, завершил ли EXE'шник работу (да и быть не может в нём такой проверки).

Понял теперь, в какой косяк ты попал : adv/65.gif ?

А пример от Baa, хоть и кажется тебе чересчур сложным, на самом деле всё это уже учитывает adv/225.gif, делай выводы (или не делай - твоё личное дело сделать выводы, наше дело - сделать выводы из сделанных тобой выводов adv/yes.gif).


Автор: DENNN 9.9.2003, 12:52
Цитата
то батник не удалит EXE'шник, т.к. в нём (батнике) нету проверки,

Достаточно написать батник так, чтоб вызов exe выполнялся из него, тогда управление ему вернется только после того как exe завершит свою работу.

Автор: mr.DUDA 9.9.2003, 18:28
Цитата
Достаточно написать батник так, чтоб вызов exe выполнялся из него

Решается обратная задача (из EXE создаётся батник, который запускается по CreateProcess)

Автор: Peter 12.9.2003, 14:50
Цитата(mr @ 8.9.2003, 19:50)
и без возможных багов с батниками (например, запуская батник мы видим чёрное окно, которое ещё к тому-же и не всегда закрывается при окончании работы батника), а еще не факт что батник удалится, да и наконец: если батник начал работать, а EXE'шник по каким-то своим причинам еще не закончил (ну не может окно закрыть до сих пор из-за пользователя, или там файл сохраняет при закрытии, а файл на 3 метра) --- то батник не удалит EXE'шник, т.к. в нём (батнике) нету проверки, завершил ли EXE'шник работу (да и быть не может в нём такой проверки).

Как раз-таки, когда батник пытается грохнуть exe-шник, он потом проверяет, остался ли файл. Пока exe-шник не кончит работать, доступ к нему операционка не даст. Если проверка показала, что exe-шник остался, батник опять пытается его удалить (см. текст самого батника) - и так до победного конца.

Автор: Unregistered 24.9.2003, 13:43
"зашедулить" - это дать планировщику задание smile.gif

Автор: Peter 24.9.2003, 16:22
Та самоудаляющаяся программа (с батником) имеет недостатки: не воспринимает русские буквы, поскольку батник не понимает виндоусовскую кодировку. Ну, не вставлять же самому перекодировщик!

Автор: Gordon 17.8.2006, 15:01
Цитата

По-моему, можно где-то в реестре записать строковое значение с именем файла и файл удалится при перезапуске Винды


Ребята, а все-таки можно так сделать smile 

Автор: _hunter 17.8.2006, 15:42
Цитата(Gordon @  17.8.2006,  15:01 Найти цитируемый пост)
Ребята, а все-таки можно так сделать smile 

можно

Автор: Gordon 17.8.2006, 15:47
Цитата

можно


А если не секрет, то как smile 

Автор: _hunter 17.8.2006, 16:05
в секцию RunOnce напиши del "путь к удаляемому файлу"

Автор: GremlinProg 17.8.2006, 16:09
Тема сильно избита.
Цитата(_hunter @  17.8.2006,  18:05 Найти цитируемый пост)
в секцию RunOnce напиши del "путь к удаляемому файлу"

Цитата

The system uses these registry entries to complete the operations at restart in the same order that they were issued. For example, the following code fragment creates registry entries that delete szDstFile and rename szSrcFile to be szDstFile at restart: 

MoveFileEx(szDstFile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
MoveFileEx(szSrcFile, szDstFile, MOVEFILE_DELAY_UNTIL_REBOOT);

Так намного проще, оказывается

Автор: Gordon 17.8.2006, 17:16
Пишу:

Код

AnsiString PathName="C:\\Program Files\\Borland\\CBuilder6\\Projects\\Projects1.exe";
TRegistry *Reg=new TRegistry;    
Reg->RootKey=HKEY_LOCAL_MACHINE;
Reg->OpenKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce",false);
Reg->WriteString("del", PathName);    
Reg->CloseKey();    
delete Reg;


Удаляется только ключ в реестре, может я что-то не так делаю smile 


GremlinProg, 
 
Цитата

MoveFileEx(szDstFile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
MoveFileEx(szSrcFile, szDstFile, MOVEFILE_DELAY_UNTIL_REBOOT);

а как этим пользоваться smile 

Автор: SergeCpp 17.8.2006, 19:05
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/movefileex.asp

If the dwFlags parameter specifies MOVEFILE_DELAY_UNTIL_REBOOT, MoveFileEx fails if it cannot access the registry. The function stores the locations of the files to be renamed at restart in the following registry value:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations


This registry value is of type REG_MULTI_SZ. Each rename operation stores one of the following NULL-terminated strings, depending on whether the rename is a delete or not: 


szDstFile\0\0

or 

szSrcFile\0szDstFile\0
The string "szDstFile\0\0" indicates that the file "szDstFile" is to be deleted on reboot. 

The string "szSrcFile\0szDstFile\0" indicates that "szSrcFile" is to be renamed "szDstFile" on reboot.

Note  Although "\0\0" is technically not allowed in a REG_MULTI_SZ node, it can because the file is considered to be renamed to a null name.

The system uses these registry entries to complete the operations at restart in the same order that they were issued. For example, the following code fragment creates registry entries that delete szDstFile and rename szSrcFile to be szDstFile at restart: 

[C++]

MoveFileEx(szDstFile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
MoveFileEx(szSrcFile, szDstFile, MOVEFILE_DELAY_UNTIL_REBOOT);

Because the actual move and deletion operations specified with the MOVEFILE_DELAY_UNTIL_REBOOT flag take place after the calling application has ceased running, the return value cannot reflect success or failure in moving or deleting the file. Rather, it reflects success or failure in placing the appropriate entries into the registry.

The system deletes a directory that is tagged for deletion with the MOVEFILE_DELAY_UNTIL_REBOOT flag only if it is empty. To ensure deletion of directories, move or delete all files from the directory before attempting to delete it. Files may be in the directory at boot time, but they must be deleted or moved before the system can delete the directory.

The move and deletion operations are carried out at boot time in the same order that they are specified in the calling application. To delete a directory that has files in it at boot time, first delete the files.

Автор: Gordon 17.8.2006, 19:43
Попробую разобраться...

P.S. Жалко я с английским не на "Ты" smile 

Автор: MAKCim 17.8.2006, 19:46
Цитата

Получается, все кто под Unix'ами батники пишут - это не спецы? 

под unix-ом удалить исполняемый файл просто
Код

#include <unistd.h>

int main(int argc, char* argv[])
{
    unlink(argv[0]);
    return 0;
}

Автор: Gordon 17.8.2006, 21:02
Хотелось бы и под виндой удалить...

Автор: BreakPoint 25.3.2010, 13:12
Если кому еще надо, есть статья в которой рассмотрены методы самоудаления исполняемых файлов под Vista и Windows 7:
http://blog.f5soft.com/самоудаление-исполняемых-файлов-vista-7/

Примеры правда на Delphi, но описано все подробно, можно на чем угодно переписать.

Автор: GoldFinch 25.3.2010, 23:36
BreakPoint,
в 6-м методе используется GetProcAddress чтобы получить адреса в другом процессе, это не работает под Vista и Windows 7.

Автор: BreakPoint 26.3.2010, 00:18
Цитата(GoldFinch @ 25.3.2010,  23:36)
BreakPoint,
в 6-м методе используется GetProcAddress чтобы получить адреса в другом процессе, это не работает под Vista и Windows 7.

Код тестировался на Vista и Win7x64 все работает нормально.
GetProcAddress получает адресс в своем просессе, а не в другом. Поскольку стандартные библиотеки загружаются по одним и темже базовым адресам (как правило), то все работает нормально.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)