singlepost

задачка: Как исполняемому файлу удалить самого себя? (решена) << На главную или назад  

В свое время такое задание было вступительным пропуском к расмотрению вакансии на должность системного программиста в одной из фирм… может кому интересно попробовать свои силы в решении…

Необходимо написать функцию которая реализовывала: удаление исполнимого файла с диска в котором эта функция была вызвана. Если сказать проще.. апликуха должна удалить сама себя по завершении работы.

Есть несколько способов решения данной задачи.. самый простой использования *.bat файла, но это в этом случае всю работу сделает командный процессор, а не вызванная функция, что противоречит условию задачи…

67 ответов в теме “задачка: Как исполняемому файлу удалить самого себя? (решена)”

  1. 59
    Денис Гублин ответил:

    цена таки да, $799

  2. 58
    Анатолий Лютин ответил:

    Екатерина Юрьевна Крамаренко
    [skip]
    шесть ноль – это ж старенькая

    Зато самая быстрая и не впадающая в раздумья случайным образом.

    P.S: IMO

  3. 57
    Cyber Max ответил:

    >> шесть ноль – это ж старенькая
    ну это не аргумент! :) темболее что поддерживает все новые компиляторы.. (не знающим не путать… компилит не студия – а компилятор cl.exe в паре с линковщиком link.exe)

  4. 56
    Екатерина Крамаренко ответил:

    ну предлагаю то что есть – пока оно есть очень по дешевке)

  5. 55
    Екатерина Крамаренко ответил:

    ну стоит прилично, поверьте)
    это инициатива майкрософт по поддержке разработчиков, только стартовала она уже давно, и почти у всех партнеров уже все закончилось. а у нас завалялось немножко коробочек. подумала, может кому нужно.

    шесть ноль – это ж старенькая

  6. 54
    Cyber Max ответил:

    >> Ребята, у нас осталось несколько коробок Visual Studio
    Visual Studio 6.0 есть? :) )

  7. 53
    Dante-Kun Desu ответил:

    я понимаю, это спам и всё такое, но неужели студия стоит 20к и 42.5к?

  8. 52
    Екатерина Крамаренко ответил:

    Ребята, у нас осталось несколько коробок Visual Studio по акции с 80% скидкой

    Visual Studio Standard – 4000р.
    Visual Studio Professional – 8500р.

    Кому нужно – пишите мне на e.kramarenko@legalsw.ru или звоните (812) 600-40-41
    Также есть льготные предложения по MSDN
    //legalsw.ru

  9. 51
    Александр Lert ответил:

    Возможно. Во всяком случае, APC, отправленные во все потоки процесса, у меня не выполняются ни в одном потоке после вызова ExitProcess. Так что жизни после ExitProcess пока нет…

  10. 50
    Cyber Max ответил:

    > По идее, kernel32 при завершении процесса выгружается из адресного
    > пространства последним
    Да но логично и правильно с точки зрения системы отпускать проекцию файла процесса, после того как все модули которые им использовались – уже отмаплены из виртуальной памяти процесса, так что мне кажется что в момент выгрузки kernel32.dll файл еще держится системой.

  11. 49
    Александр Lert ответил:

    Да, действительно, можно просмотреть модули. Остается только проблема с защитой.

    Я беру свои слова назад насчет неинтересности, конечно реализация всего этого достаточно интересна ) это я немного разочаровался, я-то решил, что есть способ совсем без других процессов.

    У меня такая мысль была, что можно было-бы вклиниться в вызов DllMain какой-либо библиотеки (того же kernel32). По идее, kernel32 при завершении процесса выгружается из адресного пространства последним (кажется, было упоминание где-то в MSDN), и, в вызове DllMain для kernel32.dll с уведомлением DLL_PROCESS_DETACH мы могли бы выполнить удаление исполняемого файла. А вклиниться можно было бы, ну к примеру, послав самому себе User APC, а затем понадеявшись, что kernel32 будет что-нибудь делать в alertable-режиме, причем как-раз в DllMain ) Ну или что-то типа того.
    Конечно, тут одни допущения, и вообще, нехорошо что-то делать в момент, когда процесс находится в непонятном состоянии. Конкретно эта идея видимо не рабочая.

  12. 48
    Женя Глебов ответил:

    Может как-то так:
    1 программа вызывает компилятор, который компилирует вторую программу, которая через 20 сек запускается и удаляет первую программу.
    А до того как прошло 20 сек, первая программа выключается. ))

  13. 47
    Александр Lert ответил:

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

  14. 46
    Cyber Max ответил:

    >> в задании было сказано делать без посторонних )
    без постороних *.bat

    Ну а вообще да.. алгоритм правильный.
    Можно без помощи постороннего процесса вkernel-mode – отпустить все ссылки на октрытый файл с помощью ObDeferenceObject – но это плохой способ..

  15. 45
    Владимир Шалимов ответил:

    Стер коммент, но все же:

    где вы собираетесь взять лишний процесс?

  16. 44
    Cyber Max ответил:

    >>Проблемы будут с вистой, где kernel32.dll будет лежать в другом
    >>процессе по рандомному адресу,
    Можно энумерировать модули в удаленном процессе, найти kernel32.dll и зная смещения в нашем процессе точек входа в функции получить их адресса в чужем процессе…

    способ номер два: использовать Nt*, Zw* аналоги вместо API функций, и вызывать их напрямую с помощью sysenter. Если MS еще не закрыл эту лазейку и вызвать sysenter можно из любого модуля, а не только из ntdll.dll

  17. 43
    Cyber Max ответил:

    >> где вы собираетесь взять лишний процесс?
    explorer.exe, ctfmon.exe практически всегда запушенны.

  18. 42
    Владимир Шалимов ответил:

    Исключение не заработал, но и файл не удалился. Вставил после слипа MessageBox – и он не вывелся. Очевидно, при вызове return 0 поток автоматом завершается.

  19. 41
    Cyber Max ответил:

    >> Думаю должно сработать, почему бы и нет?
    1)точки входа в Sleep() DeleteFile() могут быть иные нежели в вашем процессе.
    2) Откуда коду__stdcall DelExe(char* FileName) взятся в чужем процессе?
    запушенный поток в чужем процессе стартует с адресса аналогичного вашей функции &DelExe но в своем процессе где может быть что угодно.
    3) Sleep(1000) – так никто не делает, где гарантия что через секунду процесс завершится?

  20. 40
    Александр Lert ответил:

    Неинтересно потому что нужен еще процесс ) в задании было сказано делать без посторонних )
    Одного вызова да, маловато
    Примерно такая схема:
    OpenProcess + VirtualAllocEx + WriteProcessMemory – записали специально подготовленный машинный код в процесс, вместе с кодом можем передать дескриптор своего процесса
    CreateRemoteThread – создали удаленный поток
    ExitProcess – закрываем свой процесс
    Что делает записанный код: WaitForSingleObject на дескрипторе процесса, затем DeleteFile, затем VirtualFree + ExitThread (здесь видимо делаем известный трюк с запихиванием аргументов и адресов возврата в стек заранее, чтобы не освободить память кода в момент его исполнения).
    Проблемы будут с вистой, где kernel32.dll будет лежать в другом процессе по рандомному адресу, и мы не сможем заранее знать адреса нужных функций, а больше проблем не вижу.

  21. 39
    Владимир Шалимов ответил:

    тогда базовая идея (знаю, что нерабочая, но как идея, псевдокод):

    void threadFunc(){
    Sleep(1000);
    DeleteFile(GetModuleFileName());
    }

    int main(){
    CreateThread(/*не помню всех параметров*/, threadFunc);
    return 0;
    }

    Пошел компилить…

  22. 38
    Александр Lert ответил:

    Если CreateRemoteThread (или любой другой метод инжекции) разрешается использовать, то тогда все понятно, да и неинтересно, потому что нужен чужой процесс.

  23. 37
    Cyber Max ответил:

    почему CreateRemoteThread не интересно? одного вызова этой функции маловато :) Столько нюансов… читай коменты ниже :)

  24. 36
    Мопедий Дрынов ответил:

    не ну зачем лоадлайбрари? просто пишем функцию удаления с задержкой конечно же, типа (точного синтаксиса функций не помню, по памяти пишу):
    DWORD __stdcall DelExe(char* FileName)
    {
    Sleep(1000); //что б наша прога успела закрыться за это время
    DeleteFile(FileName);
    }
    и ниже вызываем ее в потоке
    CreateRemoteThread(hProcess,&DelExe,FileName,..);
    и после этого закрываем нашу прогу
    Думаю должно сработать, почему бы и нет?

  25. 35
    Cyber Max ответил:

    тогда базовая идея:

    void threadFunc(){
    Sleep(1000);
    DeleteFile(GetModuleFileName());
    }

    Не.. исключение можешь заработать..

  26. 34
    Александр Павлов ответил:

    >>>возможно, можно снять Виндовую блокировку файла и удалить его?
    Есть. Небезизвестная утилита Unlocker так и делает

  27. 33
    Cyber Max ответил:

    >> может чеиез CreateRemoteThread
    Уже ближе, только метод Дж.Рихтера на примере LoadLibrary, который Вы тут упоминаете в чистом виде работать не будет, нужно еще кое что…

  28. 32
    Мопедий Дрынов ответил:

    может чеиез CreateRemoteThread,подцепиться к какому-либо уже запущенному процессу, подсунув в качестве точки входа функцию удаления?

  29. 31
    Cyber Max ответил:

    >> На правах идеи – дело связано с потоками?

    Да.

    >> Если используется многопоточность, точно ли при вызове return 0;
    >> всепотоки прекращают работу?
    Не факт… как бы исключение не схлопотать, если какой то поток продолжит исполнения кода, уже отсутствующего в памяти, если система начнет зачистку.

  30. 30
    Фёдор Кеменов ответил:

    ..

  31. 29
    Cyber Max ответил:

    > А Ето не тоже самое что и спрятать его или переименовать или вообще
    > выполнять какие либо действия над ексешником?
    Удалить имеется в виду – обычная операция удаления.

    > Здесь точняк нужно Блокировку Операционки снимать! Да ?
    Как один из вариантов… но это путь через Ж..

    >> скопировать саму себя в оперетивку и запустить себя из оперетивки,
    >> наподобие как упаковщики делают
    Они лишь разворачивают секции кода и данных, свясь с файлом все равно существует, хотя бинарно он уже не соотвествует образу в памяти.

  32. 28
    Vitaly Ch ответил:

    > Если программа находится в оперативной памяти, то можно наверное просто очистить её на диске :) Т.е. записать 0 в каждый занимаемый программой бит ))

    наверное это и есть решение. скопировать саму себя в оперетивку и запустить себя из оперетивки, наподобие как упаковщики делают, а потом снести файл как неиспользуемый.

    2 Anatoly Lyutin:

    под линуксом просто удаляеш сам себя и ВСЕ. все остальное сделает линукс за тебя причем ПРАВИЛЬНЫМ образом.

  33. 27
    Алексей Руденко ответил:

    > наверное это и есть решение. скопировать саму себя в оперетивку и запустить себя из оперетивки, наподобие как упаковщики делают, а потом снести файл как неиспользуемый.

    А как такое провернуть?

  34. 26
    Никита Токарчук ответил:

    а я предлагал сделать как по ссылке Евгения
    по моему самое легкое решение :)

  35. 25
    Анатолий Лютин ответил:

    Хм, как бы я сделал это под linux:
    1. fork
    2. рабочая директория – /
    3. закрываем все дескрипторы (становимся демоном)
    4. remove() исходный файл.

    P.S:
    Как-нибудь проверю – канает ли.

  36. 24
    Евгений Тихонов ответил:

    //www.cyberguru.ru/cpp-sources/algorithms/udale...

  37. 23
    Nicos Ivanus ответил:

    А Ето не тоже самое что и спрятать его или переименовать или вообще выполнять какие либо действия над ексешником? Здесь точняк нужно Блокировку Операционки снимать! Да ?

  38. 22
    Евгений Тихонов ответил:

    Если программа находится в оперативной памяти, то можно наверное просто очистить её на диске :) Т.е. записать 0 в каждый занимаемый программой бит ))

  39. 21
    Александр Бохан ответил:

    выполнить команду форматирования диска))

  40. 20
    Владимир Шалимов ответил:

    На правах шутки и подписки на тему – выполнить некое действие, которое местный антивирь определит как нелегальное, предварительно выставив антивирусу флаг "удалять вирусы без предупреждения".

    На правах идеи – дело связано с потоками? Если используется многопоточность, точно ли при вызове return 0; все потоки прекращают работу?

  41. 19
    Александр Lert ответил:

    Не, ну мож подумаем сначала?

  42. 18
    Dante-Kun Desu ответил:

    Т___Т

  43. 17
    Александр Lert ответил:

    Только не говори раньше времени :)

  44. 16
    Dante-Kun Desu ответил:

    поведай же

  45. 15
    Dante-Kun Desu ответил:

    нет, говори

  46. 14
    Алексей Руденко ответил:

    возможно, можно снять Виндовую блокировку файла и удалить его?

  47. 13
    Cyber Max ответил:

    один из верных знаю :)

  48. 12
    Cyber Max ответил:

    >> возможно, можно снять Виндовую блокировку файла и удалить его?
    В общем то можно и так, но насколько я знаю.. user-mod'ом тут не обойдешся.
    Есть вполне нормальный легальный способ это сделать… чтобы никого не обманывать (ну я систему имею ввиду)

  49. 11
    Cyber Max ответил:

    >> //www.progz.ru/forum/index.php?showtopic=28100
    1-й способ не работает.
    2-й способ требует перезагрузки
    3-й способ требует перезагрузки
    4-й способ требует перезагрузки
    5-й способ – bat файл (не использовать)
    6-й способ – опятьже возложение удаления на командный процессор
    7-й способ – рабочий, но с созданием дополнительного процесса
    8-й способ – устарел, не работает начиная с WinXP

  50. 10
    Алексей Руденко ответил:

    Cyber Max, а ты знаешь верный способ?

  51. 9
    Никита Токарчук ответил:

    может прога сделает дело и запустит бат файл который ее удалит?)

  52. 8
    Алексей Руденко ответил:

    //www.progz.ru/forum/index.php?showtopic=28100

  53. 7
    Cyber Max ответил:

    >> Уточните требования!
    Ну что то типа DeleteItself("путь к самому себе");

    сотвествено что подразумевается вызов
    return DeleteItself();

    >> должно небось из любого места работать
    Всмысле?

    >> А еще уточните ОС конечно.
    Вся линейка Windows начиная с Win 2000.

    >> Наверное есть какой нибудь ВинАпи вызов для отложенного
    >> удаления файлов
    Нет такого API.

    >> или можно написать программу которая будет создавать и запускать
    >> другую программу, которая как только данная прога завершится
    >> удалит её файл.

    А кто удалит ту вторую программу которая удалит первую? Короче если еще конкретнее.. представим приложение которое должно запустить и после завершения работы удалить все следы пресутсвия себя на диске, тоесть удалить сама себя.

  54. 6
    Марина Гаврилина ответил:

    В линухе элементарно пишется ))

  55. 5
    Андрей Петров ответил:

    Уточните требования! Что не зазорно подать параметром в эту функцию? Если можно string – то путь до .ехе и все путем) Ясное дело все не так просто, должно небось из любого места работать, с любым именем экзешника… А еще уточните ОС конечно.

  56. 4
    Алексей Руденко ответил:

    Думаю это задача для системных программистов под винду, но и под линух интересно решение :-)
    Наверное есть какой нибудь ВинАпи вызов для отложенного удаления файлов, илиможно написать программу которая будет создавать и запускать другую программу, которая как только данная прога завершится удалит её файл.
    Как-то так я думаю, конкретнее надо гуглить

  57. 3
    Dante-Kun Desu ответил:

    и я подпишусь :3

  58. 2
    Vitaly Ch ответил:

    как будто тривиально …

  59. 1
    Алексей Руденко ответил:

    на комменты подпишусь…

Клуб программистов работает уже ой-ой-ой сколько, а если поточнее, то с 2007 года.