Вирус -- независящая от пользователя программа, направленная на самораспространение.
Под свойством независимости будем понимать отсутствие в вирусе специально написанных для этого функций, позволяющих пользователю управлять работой вируса.
Под способностью к самораспространению(направленностью на самораспространение) будем понимать присутствие(и использование) в вирусе специально написанных функций для распространения [копий] вируса.
Важными действиями, влияющими на способность к распространению, являются различные методы затруднения обнаружения вируса, как то -- стелс-алгоритмы, периодическое приостанавливание активности, полиморфизм, и прочее.
Под полиморфизмом вируса понимается существование одного вируса в нескольких формах. Это свойство мы далее и рассмотрим.
Итак, изменение формы вируса возможно на тех уровнях информации, с позиции которых можно рассматривать(различать) любые компьютерные программы, а именно:
Наиболее простой уровень полиморфизма, существует в двух проявлениях:
Детектирование таких вирусов может достигаться:
"Пермутирующие", они же "метаморфные" вирусы.
Идея заключается в том, чтобы изменять команды/группы команд на функционально им эквивалентные(замена), и/или менять команды/группы команд местами(перестановка).Очевидно, детектирование таких вирусов непосредственно по сигнатуре невозможно, но зная правила изменения одной копии на другую можно специальным образом обработав код получить некоторый единый для всех копий "скелет" вируса и применить сигнатуру к нему.
Остается возможным также статистический (покомандный) анализ тела вируса и детектирование по функциональной сигнатуре.
О реализации.
Здесь пока есть два основных подхода к технологии мутирования вируса:
Кстати, здесь существует интересная проблема о степени зашифрованности этого самого прообраза и соответственно возможности его детектирования.
Назовем их функционально мутирующие вирусы.
Такой уровень на практике пока еще не был реализован.
Смысл мутации заключается в том, чтобы затруднить детектирование вируса по функциональной сигнатуре.
Дело в том, что при эмуляции/трассировке вируса, его функциональные вызовы могут быть закодированы например так:
mov ah, 4Eh ; найти файл int 21h ; вызов: 21 4E jc ... call infect_file ... infect_file: ... mov ah, 3Dh ; открыть файл int 21h ; вызов: 21 3D ... mov ah, 40h ; записать в файл int 21h ; вызов: 21 40 ...
функциональна сигнатура: 21 4E 21 3D 21 40
Очевидно, что прерывания/процедуры api, которые вызываются вирусом, представляют неплохую информацию для его детектирования.
Консенсус здесь достигается при помощи генератора случайных чисел, то есть следует создать нечто вроде событий, которые будут делится на необходимые и случайные, перемешать их, и вызывать соответствующим образом.
Пожалуй самый сложный уровень, единственный за который не следует браться ;-)
Назовем их алгоритмически мутирующие вирусы.
Алгоритм работы программы (вместе с результатом ее работы), есть, наверное, самый высокий уровень информации о программе.
И как бы мы ни извращались на уровнях команд и функциональных вызовов, все равно файл с расширением .EXE и внутренним форматом PE будет найден, открыт, и в него произойдет запись. Либо нечто в этом роде.
Теоретически обойти эту проблему можно, связав, например в один сотню разных вирусов, производящих самые разные действия, и переходя от одного алгоритма работы к другому случайным образом.
Можно пойти по весьма депрессивному пути, раз за разом "выкидывая" из вируса процедуры и функции(как части алгоритма), естественно, в начале создав некоторую их избыточность.
Можно попытаться создать анализатор кода, который во внешних файлах найдет некоторый код, выполняющий _в частности_ еще и нужные нам действия, и заменить этим кодом часть собственного. Но это уже из области фантастики.
В глобальном смысле, я сегодня вижу такую ситуацию:
Вылечить можно отнюдь не все вирусы, достигается это технологиями Seek&Destroy(вставка ошибок в случайные места программы и обработка их вирусом), UEP (Unknown Entry Point) и прочими гадостями.
В частности, есть вот такая интересная техника заражения:
Выбирается точка в теле программы, в которую будет записан переход на
вирус.
В случае нормального вируса, это просто точка входа (entrypoint) программы.
В случае хорошего вируса, это случайно выбранная точка программы. (UEP)
Если вирус еще более правильный, то переход произойдет на полиморфный
расшифровщик.
А вот если вирус из этой самой точки _заберет_ с десяток инструкций,
а потом либо размешает их в полиморфном декрипторе,
либо сохранит в себе (с последующим восстановлением, понятно) -- то это совсем правильно.
А вот детектировать можно любой (или почти любой ;-) вирус, вопрос только КОГДА.
Здесь есть несколько параллельных временных стадий.
Длительность всех трех стадий некоторым образом связана с такими "качествами" вируса, как:
Здесь следует сказать пару слов о деструкции. Так вот деструкция, несомненно, нужна. ;-) Но в меру. Например всякая рандомная деструкция снижает маскировку, зато "умная" деструкция (типа пришел новый антивирус или юзер пишет письмо к аверам) усиляет защиту и усложняет лечение.
Также можно хранить вирус в нескольких файлах, но это может сильно затруднить распространение.
Можно ввести собственные сигнатуры на антивирусы, и "убивать", а лучше патчить их при загрузке. В этом случае все сводится к ситуации "кто первый "встал в резидент", тот и рулез".
Можно при обнаружении антивируса совершать "самоубийство" (полное либо частичное -- удалять/изменять часть кода), тогда вирус попадет в антивирусную контору намного позже(а еще и не весь), и соответственно более "счастливые" копии сумеют распространиться подальше.
Можно при ситуации "антивир хочет нас вылечить" совершать убийство (ритуальное) пользователя вместе с компьютером.
...не надо ;-)