AutoRunKiller II
К новому 2011 году, я написал AutoRunKiller II, правда идея появилась не сразу, началось все с написания вредилки-червя, на её основе (практически половина функций) я сделал AutoRunKiller, но это была только первая версия, её можно назвать "наброском", ну а теперь я расскажу, как можно в домашних условиях изготовить убийцу червячков и не платить за платные аналоги...
Очень благодарен нашему форумчанину WhiteP, генератор идей, также помогал библиотеками на C++ и вообще помогал мне, респект ему, очень хороший и отзывчивый парень!
Ингридиенты:
- Delphi 2010 или выше, 1-на сцуко
- голова, 1-на тыква
- руки, 2-ве тяпки
С чего начать? Учим сворачиваться в трей и определять момент подключения съемного накопителя...
Начать надо с простых вещей, надо научить программу сворачиваться в трей и подключить для трея контекстное меню...
Бросим PopupMenu1 и создадим меню с двумя надписями: "восстановить" и "закрыть", ниже код для нажатий:
procedure TAutoRunKiller.N1Click(Sender: TObject);
begin
mayClose:=False; //теперь снова нельзя закрыть программу
AutoRunKiller.Show; //восстанавливаем окно
Application.Restore;
Application.BringToFront; //помещаем его поверх всех окон
Application.ProcessMessages;//на всякий случай обрабатываем системные сообщения
end;
procedure TAutoRunKiller.N3Click(Sender: TObject);
begin
AutoRunKiller.Close; //закрываем программу - для этого все готов
end;
Для TrayIcon1 присвоим обработчик нажатия кнопки "восстановить"...
Теперь, пользователи очень любят когда программы автоматически сворачиваются в трей после запуска, моя программа после запуска, прячется через 1-ну секунду в трей...
procedure TAutoRunKiller.OnMinimizeProc(Sender: TObject);
begin
AutoRunKiller.Close;
end;
procedure TAutoRunKiller.FormCreate(Sender: TObject);
begin
//первичные настройки
TrayIcon1.Visible:=true;
AutoRunKiller.ClientHeight:=401;
AutoRunKiller.ClientWidth:=699;
//перехватываем событие сворачивания, а при сворачивании выполняем код: Close;
Application.onMinimize:=OnMinimizeProc;
//учим программу определять момент подключения съемного накопителя
Result := False;
Size := SizeOf(DEV_BROADCAST_DEVICEINTERFACE);
ZeroMemory(@dbi, Size);
dbi.dbcc_size := Size;
dbi.dbcc_devicetype := DBT_DEVTYP_DEVICEINTERFACE;
dbi.dbcc_reserved := 0;
dbi.dbcc_classguid := GUID_DEVINTERFACE_USB_DEVICE;
dbi.dbcc_name := 0;
r := RegisterDeviceNotification(AutoRunKiller.Handle, @dbi, DEVICE_NOTIFY_WINDOW_HANDLE);
if not Assigned(r) then ShowMessage('Error Register Message');
//прячем в трей программу, у таймера интервал = 1000, выполняет код: Close;
Timer3.Enabled:=true;
end;
Вроде основное есть, теперь необходимо набросать функцию поиска файла-червя, для этого необходимо исследовать файл AutoRun.inf...
Ищим червя...
Для начала, нам необходимо объявить 2-ве функи:
private
{ Private declarations }
procedure WMDeviceChange(var Msg: TMessage); message WM_DEVICECHANGE;
procedure OnMinimizeProc(Sender:TObject)
Теперь мы можем смело писать функу поиска, но...
...что же это, при попытке вылечить диск после его подключения, у нас происходит исключение..... =\
На сколько я понял, все дело в том, что сигнал о подключении поступил нашей программе, но само оборудование еще не готово к эксплуатации (по сути, даже буква еще не присвоена), поэтому, необходимо произвести лечение диска, через какую-то задержку, с этим проще справится таймер...
procedure TAutoRunKiller.WMDeviceChange(var Msg: TMessage);
var
devType: Integer;
Datos: PDevBroadcastHdr;
begin
if (Msg.wParam = DBT_DEVICEARRIVAL) or (Msg.wParam = DBT_DEVICEREMOVECOMPLETE) then
begin
Datos := PDevBroadcastHdr(Msg.lParam);
devType := Datos^.dbch_devicetype;
if devType = DBT_DEVTYP_DEVICEINTERFACE then
begin // USB Device
if Msg.wParam = DBT_DEVICEARRIVAL then
begin
//ShowMessage('Устройство подключено!');
Timer1.Enabled:=true;
end else
begin
//ShowMessage('Устройство отключено!');
end;
end;
end;
end;
procedure TAutoRunKiller.Timer1Timer(Sender: TObject);
var
d: dword;
i: byte;
s: string;
fin: boolean;
begin
Timer1.Enabled:=false;
d := GetLogicalDrives;
for i := 2 to 26 do
if 1 shl i and d > 0 then //получаем букву съемного диска
if GetDriveType(PChar(chr(i+65)+':\')) = DRIVE_REMOVABLE then begin
s := LowerCase(chr(i+65));
s:=s+':\';
try
//процедура лечение съемного накопителя
AutoRunKill(s,fin);
except
fin:=false;
end;
end;
end;
Закругляемся...
Ну вот, тепперь ваша программа может сворачиваться, разворачиваться и главное, лечить съемные диски, но это далеко еще не все, для большего функционала, необходимо еще многое реализовать:
+ Реализовать возможность отключения защиты
+ Т.к. после лечения флэх, изменения приходят после "перевтыкании" флэшки, возможность указания пользователем, автоматического извлечения (если было произведено лечение)
+ Создавать "неудаляемые" файлы на съемном диске, что позволяет не заражаться червями
+ Реализовать возможность автоматического (программного) открытия флэшки проводником, что полностью безопасно
+ Реализовать возможность отключения "Автозапуск Windows"
+ Реализовать "белый список" (позволяет указать, например, имя программы вашего инсталятора софта, который удалять незя)
+ Реализовать "черный список" (шатать хлам на съемном накопителе, позволяет указывать папки/файлы на постоянное вшатывание при обнаружении, например, папка "Reciler" создающаяся каким-то вирусом)
+ Добавить возможность включения/отключения автозапуска
+ Реализовать возможность тихого режима защиты
+ Запуск служебного ПО
+ Разблокировка Реестра/Диспетчера задач
+ Поддержку скинов (т.к. еслиб я это не сделал, меня бы убили за плагиат шкурки от Kav7
)
+ И многое другое
+ Учесть это все и переработать процесс лечения
Что у нас получилось в итоге?
Комментарии
27 комментария(ев)Дата: ЧТ, 05/05/2011 - 15:53
1) Я говорил, говорю и буду говорить, что нужно приводить или хотя бы стараться примерно приводить код к единому стандарту. Хотя бы пользоваться сочетанием клавиш Ctrl + D (автоформатирование кода). Очень сложно другим людям код разобрать думаю будет.
На мой взгляд она лишняя тут совершенно.
2) Описание процедуры
Procedure AutoRunKill(s: string; var fin: boolean);можно было запихнуть в секцию private формы AutoRunKiller, тем самым сама процедура могла бы выглядеть так:
Procedure TAutoRunKiller.AutoRunKill(s: string; var fin: boolean);и таким образом внутри тела процедуры не нужно будет каждый раз писать:
AutoRunKiller.QPanel1.Edit;...
AutoRunKiller.Faily.First;...
AutoRunKiller.Memo2.Lines[mi];3) В коде неохота разбираться, но вот эта строчка убила:
Application.ProcessMessages;//на всякий случай обрабатываем системные сообщенияКакой всякий случай на выходе из процедуры
Но это все пустяк, надо разбирать сам алгоритм. С тем что я привел жить то можно
Дата: ПТ, 06/05/2011 - 03:24
ЗЫ - не убивайте меня за goto...
Дата: ПТ, 06/05/2011 - 13:33
интерфейс клёвый, да и вообще классно всё сделано, потом посмотрю на работоспособность
Дата: ПТ, 06/05/2011 - 14:15
Интерфейс с Касперского скопирован
Дата: ПТ, 06/05/2011 - 13:44
Знай наших Казахстанцев! Молодец, DrBlack!
Дата: ПТ, 06/05/2011 - 16:26
а главное, программирование антивирусов теперь не кажется непосильной задачей...
Дата: ПТ, 06/05/2011 - 18:44
Тоесть проект тоже не ваш? Можете не отвечать
Дата: ПТ, 06/05/2011 - 20:50
...хорошо бы продумать защиту самой утилиты от заражения.
p.s.: что касаемо самого autorun.inf есть любопытный метод, который можно использовать как дополнение к блокировке автозапуска (уже известным способом)
Дата: ПТ, 06/05/2011 - 22:41
Я отключаю вообще автозапуск в своей системе со всех носителей.
Дата: ПТ, 06/05/2011 - 23:26
я не о ключах NoDriveAutoRun и NoDriveTypeAutoRun или через gpedit, тут немножко другое