Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Последние темы форума

Показать новые сообщения »

Почтовая рассылка

Подписчиков: 11634
Последний выпуск: 19.06.2015

"Вирусы", "Черви", "Драконы" и резиденты на службе прогресса.

Назад | Далее

гл.4 СОЗДАНИЕ РЕЗИДЕНТНЫХ ПРОГРАММ (практическая реализация)
============================================================
     Итак, мы познакомились с механизмом работы прерываний и научились реали-
зовывать вызов  прерываний на  уровне обычный JMP-ов и CALL-ов  и даже не ис-
пользовать при этом таблицу векторов.
     Чудесно!
     Теперь об создании резидентных программ (именно  таковыми являются 'дра-
коны' и 90% всех 'вирусов').
     Что такое резидентная программа (в дальнейшем - просто - резидент) ?
     Это  такая  программа, которая находится в оперативной памяти  постоянно
(обычные, нерезидентные программы присутствуют в памяти лишь во  время их не-
посредственного исполнения; когда их выполнение заканчивается  -- они "умира-
ют" - память занятая ими - освобождается . Резидент же  может  обитать в ОЗУ,
[кстати rezide - по англ. 'обитать']  не будучи в данный момент исполняем, но
в то же время, - готовый к действию).
     Вот как распределяется память  при  выполнении обычных и резидент. прог-
рамм (КРАЙНЕ упрощенно):


      -----------------------------------------------------------¬
      ¦                        рис.2                             ¦:
      L-----------------------------------------------------------
обычная программа:

                      До загрузки чего-либо:

     ---------T--------------T----------------------------------------
     ¦таблица ¦              ¦
     ¦векторов¦  область DOS ¦   свободная память . . . . . . . . . .
     ¦прерыв-й¦              ¦
     L--------+--------------+----------------------------------------
   0:0 ----> старшие адреса

                      Загрузили и исполняем обычную программу:
                                                      ¦
                                      -----------------
     ---------T--------------T--------V----------T--------------------
     ¦таблица ¦              ¦    TETRIS.EXE     ¦
     ¦векторов¦  область DOS ¦(есть такая глупая ¦ свободная память .
     ¦прерыв-й¦              ¦     игрушка)      ¦
     L--------+--------------+-------------------+--------------------
   0:0

                      После того, как прогр-а завершилась:

     ---------T--------------T----------------------------------------
     ¦таблица ¦              ¦
     ¦векторов¦  область DOS ¦   свободная память . . . . . . . . . .
     ¦прерыв-й¦              ¦ (все вернулось на кругИ своя...)
     L--------+--------------+----------------------------------------
   0:0
===========================================================================
     Теперь - что касается резидентов:

                      До загрузки чего-либо:

     ---------T--------------T----------------------------------------
     ¦таблица ¦              ¦
     ¦векторов¦  область DOS ¦   свободная память . . . . . . . . . .
     ¦прерыв-й¦              ¦
     L--------+--------------+----------------------------------------
   0:0

                      Загрузили резидент:-------------¬
                                                      ¦
                                      -----------------
     ---------T--------------T--------V----------T--------------------
     ¦таблица ¦              ¦    KEYR23.COM     ¦
     ¦векторов¦  область DOS ¦(драйвер рус. кла- ¦ свободная память .
     ¦прерыв-й¦              ¦     виатуры)      ¦
     L--------+--------------+-------------------+--------------------
   0:0    ---------------------------
          ¦
     И так- --  до окончания работы на PC! Резидент будет сидеть в ОЗУ и быть
всегда готов вам услужить. Если  Вы  теперь загрУзите tetris, он попадет  вот
куда:

     ---------T--------------T-------------------T----------T---------
     ¦таблица ¦              ¦    KEYR23.COM     ¦          ¦
     ¦векторов¦  область DOS ¦(драйвер рус. кла- ¦TETRIS.EXE¦свободная
     ¦прерыв-й¦              ¦ ¦   виатуры)      ¦          ¦память...
     L--------+--------------+-¦-----------------+----------+---------
   0:0                         Lстал резидентом


     Только программы типа Volkov Comander могут  безболезненно удалять рези-
денты из памяти (и то лишь те, которые были загружены после них {удаляющих}).
     Сделать программу  резидентной  (постоянно  присутствующей  в памяти) --
ЭЛЕМЕНТАРНО. Вот один из способов (в дальнейшем мы рассмотрим их все):

    (прокоментируем ниже)
      -----------------------------------------------------------¬
      ¦                         пример 4                         ¦:
      L-----------------------------------------------------------

TITLE   Это - COM. программа N4 для демонстрации посадки резидента
ASSUME        CS:CodeSegment
;---------------------------------------------------------------------------
CodeSegment   SEGMENT PARA
              ORG(100h)
Start:
MainProcedure PROC NEAR
              ;
              ;
              ;
              ;
              ;
              MOV AX,0E61h                 ; напечатать
              INT 10h                      ;   символ 'a'
resident_end: ;
              ;
              MOV DX,OFFSET resident_end   ; DXвыполняется
  ¦ \ ¦ /            +TTTTT+                ¦      п/п-ма
  L - * - --------> -+++++++                ¦      обработки
    / ¦ \           ¦+++++++                ¦      (стандартная)
  возник            ¦¦     ¦                ¦      IRET------------¬
  сигнал --         ¦L------                ¦                      ¦
  -- прерывание     Lв таблице ---------T----                      ¦
                     векторов           делается                   ¦
  ---------------¬   найден адрес       переход                    ¦
  V              L¬  обработчика        по этому                   ¦
                  ¦  (стандартного)     адресу                     ¦
                  ¦                                                ¦
                  L------T------------------------------------------
        делается переход обратно - в пользовательскую программу,
        в ту точку, перед которой прерыв-е возникло



     А вот какая стала цепочка после того, как мы перехватили прерыв-е

  ¦                                  г================================¬
  ¦                  ------¬         ¦      ------>выполняется        ¦
  ¦ \ ¦ /            +TTTTT+         ¦      ¦      ---НАША----        ¦
  L - * - --------> -+++++++         ¦      ¦      п/п-ма обработки   ¦
    / ¦ \           ¦+++++++         ¦      ¦      (она резидентна)   ¦
  возник            ¦¦     ¦         ¦      ¦          ¦              ¦
  сигнал --         ¦L------         ¦      ¦          L---->------¬  ¦
  -- прерывание     Lв таблице ---->----T----                      ¦  ¦
                     векторов        ¦  делается                   ¦  ¦
  ------------¬      найден адрес    ¦  переход                    ¦  ¦
  ¦           L¬     ---НАШЕГО----   ¦  по этому                   ¦  ¦
  V            L¬    обработчика     ¦  адресу                     ¦  ¦
                ¦                    ¦             возвращаем      ¦  ¦
                ¦                    ¦             управление      ¦  ¦
                ¦                    ¦             стандартно- ----+  ¦
                ¦                    ¦             му обработ-     ¦  ¦
                ¦         наше новое-¦             чику (JMP Far)  ¦  ¦
                ¦         звено      L=============================¦==-
                ¦                                 --------- сделаем для него резидентный
обработчик.
     Какое прерывание выбрать?  Предложим для простоты прерывание N 5 (печать
экрана). Оно  возникает, если Вы  нажмете клавишу Print Scrin. Вызываемая при
этом п/п-ма печатает на принтере копию экрана PC. Прерывание N 5 не требует и
не возвращает  никаких параметров (чУдно!),  и еще его не обязательно возвра-
щать стандартному обработчику; ничего не случится, если Вы его зажмете (весь-
ма редкое  свойство). Вы  наверное не раз замечали что  если Вы нажмете Print
Scrin, а  принтер не готов -- раздается гудок,  -- это стандартный обработчик
прерывания N 5 'назвал' Вас раздолбаем).
     Создадим-ка резидент, который, перехватывая прерывание N  5  ,  ну  ска-
жем,.. выведет на экран 'сердечко' (символ  с кодом 3), и после этого возвра-
тит управление  стандартному  обработчику  (вежливость - высшая добродетель).
Таким образом, при нажатии Print  Scrin  сначала  будет напечатано 'сердечко'
(работает наш резидентный обработчик), а уже потом раздастся гудок (заработа-
ет стандартный обработчик и обругает Вас за отключенный принтер).
     Итак -- вперед!

    (подробно прокоментируем ниже)
      -----------------------------------------------------------¬
      ¦                         пример 5                         ¦:
      L-----------------------------------------------------------

TITLE   Это - COM. программа N5 для демонстрации посадки резидента
ASSUME        CS:CodeSegment
;-----------------------------------------------------------------
CodeSegment   SEGMENT PARA
              ORG(100h)
Start:
MainProcedure PROC NEAR
              ;
              ;
              JMP  initial                    ; перепрыгнем через данные
              ;                               ; и наш обработчик прер-я 05
              ;                               ; на инициализирующую часть
              ;
              ;
saved_int05:  DD   0                          ; данные (хранилище для
              ;                               ; адреса стандартного обра-
              ;                               ; ботчика прерывания 05 --
              ;                               ; -- 2 слова)
              ;
              ;-----------наша п/п-а обработки прерывания 05------------------¬
              ;¦         (она останется резидентной в памяти)                 ¦
              ;¦        здесь мы можем приколоться как хотим..                ¦
              ;¦                              ;                               ¦
int05_treater:PUSH AX                         ;                               ¦
              ;                               ;                               ¦
              MOV  AH,0Eh                     ;входные параметры прерыв-я 10h:¦
              MOV  AL,03h                     ;  (печатать 'сердечко' - код 03)
              INT  10h                        ;печатаем 'сердечко'            ¦
              ;                               ;                               ¦
              POP  AX                         ;PUSH и POP ОЧЕНЬ важны (см. ко-¦
              ;                               ;  ментарий после примера)      ¦
              ;                               ;                               ¦
              ;                               ;                               ¦
              JMP  dword ptr CS:[saved_int05] ; длин. JMP   по адресу, котор. ¦
rezident_end: ;¦                              ; находится теперь в хранилище  ¦
              ;¦                              ; saved_int05 (возвращаем управ-¦
              ;¦                              ; ление стандартному обработчику¦
              ;¦                              ; прерывания 05)                ¦
              ;L---------------------------------------------------------------
              ;                               ;
              ;-----------инициализирующая часть------------------------------¬
              ;¦ (здесь мы сажаем резидент, переопределяя адреса)             ¦
              ;¦                                  ;                           ¦
initial:      XOR  DX,DX                          ; ---¬                      ¦
              MOV  DS,DX                          ; ---+--> DS = 0            ¦
              ;                                   ;                           ¦
              MOV  AX,DS:[5*4]                    ;сохраняем в хранилище saved_
              MOV  word ptr CS:[saved_int05  ],AX ;  int05 адрес стандартного ¦
              MOV  AX,DS:[5*4+2]                  ;  обработчика прерывания 05¦
              MOV  word ptr CS:[saved_int05+2],AX ;  ( OFFSET и SEGMENT )     ¦
              ;                                   ;                           ¦
              ;                                   ;                           ¦
              CLI                                 ;запрещаем прерывания       ¦
              MOV  AX,OFFSET int05_treater        ;                           ¦
              MOV  word ptr DS:[5*4],AX           ;кладем в таблицу векторов  ¦
              PUSH CS                             ;  адрес нашего обработчика ¦
              POP  AX                             ;  прерывания 05            ¦
              MOV  word ptr DS:[5*4+2],AX         ;                           ¦
              STI                                 ;разрешаем прерывания       ¦
              ;                                   ;                           ¦
              ;                                   ;                           ¦
              MOV  DX,OFFSET rezident_end         ;DX=======>====>¬ перепрыгнем через данные
             L-------------                    ¦ и наш обработчик прер-я 05
saved_int05: -----------------------------¬    V на инициализирующую часть
             ¦данные: (хранилище для      ¦    ¦   L---------T----------
             ¦адреса стандартного обра -  ¦    ¦--------------
             ¦ботчика прерывания 05 --    ¦    ¦
             ¦-- 2 слова)                 ¦    ¦
             L-----------------------------    ¦
                                               V
int05_treater:----------------------------¬    ¦
             ¦наша п/п-ма обработки       ¦    ¦
             ¦прерывания 05 (она оста-    ¦    ¦
             ¦нется резидентной в памяти) ¦    V
rezident_end:L-----------------------------    ¦
                                               ¦
        г=========  -----------------------------¬
initial:     ¦инициализирующая часть      ¦
             ¦(здесь мы сажаем резидент,  ¦
             ¦переопределяя адреса        ¦
             ¦                            ¦
             ¦MOV DX,OFFSET rezident_end  ¦
             ¦INT 27h (выход в DOS)       ¦
             L-----------------------------

     Как видно из рисунка, прогр-ма состоит из двух главных частей:  той, что
остается в памяти  резидентно  и не  выполняется  при запуске самой  прогр-мы
(данные + наша п/п-ма обработки прерывания 05), и -- инициализирующей части.
     Почему порядок следования этих частей именно такой?
     Почему инициализирующая часть не остается в памяти резидентно?
     Почему наша п/п-ма обработки прерывания 05 начинается оператором PUSH AX
и заканчивается оператором POP AX?
     Что за новые операторы CLI и STI?

Назад | Далее

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог