                                                            Приложение 5



          ИСПОЛНЯЕМЫЕ ФАЙЛЫ И СВЯЗАННЫЕ С НИМИ СИСТЕМНЫЕ БЛОКИ


               Распределение оперативной памяти в MS DOS

   Оперативная память  в MS DOS  распределяется в  соответствии  с  при-
веденной таблицей.

──────────┬─────┬───┬────────────────────────────────
          │     │За-│
  Адрес   │Длина│ви-│
(сегмент: │(де- │си-│    Наименование и описание
смещение) │ ся- │мо-│
          │ тич)│сть│
══════════╪═════╪═══╪════════════════════════════════
0000:0000 │ 1024│ - │ Таблица векторов прерываний:
          │     │   │  256 4-байтовых адресов
──────────┼─────┼───┼────────────────────────────────
0040:0000 │ 256 │ - │ Область данных ROM-BIOS
──────────┼─────┼───┼────────────────────────────────
0050:0000 │ 512 │ - │ Область данных DOS
──────────┼─────┼───┼────────────────────────────────
xxxx:0000 │ 8928│Ver│ Код BIOS (считанный из IO.SYS)
──────────┼─────┼───┼────────────────────────────────
xxxx:0000 │29920│Ver│ Обработчики прерываний DOS,
          │     │   │ включая INT 21h
          │     │   │ (MSDOS.SYS или IBMDOS.COM)
──────────┼─────┼───┼────────────────────────────────
xxxx:0000 │     │Con│ DOS: буфера, области данных
          │     │   │ и устанавливаемые драйверы
──────────┼─────┼───┼────────────────────────────────
xxxx:0000 │     │Ver│ Резидентная порция COMMAND.COM
          │     │   │ (стандартный - около 4K длиной)
          │     │   │ включает обработчики прерываний
          │     │   │ 22h, 23h и 24h
──────────┼─────┼───┼────────────────────────────────
xxxx:0000 │     │   │ Резидентные программы и
          │     │   │ данные
──────────┼─────┼───┼────────────────────────────────
xxxx:0000 │     │   │ Текущая выполняемая прикладная
          │     │   │ программа (типа COM или EXE).
          │     │   │ Сначала программе выделяется
          │     │   │ память до адреса A000:0000
          │     │   │ (640K) или до максимального
          │     │   │ для данного компьютера адреса
──────────┼─────┼───┼────────────────────────────────
xxxx:0000 │     │Con│ Транзитная часть COMMAND.COM
          │     │   │ (содержит интерпретатор команд,
          │     │   │ внутренние команды и т.п.).
          │     │   │ Перезагружается, если была
          │     │   │ чем-то перекрыта
          │     │   │
──────────┴─────┴───┴── граница 640K зоны ───────────


                                 Продолжение таблицы
──────────┬─────┬───┬────────────────────────────────
          │     │За-│
  Адрес   │Длина│ви-│
 сегмент: │(де- │си-│    Наименование и описание
смещение) │сят.)│мо-│
          │     │сть│
══════════╪═════╪═══╪════════════════════════════════
A000:0000 │     │ - │ EGA-память для некоторых
          │     │   │ видеорежимов
──────────┼─────┼───┼────────────────────────────────
B000:0000 │     │ - │ Видеопамять монохромного
          │     │   │ адаптера и Геркулес (Hercules)
──────────┼─────┼───┼────────────────────────────────
B800:0000 │     │ - │ Видеопамять CGA
          │     │   │ (также страница 2 для Hercules)
══════════╪═════╪═══╪════════════════════════════════
C800:0000 │     │ - │ Внешний код ROM. ROM-BIOS ищет
   до     │     │   │ здесь (в 2K-блоках) код,
E000:0000 │     │   │ выполняемый при загрузке.
          │     │   │ Этот код обычно инсталлирует
          │     │   │ обработчик устройства
          │     │   │ (дополнительный BIOS винчестера
          │     │   │ или EGA)
──────────┼─────┼───┼────────────────────────────────
E000:0000 │     │ - │ Модули ROM материнской платы
   до     │     │   │ в блоках по 64K (только AT)
E000:FFFF │     │   │
──────────┼─────┼───┼────────────────────────────────
F600:0000 │     │ - │ Обработчик ошибок при загрузке,
          │     │   │ ROM-резидентный интерпретатор
          │     │   │ BASIC (для оригинальных IBM PC)
──────────┼─────┼───┼────────────────────────────────
FE00:0000 │     │ - │ ROM-BIOS: POST и код загрузки,
          │     │   │ обработчики прерываний и прочее
──────────┼─────┼───┼────────────────────────────────
F000:FFF0 │     │ - │ JMP на программу, выполняемую
          │     │   │ при включении или сбросе
──────────┼─────┼───┼────────────────────────────────
F000:FFF5 │     │ - │ Дата издания BIOS (в ASCII)
──────────┼─────┼───┼────────────────────────────────
F000:FFFE │     │ - │ Идентификационный код IBM PC
──────────┴─────┴───┴────────────────────────────────



   Примечания.

   1. В графе  "Зависимость" знак  "--" означает, что приведенные в пред-
ыдущих графах  значения постоянны,  "Ver" -- зависят  от  версии  MS DOS,
"Сon" -- от содержимого CONFIG.SYS.

   2. Приведенные значения  соответствуют файлам  IO.COM и  MSDOS.COM  в
MS DOS версии 3.3.

   BIOS хранит  двухбайтовую переменную по адресу 0040:0013, которая со-
общает количество килобайт используемой памяти (объем системной памяти).
Это значение можно  либо посмотреть непосредственно,  используя, скажем,
утилиту Low  или Pepores  (Софтпанорама, т.2,  No. 8)  или получить  как
часть протокола некоторых утилит, например SysMap. Для большинства машин
это 640  (280h) или  512 (200h).  Вместе с  тем встречаются компьютеры с
639K  и  638K  оперативной   памяти.  Поэтому  полезно  записать   объем
оперативной  памяти  используемого  компьютера,  чтобы  потом  не искать
несуществующий бутовый вирус.

   Бутовые вирусы  обычно уменьшают  значение слова  по адресу 0040:0013
при своей инсталляции, "откусывая" необходимое им число килобайт.  Таким
образом, объем системной памяти  уменьшается, и это уменьшение  является
свидетельством того, что "что-то не так". Прерывание int 12h  возвращает
в  регистр  AX  содержимое  слова  по  адресу  0040:0013,  т.е.   размер
установленной системной памяти в килобайтах. Его можно вызвать из любого
отладчика, например DEBUG.

   Память свыше 1 мегабайта доступна на компьютерах класса AT через фун-
кцию BIOS  INT 15h. Эта память часто используется для организации вирту-
ального диска.

                  Префикс программного сегмента (PSP)

   Когда программа  начинает выполнение,  DS:0000 и ES:0000 указывают на
начало PSP  этой программы. Информация PSP позволяет выделить имена фай-
лов и  опции из строки команд, узнать объем доступной памяти, определить
окружение и т.д.

       0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F

     ┌───────╥───────╥───╥───┬───────┬───────╥───────┬───────╥───────┐
 00  │int 20h║MemTop ║Rsv║ CALL смещ. сегмент║Адр.зaв.(int22)║ Ctrl-
     ├───┴───╫───┴───╨───╨───╥───┴───┼───┴───╫───┴───┼───┴───╫───┴───┤
 10    Break ║Critical Error ║         Резервная область DOS
     ├───┼───╨───┼───┼───┼───╨───┼───┼───┼───╨───┼───╥───┼───╫───┼───┤
 20                    Резервная область DOS         ║EnvSeg ║
     ├───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───╨───┴───╨───┴───┤
 30                    Резервная область DOS
     ├───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┤
 40                    Резервная область DOS
     ├───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───╥───┴───┼───┴───┤
 50                    Резервная область DOS         ║
     ├───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───╫───┴───┼───┴───┤
 60         Форматированная область параметра 1      ║
     ├───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───╨───┴───┼───┴───╖
 70         Форматированная область параметра 2                      ║
     ╓───╥───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───╜
 80  ║len║ Неформатированная область параметров
     ╙───╨───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┤
 90         (символы из командной строки DOS)
     ├───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┤
 ...  ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...

     ╓───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┤
100  ║ начало кода для COM- или EXE-файла
     ╙───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┤

           Рис.1. Структура префикса программного сегмента.

   Первым полем  префикса программного сегмента (рис.1) является команда
INT 20h [0;2] --  программы могут  выполнять на нее переход с помощью JMP
или RET  для выхода. Поле MemTop содержит адрес вершины доступной памяти
системы в  параграфах [+2;2].  Далее один  байт резервируется -- поле Rsv
[+4;1]. Следующее  поле [5;5]  содержит команду  длинного перехода  (FAR
CALL) к диспетчеру функций DOS. Поле Avail [6;2] содержит доступные бай-
ты в  программном сегменте (только для COM-файла). Далее следуют три че-
тырехбайтовых поля,  имеющие формат <смещение><сегмент> и содержащие со-
ответственно адрес  завершения (INT 22h) [+0Ah;4], адрес обработки Ctrl-
Break  (INT 23h)  [+0h;4]  и  обработчик  критических  ошибок  (INT 24h)
[+12h;4]. За ними идет резервная область DOS [+16h;16h-2B].



Поле EnvSeg [+2Ch;2] содержит сегментный адрес окружения DOS. Далее сле-
дует еще  одна резервная  область DOS [+2Eh;2Eh-5B]; Форматированная об-
ласть первого параметра [+5Ch;10h] содержит FCB для 1-го параметра. Ана-
логично форматированная  область второго  параметра [+6Ch;14h]  содержит
FCB для  2-го параметра. Поле Len [+80h;1] содержит длину области UPA (с
адреса 81h), а также смещение умалчиваемой DTA. За полем Len расположена
неформатированная область  параметров, содержащая символы, полученные из
командной строки DOS [+81h;7Fh] (кроме директив переназначения).

   Начало кода  для COM-  или EXE-файла,  загруженного в оперативную па-
мять, находится  по смещению  100h. Отметим,  что при загрузке заголовок
EXE-файла загружается  отдельно, и  в памяти  сам EXE-файл  начинается с
байтов, непосредственно следующих за заголовком.


                     Блок управления памятью (MCB)

   Это управляющий блок, используемый DOS при распределении, модификации
и освобождении  блоков системной  памяти. Анализ цепочки этих блоков по-
зволяет, в  частности, получить  сведения об  имеющихся резидентных про-
граммах. Структура блока MCB показана на рис.2.

     0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
   ╓───╥───┬───╥───┬───╥───┬───────┬───────┬───────┬───────┬───────┐
10 ║Тип║ Вл-лец║ Размер║              зарезервировано              │
   ╟───╨───┼───╨───┼───╨───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┤
20 ║ Начало блока памяти (для блока с загруженной программой - PSP)
   ╙───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼

              Рис.2. Структура блока управления памятью.

   Блоки управления памятью всегда выравнены на границу параграфа ("сег-
мент блока").  Поле "Тип" может принимать два значения -- 'M' (4Dh), если
за этим блоком есть еще блоки и 'Z' (5Ah), если данный блок является по-
следним. Поле  "Владелец"  (соответствующая  графа  обычно  обозначается
Parent, Owner)  содержит параграф  владельца (для  FreeMem); если  0, то
владельцем является сам данный блок. Поле "Размер" (Size) содержит число
параграфов в  этом блоке. Блок памяти -- начало информации, расположенной
в данном  блоке. Общий  объем этой информации равен (Размер*10h) байтов.
Сегментный адрес  начала блока памяти возвращает функция 48h (AllocMem).
Для блока  M-типа следующий блок находится по адресу (сегмент_блока+Раз-
мер):0000, а  для  блока  Z-типа  выражение  (сегмент_блока+Размер):0000
всегда указывает  на конец оперативной памяти (для систем с 640K это ад-
рес: A000:0000h).  После функции  4Bh (Exec),  Z-блок начинается с (PSP-
1):0000 нового процесса.

   В списке  резидентных программ  могут оказаться и простые резидентные
вирусы, хотя более сложные резидентные вирусы маскируются таким образом,
чтобы обойти данную возможность обнаружения. Список MCB можно получить с
помощью специальных  утилит (например,  SysMap, MemAnal, Release и др.).
Эти утилиты  отличаются удобством  и степенью подробности выдаваемой ин-
формации. Ниже  приведен протокол, выдаваемый утилитой PCMap фирмы Video
Trends Software.

   Как видно  из приведенной карты, обычно в MS DOS используется порядка
десятка резидентных  программ различного назначения, и выявить "лишнюю",
даже если  она видна, не так просто. Поэтому желательно иметь распечатку
"эталонной" карты памяти, с которой можно сравнить имеющуюся.

  PC SYSTEM MAP  V3.00    Video Trends Software  1989
────────────────────────────────────────────────────────
 Segment   Size     Program      Parent   Cooked Vectors
  0000   001,024  INTERRUPT VECTOR TABLE
  0040   000,256  BIOS  DATA  AREA
  0050   000,512  DOS COMMUNICATION AREA    1E
  0070   008,928  IO.SYS       BOOT RECORD  01 03 04 0F                                             13 1B 29 EF                                            F3 F7 FA
  029E   029,920  MSDOS.SYS    IO.SYS       20 26 2A 2B                                            2C 2D 31 32                                            34 35 36 37                                            38 39 3A 3B                                            3C 3D 3E 3F
  09ED   012,784  EMMXXXX0     IO.SYS       67 F6
  0D0C   000,112  PCKXXXX0     IO.SYS       25
  0D13   000,768    1 units    IO.SYS       19
  0D43   000,928  4DOSSTAK     IO.SYS
  0D7D   001,072  HANDLE TABLE IO.SYS
  0DC0   000,224  FCBs TABLE   IO.SYS
  0DCE   020,592  DOS BUFFERS  IO.SYS       EE FF
  12D5   000,576  DRIVE TABLES IO.SYS
  12F9   003,824  DOS STACKS   IO.SYS       02 0E 70 76
  13E9   002,992  COMMAND.COM  COMMAND.COM  2E
  14A5   000,512  COMMAND.COM  ENVIRONMENT
  14C6   000,080  RELEASE.COM  ENVIRONMENT
  14CC   003,488  RELEASE.COM  COMMAND.COM  21 27
  15A7   000,128  MOUSE.COM    ENVIRONMENT
  15A7   000,128  MOUSE.COM    ENVIRONMENT
  15B0   010,048  MOUSE.COM    COMMAND.COM  0A 33
  1825   000,128  CPANEL.COM   ENVIRONMENT
  182E   032,928  CPANEL.COM   COMMAND.COM
  2039   000,128  UNIEGA.COM   ENVIRONMENT
  2042   006,480  UNIEGA.COM   COMMAND.COM  10 1F 44
  21D8   000,128  UNIKBD.COM   ENVIRONMENT
  21E1   000,848  UNIKBD.COM   COMMAND.COM  16
  2217   000,128  NC.EXE       ENVIRONMENT
  2220   012,896  NC.EXE       COMMAND.COM
  2547   000,128  COMMAND.COM  ENVIRONMENT
  2550   000,512  COMMAND.COM  ENVIRONMENT
  2571   000,144  PCMAP1.EXE   ENVIRONMENT
  257B   002,736  FREE         UNKNOWN
  2627   000,128  TXTSCR.COM   ENVIRONMENT
  2630   000,976  TXTSCR.COM   UNKNOWN      08 09 28
  266E   002,896  COMMAND.COM  COMMAND.COM  00 22 23 24                                            2F
  2724   025,120  PCMAP1.EXE   COMMAND.COM

 Dos   Memory: 655,360 bytes
 Block Memory: 655,360 bytes

 Free  Memory: 469,920 bytes


                  Формат исполняемых программ в MS DOS

   В MS DOS  имеются два  основных формата  исполняемых программ:  СOM и
EXE. Файл  COM-формата -- это двоичный образ кода и данных программы. Та-
кой файл  должен занимать менее 64K. Файл EXE-формата содержит специаль-
ный заголовок,  при помощи которого загрузчик выполняет настройку ссылок
на сегменты в загруженном модуле.

   Ввиду сегментации адресного пространства процессора и того факта, что
переходы (JMP)  и вызовы  (CALL) используют относительную адресацию, оба
типа программ  (EXE и  COM) могут выполняться в любом месте памяти. Про-
граммы обычно  не пишутся  в предположении,  что они будут загружаться с
определенного адреса  (за исключением некоторых самозагружающихся, защи-
щенных от копирования игровых программ). Программы типа EXE могут состо-
ять из  нескольких сегментов  и могут  выполняться в  любом месте памяти
только потому, что DOS настраивает сегментные адреса при загрузке.


                             COM-программы

   COM-программы содержат  единственный сегмент  (или, во всяком случае,
не содержат явных ссылок на другие сегменты). Образ COM-файла считывает-
ся с  диска и  помещается в  память, начиная  с PSP:0100.  COM-программы
обычно используются  для небольших  утилит. Они быстрее загружаются, ибо
не требуется  настройка сегментов, и занимают меньше места на диске, по-
скольку заголовок и сегмент стека отсутствуют в загрузочном модуле.

   После загрузки СОM-файла:

   - CS, DS, ES и SS указывают на PSP;

   - SP указывает  на конец сегмента PSP (обычно 0FFFEh, но может быть и
меньше, если  полный 64K сегмент недоступен, например, при работе отлад-
чика). Слово  по смещению  06h в PSP указывает, какая часть программного
сегмента доступна;

   - вся память системы за программным сегментом распределена программе;

   - слово 00h помещено в стек (командой PUSH);

   - IP содержит  100h (первый  байт модуля)  в результате  команды  JMP
PSP:100.


                             EXE-программы

   EXE-программы содержат  несколько программных сегментов, включая сег-
мент кода, сегмент данных и сегмент стека. EXE-файл загружается, начиная
с адреса  PSP:0100. В процессе загрузки считывается информация заголовка
EXE в начале файла и выполняется перемещение адресов сегментов.

   После перемещения управление передается загрузочному модулю посредст-
вом инструкции  далекого перехода (FAR JMP) к адресу CS:IP, извлеченному
из заголовка EXE.
   В момент получения управления программой EXE-формата:

   - DS и ES указывают на PSP;

   - CS, IP, SS и SP инициализированы значениями, указанными в заголовке
EXE;

   - поле PSP MemTop содержит значение, указанное в заголовке EXE. Обыч-
но вся доступная память распределена программе.

   Как видно из рис.3, заголовок состоит из двух частей: форматированной
части (первые  1Ch байт)  и таблицы перемещений (Relocation Table) пере-
менного размера, причем начало таблицы перемещений определяется значени-
ем поля  TablOff (обычно  это поле  содержит 1Ch, но могут быть и другие
значения). Форматированная  часть заголовка включает 14 двухбайтовых по-
лей:

      0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
    ┌───────╥───────╥───────╥───────╥───────╥───────╥───────╥───────┐
 00 │ Sign  ║PartPag║PageCnt║ReloCnt║HdrSize║ MinMem║ MaxMem║ ReloSS│
    ├───┴───╫───┴───╫───┴───╫───┴───╫───┴───╫───┴───╫───┴───╨───┴───┤
 10 │ ExeSP ║ ChkSum║ ExeIP ║ ReloCS║TablOff║Overlay║ Rel.Table El  │
    ├───┴───╨───┴───╫───┴───╨───┴───╫───┴───╨───┴───╫───┴───────┴───┤
 20 │ смещ.  сегмент║ смещ.  сегмент║  ...     ...  ║  ...     ...  │
    └───┴───┼───┴───╨───┴───┼───┴───╨───┴───┼───┴───╨───┴───┼───┴───┘
 30
    ├───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┤
...  ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...

    ├───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┤
1F0  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
    ├───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┤
200       начало кода EXE-программы
    ├───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┼───┴───┤

             Рис.3. Структура заголовка файла EXE-формата.
   Sign -- "подпись" EXE-файла (4D5Ah -- 'MZ') [0;2];
   PartPag -- длина  неполной последней  страницы  (обычно  игнорируется)
[2;2];
   PageCnt -- длина  образа загружаемой  программы в 512-байтовых страни-
цах, включая заголовок [4;2];
   ReloCnt -- число элементов в таблице перемещений [6;2];
   HdrSize -- длина заголовка в 16-байтовых параграфах [8;2];
   MinMem -- минимум  требуемой памяти  за концом  программы  (параграфы)
[0Ah;2];
   MaxMem -- максимум  требуемой памяти  за концом  программы (параграфы)
[0Ch;2];
   ReloSS --  сегментное  смещение  сегмента  стека  (для  установки  SS)
[0Eh;2];
   ExeSP -- значение регистра SP (указателя стека) при запуске [10h;2];
   ChkSum -- контрольная  сумма (отрицательная  сумма всех  слов файла; в
существующих версия  MS DOS, к  сожалению, при  загрузке не проверяется)
[12h;2];
   ExeIP -- значение регистра IP (указателя команд) при запуске [14h;2];
   ReloCS -- сегментное  смещение кодового  сегмента (для  установки  CS)
[16h;2];
   TablOff -- смещение для 1-го элемента перемещения (часто 1Ch) [18h;2];
   Overlay -- номер оверлея (0 для главного модуля) [1Ah;2].

   Как видно  из приведенной структуры, заголовок EXE-файла всегда начи-
нается с  подписи MZ  или, реже,  ZM. После загрузки программы загрузчик
анализирует эти  первые два байта и, если они содержат "MZ", то рассмат-
ривает данный  файл как  EXE-файл, независимо  от расширения имени файла
(оно может  быть и  COM и  BIN, а не только EXE). Эта особенность MS DOS
учитывается не всеми файловыми вирусами. Поэтому, если при заражении ви-
рус исходит из предположения, что тип файла соответствует расширению его
имени, то  он неправильно  заражает "замаскированные" EXE-файлы, которые
после заражения,  таким образом,  становятся неработоспобными.  В то  же
время этот эффект потери работоспособности является обратимым: после ле-
чения фагом заголовок будет восстановлен.
   Обычно заголовок  имеет размер 512 байтов (200h) и значительная часть
его не используется (содержит нули).

   Файловые вирусы при заражении изменяют заголовок EXE-файла, и это об-
стоятельство можно использовать для контроля. Обычно файловые вирусы из-
меняют значение  полей ExeIP и ReloCS таким образом, чтобы они указывали
на начало  тела вируса,  дописанного в  конце программы (перед передачей
управления программе загрузчик заносит в регистры значения из соответст-
вующих полей  заголовка, а  затем передает  управление по адресу CS:IP).
Некоторые  вирусы   используют  способ,   неосторожно  "рекомендованный"
Д.Н.Лозинским в документации к полифагу Aidstest и основанный на коррек-
тировке соответствующего элемента Relocation Table. Как уже указывалось,
эта таблица  начинается с  байта, адрес  которого указан  в поле TablOff
(обычно 1Ch)  и имеет  ReloCnt элементов. Каждый элемент занимает четыре
байта и содержит два поля: <смещение> и <сегмент>:


     Формат таблицы перемещения (Relocation table)

        ┌───────┬───────┬ ─ ─ ┬───────┬───────┐
        │ смещ.  сегмент│ ... │ смещ.  сегмент│
        └───┴───┴───┴───┴ ─ ─ ┴───┴───┴───┴───┘


   Загрузчик добавляет  к каждому из слов, определенных адресом соответ-
ствующего элемента  таблицы перемещений,  адрес начала  сегмента (обычно
PSP + 10h). Легко  видеть, что этот процесс можно использовать для изме-
нения команды  перехода или вызова подпрограммы, содержащегося по адресу
ReloCS:ExeIP, как бы возвращаясь тем самым к способу, обычно применяемо-
му вирусами при заражении COM-файла.


                         Резидентные программы

   Выход из программы в MS DOS можно выполнить двумя способами:

   1. С  помощью функции 4Ch (EXIT) в любой момент, независимо от значе-
ний регистров.

   2. С  помощью функции  00h или  прерывания 20h, когда CS указывает на
PSP.

   В этих  случаях занимаемая программой память освобождается. Кроме то-
го, MS DOS  позволяет завершить  программу и оставить ее постоянно рези-
дентной (TSR),  используя либо  прерывание 27h,  либо  функцию  DOS  31h
(KEEP). Последний  способ применяется, когда резидентный код длиннее 64K
или необходимо сформировать код выхода для родительского процесса.

   Концепция TSR-программы  используется большинством  файловых и  всеми
бутовыми вирусами  для того, чтобы контролировать выполняемые операцион-
ной системой  операции и  заражать выполняемые или открываемые на чтение
программы.

