Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > Самоудаление |
Автор: Peter 27.8.2003, 11:46 | ||
Пишу:
Компилю под 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 |
А зачем его удалять ![]() В нём же нету никакой полезной инфы - пускай себе болтается ![]() ![]() ![]() ![]() ![]() ![]() |
Автор: 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 | ||
В exe-шнике полезная инфа - только для дизассемблирования, а если надо скрыть следы, то этот способ не катит... По-моему, можно где-то в реестре записать строковое значение с именем файла и файл удалится при перезапуске Винды |
Автор: oleg1973 28.8.2003, 17:45 |
естественно можна сделать батник который уничтожит ехе и потом сам себя но имхо ето не по програмерски ![]() нада сделать так: invoke CreateProcess,0,cline,0,0,0,NORMAL_PRIORITY_CLASS,0,0,sinfo,pinfo invoke ExitProcess,0 cline: db 'cmd ( а вот тут нада задержку сделать) del main.exe',0 вот а как задержку сделать сами думайте ![]() |
Автор: 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 |
Где-то у меня инфа по удалению, была. Или на форуме, где-то, или у меня на дискетках, посмотрю, может и найду ![]() |
Автор: 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; Это насчет "где то в реестре" ![]() После перезагрузки винды не будет не екзешника ни записи в реестре ![]() |
Автор: mr.DUDA 30.8.2003, 23:01 |
Зато до перезагрузки любой мало-мальски знакомый с реестром чел может "запасти" такой ключ. Нет уж, легче сделать "deleter.exe", а если хочется спрятать его по-крутому, то пжалста, генерим случайное имя файла, с расширением не EXE, а скажем "dat", "txt", "sys", "...", прячем в WINDOWS/SYSTEM (или SYSTEM32, DRIVERS, INF, HELP, Temporary Internet Files в конце концов ![]() |
Автор: HexoGenus 1.9.2003, 07:50 |
Я вообщето не для того что бы что то прятать предложил, а для легального самоудаления ![]() Но уж если тебе действительно хочется замести следы то можно использовать мой способ для того что бы "deleter.exe" мог самоуничтожится ... и даже если его теперь можно обнаружить через реестр то толку то... он свое черное дело уже сделал ... ![]() |
Автор: Baa 1.9.2003, 10:40 |
http://forum.vingrad.ru/index.php?act=ST&f=1&t=12088&unread=1&st=0entry77762 |
Автор: 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...
|
Автор: Baa 3.9.2003, 14:57 |
Peter, а чем тебе мой пример самоудаления не понравился? |
Автор: Peter 8.9.2003, 16:26 | ||
Толстый больно ![]() У Nastya гораздо короче. |
Автор: Baa 8.9.2003, 16:47 |
Peter, зато у меня без всяких временных файлов. ![]() |
Автор: mr.DUDA 8.9.2003, 19:50 |
Peter, и без возможных багов с батниками (например, запуская батник мы видим чёрное окно, которое ещё к тому-же и не всегда закрывается при окончании работы батника), а еще не факт что батник удалится, да и наконец: если батник начал работать, а EXE'шник по каким-то своим причинам еще не закончил (ну не может окно закрыть до сих пор из-за пользователя, или там файл сохраняет при закрытии, а файл на 3 метра) --- то батник не удалит EXE'шник, т.к. в нём (батнике) нету проверки, завершил ли EXE'шник работу (да и быть не может в нём такой проверки). Понял теперь, в какой косяк ты попал : ![]() А пример от Baa, хоть и кажется тебе чересчур сложным, на самом деле всё это уже учитывает ![]() ![]() |
Автор: DENNN 9.9.2003, 12:52 | ||
Достаточно написать батник так, чтоб вызов exe выполнялся из него, тогда управление ему вернется только после того как exe завершит свою работу. |
Автор: mr.DUDA 9.9.2003, 18:28 | ||
Решается обратная задача (из EXE создаётся батник, который запускается по CreateProcess) |
Автор: Peter 12.9.2003, 14:50 | ||
Как раз-таки, когда батник пытается грохнуть exe-шник, он потом проверяет, остался ли файл. Пока exe-шник не кончит работать, доступ к нему операционка не даст. Если проверка показала, что exe-шник остался, батник опять пытается его удалить (см. текст самого батника) - и так до победного конца. |
Автор: Unregistered 24.9.2003, 13:43 |
"зашедулить" - это дать планировщику задание ![]() |
Автор: Peter 24.9.2003, 16:22 |
Та самоудаляющаяся программа (с батником) имеет недостатки: не воспринимает русские буквы, поскольку батник не понимает виндоусовскую кодировку. Ну, не вставлять же самому перекодировщик! |
Автор: Gordon 17.8.2006, 15:01 | ||
Ребята, а все-таки можно так сделать ![]() |
Автор: _hunter 17.8.2006, 15:42 |
можно |
Автор: Gordon 17.8.2006, 15:47 | ||
А если не секрет, то как ![]() |
Автор: _hunter 17.8.2006, 16:05 |
в секцию RunOnce напиши del "путь к удаляемому файлу" |
Автор: GremlinProg 17.8.2006, 16:09 | ||
Тема сильно избита.
Так намного проще, оказывается |
Автор: Gordon 17.8.2006, 17:16 | ||||
Пишу:
Удаляется только ключ в реестре, может я что-то не так делаю ![]() GremlinProg,
а как этим пользоваться ![]() |
Автор: 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. Жалко я с английским не на "Ты" ![]() |
Автор: MAKCim 17.8.2006, 19:46 | ||||
под unix-ом удалить исполняемый файл просто
|
Автор: 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 | ||
Код тестировался на Vista и Win7x64 все работает нормально. GetProcAddress получает адресс в своем просессе, а не в другом. Поскольку стандартные библиотеки загружаются по одним и темже базовым адресам (как правило), то все работает нормально. |