ZF

                           Вакцинатор Рувакцин.
                              (c) 1998 Ruwa


                           Идейные размышления

    С легкой руки одного приятеля (А.Татуков) в мой башке  засела мысль
написать   вакцинатор....  Идея  вакцинации  сама  по  себе  это  очень
интересная идея, в плане борьбы с вирусами. К чему страдать от ожидания
дополнений  к  антивирусным  средствам  которые  станут ловить и лечить
новые вирусы или  их  легкие  изменения,  достаточно  просто  подцепить
программку    которая    будет    контролировать   состояния   основных
"стратегических" фрагментов  файла.  Вот  и  занялся  я  этой,  кххммм,
ерундой.......

    Идея достаточно  проста,  но  от  чего-то  чайники  не  очень любят
вакцинироваться (впрочем как и ежедневно запускать прогаму  Adinf  ;)).
Цикл   работы   такой  программы  достаточно  прост:  она  перехватыват
управление на себя и проверят начало программы-носителя с ее  копией на
диске.  Если  вирус  сел  поверх  вакцины,  то естесно упраление первым
получит  вирус,  но  (имеются  в  виду   нормальные   вирусы,   которые
воостанавливают первоначальное состояние проги) после завершения работы
вируса управление получает вакцина и  она  сравнивает  начало  прогаммы
(jmp  вакцина) в ___памяти___ с тем что находиться в этом же __файле__,
но на диске (а на диске будет jmp вирус).

    Этот способ на будет  работать  при  резидентных  вирусах,  которые
будут отслеживать открытие файла 3Dh и воостановливать файл !!!!!

    Далее все  просто,  вакцина восстанавливает начальные байты (ставит
jmp вакцина) и корректирует длину файла !


                    Техническая реализация

    Я не  стал публиковать полностью рабочую версию вакцинатора (хи-хи,
по той простой причине что она еще не готова  ;)).  И  представляю  так
сказать рабочий скелет !!!!  Итак вакцинатор для СОМ файлов -- Рувакцин
;)) Рувакцин прекрасно вел себя на всех вирусах которые имеются  в моей
коллекции, он обнаруживал и воссанавливал оригинальную прогамму.

    Рувакцин не  проходил  еще "мощной" проверки на предмет оптимизации
кода, так что не надо кидать в меня камнями, если кто-то увидит как что
-то можно сделать короче....

    В вакцинаторе  сделана антиэвристность ;)) Так что Паутиныч не орал
на него...  "кажись вирус,  кажись...".  Осталные  антивири  вели  себе
деликатно и не ругались.

    На момент   публикации   оставлен  ряд  недоработок  и  технических
неточностей (ну дык, берете и сами пишите ;)):

    - программа будет некорректно  восстановлена,  если  вирус  шифрует
фрагмент тела программы;
    - не очень корректна инсталяция вакцины  на  программу,  в  смысле:
установка  вакцины,  последующее  заражение вирусом,  и опять установка
вакцины,  том  плане  что  возможно  многократное  повторение   запуска
программы и она все будет лечиться,  лечиться и лечиться.... до полного
излечения ;))
    - "нарабочесть"  вакцины  если какой-то вирус стерет имя прогаммы в
переменной окружения, но этот ньюанс это вообще.... просто зло ;))

    все замечания,   пожелания,   обругания,   целования....    (нужное
подчеркнуть) жду на valery@ene.pcpes.elektra.ru


            Вакцинатор Рувакцин (исходник)        (c) 1998 Ruwa

;Cut - резать здесь
model tiny
locals
jumps

LenComBuffer EQU 15
LenBuffer    EQU 30

FileExe      EQU 1
FileCom      EQU 2
Set          EQU 0
ReSet        EQU 1


dataseg
mode     db ?
buffer   db LenBuffer*2 dup(0)
fname    db 13 dup (0)

err1    db 13,10,"Не могу открыть файл",13,10,24h
err2    db 13,10,"Вакцинация ЕХЕ файлов пока не реализована K",13,10,24h
err3    db 13,10,"Рувакцин _уже_ установлен",13,10,24h
err4    db 13,10,"Файл не защищен рувакцином",13,10,24h
msg1    db 13,10,"  Рувакцин установлен",13,10,24h
msg3    db 13,10,"  Рувакцин снят",13,10,24h
help    db "RUVACCIN имя вакцинируемого файла",13,10
        db "                 /U снять вакцину",13,10
        db " (c)97 Ruwa Entertainment",13,10,24h

codeseg
startupcode
        call CMDLine
        jnc CMD_OK
        lea dx, help
        mov ah,9
        int 21h
        int 20h
CMD_OK:
; читаем атрубуты файла
        mov ax,4300h
        lea dx,fName
        int 21h
        jnc FileOK
        lea dx, err1
        mov ah,9
        int 21h
        int 20h
FileOK:
; сохраняем старые атрибуты
        push cx
; и устанавливаем новые...
        mov ax,4301h
        lea dx,fName
        mov cx,0
        int 21h
; открывает для чтения и записи
        mov ax,3D02h
        lea dx, fname
        int 21h

        xchg ax,bx
; читаем начало файла
        lea dx,buffer
        mov cx,LenBuffer
        mov ah,3Fh
        int 21h
; запоминаем его время/дату
        mov ax,5700h
        int 21h
        push cx
        push dx

; проверка на ЕХЕшность
        mov ax,word ptr[buffer]
        not ax
        mul ah
        cmp ax,72BAh ; ну че ??? там стоит MZ или ZM
        je  GO_EXE   ; точно ЕХЕ файл !

; ***********************************************
; ******* значит имеем дело с СОМ файлом ********
; ***********************************************
ComReSet: ;********* снимаем вакцину ************
        cmp byte ptr[mode],ReSet
        jne ComSet
        lea dx,err4
; проверим ка, а стоит ли вакцинатор на файле
        call ident
        jnc exit     ; если нет, то тогда чего снимать

; ************** снять вакцину ******************
        mov si,word ptr[buffer+1]   ; смещение для jmp'а
        add si,5 ; попадем на область хранения старых байт и длины
        mov dx,si
        mov ax,4200h
        xor cx,cx
        int 21h
; считаем настоящее начало файла и его длину
        mov ah,3Fh
        mov cx,LenComBuffer+2
        lea dx,buffer
        int 21h
; сохраним длину файла в стеке
        push word ptr[buffer+lenComBuffer]

        call BOF
; и записываем оригинальные файты файла
        mov ah,40h
        lea dx,buffer
        mov cx,LenComBuffer
        int 21h

        pop dx
        mov ax,4200h
        xor cx,cx
        int 21h
; и отрезаем вакцину
        mov ah,40h
        mov cx,0
        int 21h

        lea dx,msg3
        jmp exit

ComSet:   ;********* ставим вакцину *************
        lea dx,err3
; прoверим а может мы уже стоим ?
        call ident
        jc exit      ; я так и знал уже стоим !!

; сохраним "настоящее" начало в вакцине
        lea si,buffer
        lea di,oldComByte
        mov cx,LenComBuffer
        rep movsb
; поскакали в конец файла
        call EOF
; длина вакцинируемого файла
        mov word ptr [oldComLen],ax
; формируем смещение для jmp'а
        sub ax,3
        mov word ptr [newComByte+1],ax
        sub ax, offset BeginCom-103h
; записать смещение вакцины от начала проги
        mov word ptr[StartCom+1],ax
; пишем свое бренное тело в хвост проги
        mov cx,LenCom
        lea dx,beginCom
        mov ah,40h
        int 21h
; будем менять начало файла..... скок
        call BOF
; и запишем новый заголовок
        mov cx,LenCombuffer
        lea dx,newComByte
        mov ah,40h
        int 21h

        lea dx,msg1
        jmp exit
exit:
        mov ah,9
        int 21h

; восстановим время/дату
        pop dx
        pop cx
        mov ax,5701h
        int 21h

        mov ah,3Eh
        int 21h
; восстановим атрибуты
        pop cx
        mov ax,4301h
        lea dx,fName
        int 21h
        ret
; ***********************************************
; ******* значит имеем дело с ЕХЕ файлом ********
; ***********************************************
GO_EXE:
        lea dx,err2
        jmp exit
;***********************************************
proc BOF
; прыг в начало файла
        mov ax,4200h
        xor cx,cx
        xor dx,dx
        int 21h
        ret
endp

;***********************************************
proc EOF
; прыг в конец файла
        mov ax,4202h
        xor cx,cx
        xor dx,dx
        int 21h
        ret
endp
;***********************************************
proc ident
; проверка на повторную установку
; CY - если вакцинатор установлен
        cmp word ptr[buffer+3],'uR'
        jne exit_ch
        cmp word ptr[buffer+5],'aw'
        jne exit_ch
        stc
        ret
exit_ch:
        clc
        ret
endp ident
;***********************************************
proc CMDLine
; помещает в переменную fName имя исследуемого файла
; если присутствует ключ /U то возвращает в переменной mode значение
        lea di,fname
        mov si,82h
        or byte ptr[si-2],0
        jnz cmd1
; если нет параметров, то сушим весла
        stc
        ret

cmd1:
        lodsb
        cmp al,32
        je cmd3
cmd2:
        cmp al,13
        je cmd3
        stosb
        jmp cmd1
cmd3:
        dec si
        mov byte ptr[si],24h

cmd4:
        lodsb
        or al,al
        je cmd_exit
        cmp al,"/"
        jnz cmd4
        mov al, byte ptr[si]
        or al,33
        cmp al,'u'
        jne cmd_exit
; режим работы - снять вакцину
        mov byte ptr[mode],ReSet
cmd_exit:
        ret
endp

;*************************************************************
;**************** Вакцинатор для СОМ файлов ******************
;*************************************************************
BeginCom EQU $
         jmp StartCom

oldComByte db LenComBuffer dup('!')
oldComLen  dw ?
exitCom:
        ret
StartCom:
; в ВР смещение от начала проги
        db 0BDh       ; mov bp,
        dw ?

        mov si,[ds:2Ch]
        mov ds,si
        xor ax,ax
        mov si,1
        mov cx,2000
NextLoop:
        dec si
        lodsw
        or ax,ax
        jnz NextLoop
        cmp word ptr[si],0001h
        jnz ExitCom
        mov dx,si
        inc dx
        inc dx

        mov word ptr[cs:FileName+bp],dx
        mov word ptr[cs:FileName+2+bp],ds

        mov ax,3D00h
        int 21h
        push cs
        pop ds
        jc exitCom

        xchg ax,bx

        mov ah,3Fh
        mov cx,LenComBuffer
        mov dx,tempCombuffer
        int 21h

        mov ah,3Eh
        int 21h

        mov di,100h
        mov si,dx
        rep cmpsb

        jnz mismatch
; все ОК и сдель передавать управление на прогу !!!
match:
        mov di,100h
        push di
; воостановить старые байты
        lea si,oldComByte
        add si,bp
        mov cx,LenComBuffer
        rep movsb
        ret
mismatch:
        lea dx,vComMes
        add dx,bp
        mov ah,9
        int 21h
checkKey:
        mov ah,10h
        int 16h

        cmp ah,03h  ; Лечить
        je k_cure
        cmp ah,02h  ; Игнорировать
        je match
        cmp ah,04h  ; Завершить
        jne not_key
        int 20h
not_key:
        mov ah,2
        mov dl,7
        int 21h
        jmp checkKey
k_cure:
; загрузим в регистры имя файла в окружении программы
        lds dx,dword ptr[FileName+bp]
; и прочитаем атрибуты
        mov ax,4300h
        int 21h
        push cx            ; сохраним их в стеке
        mov ax,4301h       ; и сбросим на файле
        mov cx,0           ; к такой-то матери
        int 21h

        mov ax,3D02h
        int 21h
        xchg ax,bx

; запомним время/дату
        mov ax,5700h
        int 21h
        push cx
        push dx

        push ds
        push cs
        pop ds
; запишем "вакцинированные" байты
        mov ah,40h
        mov cx,LenComBuffer
        lea dx,newComByte
        add dx,bp
        int 21h
; прыг на длину проги с вакциной
        mov ax,4200h
        mov dx,[oldComLen+bp]  ; настоящая длина файла
        add dx,LenCom          ; плюс длина вакцины
        xor cx,cx
        int 21h

        pop ds
; обрезание
        mov cx,0
        mov ah,40h
        int 21h
; восстанавливаем дату/время
        mov ax,5701h
        pop dx
        pop cx
        int 21h
; закрываем файл
        mov ah,3Eh
        int 21h
; восстанавливает атрибуты
        pop cx                 ; сохраненные атрибуты
        mov ax,4301h
        int 21h
        push cs
        pop ds
        ret
newComByte db 0E9h
           dw 0
           db "Ruwa"
FileName   dd ?


vComMes    db "   Оба-на кажеться вирус !!",13,10
           db "1 - игнорировать",13,10
           db "2 - лечить",13,10
           db "3 - завершить",13,10,24h


LenCom        EQU $-BeginCom
tempCombuffer EQU 65235-LenCom

;*************************************************************
;**************** Вакцинатор для ЕХЕ файлов ******************
;*************************************************************

        END


(C) NF, 1998-2004