Ступень1 выбор случайного расшифровщика из списка
Идея: создаем некоторое количество шифровщиков/расшифровщиков, выбираем случайный шифровщик и зашифровываем тело вируса вместе с остальными шифровщиками/расшифровщиками. В каждом последующем поклонении расшифровщик расшифровывает вирус, передает управление основному телу, а перед внедрением выбирает случайный шифровщик, которым и зашифровывает его. Код вируса меняется на 100% и "визуально" опознать зараженный файл уже не представляется возможным.
Правда, поскольку количество расшифровщиков всегда конечно (даже если оно очень-очень велико), сигнатурный поиск остается достаточно эффективной мерой противодействия. Антивирус просто заносит в базу "фотороботы" всех расшифровщиков и… хана вирусу. Правда, тут есть одно небольшое "но". Расшифровщики различных вирусов (и даже честных программ с навесной защитой) обычно похожи как две капли воды и потому в их детектировании нет никакой пользы. Антивирус вынужден привлекать эмулятор, имитирующий выполнение расшифровщика и раскриптовывающий основной вирусный код. Если распаковщик содержит антиотладочные команды или использует машинные инструкции, не поддерживаемые эмулятором, антивирус обломается по полной программе. Здесь, правда, появляется проблема типа "грабли", на которые наступают те, кто борется с эмулятором. Чем больше антиотладочных приемов содержит расшифровщик, тем выше его уникальность и, следовательно, надежнее детектирование. Строго говоря, первая ступень — это еще не полиморфизм. Такие вирусы называют псевдо-полиморфными или олигоморфиками, но все-таки это уже большой шаг вперед.
Какие проблемы возникают при кодировании? Во-первых, код расшифровщика должен быть полностью перемещаемым. Тут базара нет! Написать такой расшифровщик несложно. Во-вторых, расшифровщик должен как-то определять начало и конец зашифрованного фрагмента. Это тоже решаемо. Шифровка не изменяет длину данных, и размер шифроблока будет постоянен для всех расшифровщиков, так что его можно вычислить еще на стадии ассемблирования.
В-третьих, для каждого шифровщика должен существовать парный расшифровщик или же выбранный криптоаглгоритм должен быть симметричен, т. е. повторная шифровка зашифрованного текста расшифровывает его (не путать с симметричной криптографией — это совсем из другой области!)
Свойством "симметрии" обладают операции NOT; XOR X, любая константа; ROL/ROR X, 4 и некоторые другие арифметическо-логические операции, например, ADD byte,100h/2. Простейший симметричный шифровщик может выглядеть так (предварительно необходимо открыть сегмент кода на запись, что можно сделать функцией VirtualProtect):
MOV ESI, offset body_begin
MOV EDI, ESI
MOV ECX, offset body_end - body_begin
my_begin:
LODSB
XOR AL, 66h
STOSB
LOOP my_begin
body_begin:
; // тело вируса со всеми остальными шифровщиками
body_end:
Листинг 4 симметричный расшифровщик на основе XOR
А вот другой расшифровщик:
LEA EAX, body_end
my_begin:
NOT byte ptr DS:[EAX]
SUB EAX, offset body_begin +1
PUSHF
ADD EAX, offset body_begin
POPF
JNZ my_begin
body_begin:
; // тело вируса со всеми остальными шифровщиками
body_end:
Листинг 5 симметричный расшифровщик на основе NOT
Несимметричные шифровщики/расшифровщики устроены сложнее, зато здесь наблюдается гораздо большее разнообразие. Можно использовать практически любую комбинацию арифметическо-логических команд, только никакого смысла в этом нет. Все равно, если антивирус доберется до файла, он его схватает.