Большой архив статей, книг, документации по программированию, вебдизайну, компьютерной графике, сетям, операционным системам и многому другому
 
<Добавить в Избранное>    <Сделать стартовой>    <Реклама на сайте>    <Контакты>
  Главная Документация Программы Обои   Экспорт RSS E-Books
 
 

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


     Например:
     адрес п/п-ы прерывания N0 (реакция на ситуацию "деление  на нуль") нахо-
дится   в   таблице  векторов  прерываний  по  адресу  0000:0000--segment   и
0000:0002--offset
     адрес п/п-ы прерывания N5  (печать  экрана) находится в таблице векторов
прерываний по адресу 0000:0014--segment и 0000:0016--offset

     Если мы замыслим заменить исходную стандартную п/п-му нашей собственной,
мы должны:
     1. Засунуть куда-то эту нашу п/п-му (и чтобы она там действительно была!
И была готова обработать соотв. прер-е).
     2. Изменить в таблице векторов адрес исходной стандартной п/п-ы на адрес
нашей.

     Отметим, что  пихать нашу п/п-му обработки  прерыв-я в то-же  место, где
сидела исходная (иногда это физически возможно) лучше не надо, хотябы потому,
что исходная нам ЕЩЕ ОЧЕНЬ МОЖЕТ ПРИГОДИТЬСЯ.

     ПОДРОБНО опишем механизм того, как PC реализует обработку прерываний:
     1. PC прячет  в  стек  регистр  флагов.
     2. PC прячет в стек содержимое регистра CS.
     3. PC прячет в стек значение IP для следующей команды.
     4. PC  делает JMP Far  <сегмент. адрес п/п>:[<офсетн. адрес п/п>] (джамп   @@??
на п/п-у обработки прерывания).
     ПРИ ЭТОМ все операции 1-4 (PUSHF, PUSH CS, ,  JMP  FAR ) содер-
жатся неявно В ОДНОЙ КОМАНДЕ "INT" вызова прерывания  (если прерыв-е реализу-
ется программно).
     5. Далее выполняется п/п-ма обработки прерывания.
     6. П/п-ма  обработки  прерывания  завершается специальной командой IRET,
которая состоит из следующих действий:
    а) помещается из стека слово в регистр IP (и увелич. SP на 2) ---¬
    б) помещается из стека слово в регистр CS (и увелич. SP на 2)    +----¬
    в) помещается из стека слово в регистр флагов (увелич. SP на 2)---    ¦
                                                                          ¦
                                                                          ¦
             т.е. это- JMP Far обратно, в программу                       ¦
             пользователя, на команду, следующую за той,                  ¦
             которая осуществила вызвлв прерыв-я                          ¦
              + восстановление флагов  <-----------------------------------



     А что  такое п/п-ма обработки  прерывания? Очень часто - трудно сказать;
считайте, что стандартная п/п-ма обработки прерывания (та -  которую PC имеет
изначально) -- своего рода -- черный ящик. И, как в любом черном ящике, здесь
нам доступны, в лучшем  случае, лишь ВХОД и ВЫХОД. Пусть, например,  мы хотим
напечатать на экране PC один символ. Это легко можно сделать,  дав прерывание
номер 10h. При этом будет вызвана п/п-ма печати символа, о  структуре которой
мы ничего не знаем. Как и большинство п/п-м, эта п/п-ма  имеет  входные и вы-
ходные параметры, через которые мы загружаем в нее и получаем  обратно инфор-
мацию. ВХОДНЫЕ И ВЫХОДНЫЕ ПАРАМЕТРЫ П/П-МЫ ПОМЕЩАЮТСЯ В РЕГИСТРЫ ПРОЦЕССОРА.
     Например, --  мы страстно хотим напечатать  на экране символ  'a'. Тогда
нам необходимо сделать следующие действия:


     MOV  AH,0Eh  ;это означает что п/п-ма должна ПЕЧАТАТЬ ОДИН СИМВОЛ------¬
                  ;                                                         ¦
     MOV  AL,61h  ;п/п-ма должна печатать КОНКРЕТНЫЙ СИМВОЛ 'a'(его код=61h)¦
                  ;L---T-----------------------------------------------------
                  ;    L-загрузка входных параметров
                  ;
     INT  10h     ;приказ "печатай!"        (генерация прерывания N 10h)


     а вот выходных параметров это прерывание (вернее сказать- данный способ
     его использования) не имеет



     А вот как выглядит при этом работа процессора:

      -----------------------------------------------------------¬
      ¦                         рис.1                            ¦:
      L-----------------------------------------------------------

-- НАША (ПОЛЬЗОВАТЕЛЬСКАЯ) ПРОГРММА ------¦--- П/П-ма ОБРАБОТКИ ПРЕРЫВАНИЙ ---
                                          ¦
                                          ¦
                                          ¦
ДЕЙСТВИЯ ПРОЦЕССОРА        МНЕМОКОДЫ      ¦     МНЕМОКОДЫ       ДЕЙСТВИЯ
('на пальцах'):                           ¦                     ПРОЦЕССОРА:
                          =======>====¬   ¦   г===>=====¬
AH<---0Eh                  MOV  AH,0Eh¦   ¦   ¦.печать..¦       .печать..
AL<---61h                  MOV  AL,61h¦   ¦   ¦.символа.¦       .символа.
PUSHF---------------TT---> INT  10h   L===>===-.........¦       .........
PUSH CS             ¦¦    г===============<====T¬IRET<--¦------¬--POP IP
PUSH IP             ¦¦    L==>=¬          ¦    ¦L=====<=-      L+ POP CS
JMP Far по адресу --+-         ¦          ¦    ¦                L-POPF
     <0:40>:[<0:42>]                      ¦    ¦
     L--T--  L---T-                       ¦    ¦
        ¦        ¦                        ¦    L-> путь выполнения        @@??
        ¦        ¦                        ¦
слово по-        L--- слово по
адресу 0:40           адресу 0:42


     Покажем, опираясь на описонный выше подробный механизм выполнения преры-
ваний, как реализовать прер-е НЕ пользуясь классической командой INT. Печата-
ем символ 'a' (см. пример 1):

      -----------------------------------------------------------¬
      ¦                         пример 1                         ¦:
      L-----------------------------------------------------------

TITLE   Это - COM. программа N1 для демонстрации механизма вызова прерываний
ASSUME        CS:CodeSegment
;---------------------------------------------------------------------------
CodeSegment   SEGMENT PARA
              ORG(100h)
Start:
MainProcedure PROC NEAR
              ;
              ;
              ;
              ;--запасаем в стеке информацию, необходимую для автоматического-¬
              ;         возврата  из п/п-мы обработки прерыв-я                ¦
              ;                  ;                                            ¦
              PUSHF              ;                                            ¦
              PUSH CS            ;                                            ¦
              MOV  BX,OFFSET after_int ;---¬                                  ¦
              PUSH BX            ;---------+-засунуть в стек IP точки возврата¦
              ;                  ; из п/п-ы обработки прерывания              ¦
              ;----------------------------------------------------------------
              ;
              MOV  AH,0Eh        ;входные
              MOV  AL,61h        ;       параметры прерыв-я 10h
              ;
              ;
              XOR  DX,DX         ; DX = 0    напрямую, как Вы знаете, засунуть
              MOV  DS,DX         ; DS = 0     константу в регистр DS невозможно
              ;
              ;
              JMP  dword ptr DS:[40h] ;длин. джамп по адресу, котор. находится
              ;                       ; в ячейках 0000:0040h и 0000:0042h
after_int:    ;
              RET                ;закончить программу и вернуться в DOS
              ;
              ;
              ;
MainProcedure ENDP
              ;
CodeSegment   ENDS
              END Start

     Пояснение: команда JMP dword ptr DS:[40h] (длинный JMP) осуществляет пе-
реход по адресу, который хранится по адресу DS:[40h]. Это -- адрес п/п-мы об-
работчика прерывания  10h. При этом в стек нужно  уронить регистр флагов, ре-
гистры CS и  IP.  Т.о. для того, чтобы  команда  IRET, завершающая обработчик
прерывания 10h вернула управление нашей программе (на метку after_int), необ-
ходимо сохранить в стеке определенную информацию (см. пример 1).

-----------T------------------------------------------------------T------------
           ¦ в случае, если кто-то не знаком с пакетом    TASM, то:
           L-------------------------------------------------------
     А теперь --  создадим загрузочный модуль.
     Вы  можете  при помощи любого текстового редактора перетащить  вышепред-
ставленный текст  исходника в текстовой  файл с расширением .asm, например --
proba.asm
     А после этого сделать сначала .OBJ файл:


           tasm.exe    /l    proba.asm
                      LT-
                       L---- будет создан файл листинга proba.lst
                               (там Вам покажут ошибки - если они есть)

     а потом - и .COM файл:

           tlink.exe    /t    proba.obj
                       LT-
                        L--- будет создан .COM файл

     Если Вы не знакомы с пакетом TASM и это - Ваш первый опыт, то можете по-
ка-что пропустить (особо не задумываясь) всякие  диррективы, предшествующие и
последующие за текстом основной программы (TITLE ...; ASSUME ...; CodeSegment
SEGMENT  PARA;  ORG(100h);MainProcedure ENDP; CodeSegment ENDS; END Start  ).
Поступайте  с  ними пока-что чисто механически. (На  досуге  можете  почитать
/1/,/2/,/7/)
     Итак, у  нас есть готовый COM. модуль, который  можно загрузить и выпол-
нить.
     И он напечатает литеру 'a'.
     Замечательно!


     А вот тут пример того  как решить  ту же задачу не JMP Far-ом, а -- CALL
Far-ом Разница в том, что в этом случае не нужно прятать в стек значения CS и
IP для точки возврата из п/п-мы обработки прерывания (CALL Far  оказался "ум-
нее" - он делает это автоматически).

      -----------------------------------------------------------¬
      ¦                         пример 2                         ¦:
      L-----------------------------------------------------------

TITLE   Это - COM. программа N2 для демонстрации механизма вызова прерываний
ASSUME        CS:CodeSegment
;---------------------------------------------------------------------------
CodeSegment   SEGMENT PARA
              ORG(100h)
Start:
MainProcedure PROC NEAR
              ;
              ;
              ;
              XOR  DX,DX         ; DX = 0
              MOV  DS,DX         ; DS = 0
              ;
              PUSHF              ;запасаем информацию, необходимую для автома-
              ;                  ;тического ыозврата из п/п-ы обработки прерыв-я
              ;
              MOV  AH,0Eh        ;входные
              MOV  AL,61h        ;       параметры прерыв-я 10h
              ;
              ;
              CALL dword ptr DS:[40h] ;длинный вызов п/п-ы обработки прерыв-я 10h
              ;                       ;(по адресу 0:40h - адрес п/п-ы обработки)
              ;                       ;(два слова)
              ;
              RET                ;закончить программу и вернуться в DOS
              ;
              ;
              ;
MainProcedure ENDP
              ;
CodeSegment   ENDS
              END Start


     И последнее, что мы сделаем в этой главе, - научимся давать вызов преры-
вания, не пользуясь INT-ом и не  обращаясь каждый раз к таблице векторов. За-
чем  ?  Это  иногда полезно. Дело в том, что 'вирусы' и 'драконы' очень часто
пользуются прерываниями и при этом должны оставаться необнаруживаемыми. А ес-
ли прерывание дается  командой INT, то охранные системы (всевозможные антиви-
русные мониторы) тут же узнаЮт об  этом и могут насторожиться. Если мы посто-
янно пользуемся таблицей векторов, то где гарантия, что антивирусные мониторы
межу делом не подложили в нее адрес СВОЕЙ п/п-мы, и, вместо того, чтобы полу-
чить сервис п/п-мы-обработчика прерыв-я, мы попадаем в засаду. А если мы сох-
раним в коде нашей программы адрес п/п-мы исходного обработчика прерыв-я (и в
тот момент  будем абсолютно уверены, что имеем  дело не  с 'оборотнем') то  в
дальнейшем сможем смело делать JMP Far или CALL Far без опасения быть обнару-
женными.

     Вот готовая программа: (коментарии см. ниже)

      -----------------------------------------------------------¬
      ¦                         пример 3                         ¦:
      L-----------------------------------------------------------

TITLE   Это - COM. программа N3 для демонстрации механизма вызова прерываний
ASSUME        CS:CodeSegment
;---------------------------------------------------------------------------
CodeSegment   SEGMENT PARA
              ORG(100h)
Start:
MainProcedure PROC NEAR
              ;
              ;
              ;
              JMP  over_data           ; перепрыгнем через данные
              ;
              ;
saved_int10:  DD   0                   ; данные (хранилище для адреса INT 10h
              ;                        ;   -- 2 слова)
              ;
over_data:    XOR  DX,DX               ; DX = 0
              MOV  DS,DX               ; DS = 0
              ;
              ;--сохраняем в хранилище адрес исходн. п/п-мы INT 10h (2 слова)-¬
              ;                                    ;                          ¦
              MOV  AX,DS:[10h*4]                   ;мы указываем лишь порядко-¦
              MOV  word ptr CS:[saved_int10  ],AX  ;вый номер прерывания      ¦
              MOV  AX,DS:[10h*4+2]                 ;                          ¦
              MOV  word ptr CS:[saved_int10+2],AX  ;                          ¦
              ;----------------------------------------------------------------
              ;
              ;--запасаем в стеке информацию, необходимую для автоматического-¬
              ;         возврата  из п/п-мы обработки прерыв-я                ¦
              ;                                    ;                          ¦
              PUSHF                                ;                          ¦
              PUSH CS                              ;                          ¦
              MOV  BX,OFFSET after_int             ;---¬  засунуть в стек     ¦
              PUSH BX                              ;---+- IP точки возврата   ¦
              ;----------------------------------------------------------------
              ;
              ;
              MOV  AH,0Eh                     ;входные параметры
              MOV  AL,61h                     ;  прерыв-я 10h (печатать 'a')
              ;
              JMP  dword ptr CS:[saved_int10] ;длин. джамп по адресу, котор. на-
              ;                               ; ходится теперь в хранилище
after_int:    ;                               ;   saved_int10
              ;
              RET                             ;закончить программу и вывалиться
              ;                               ;  в DOS
              ;
              ;
MainProcedure ENDP
              ;
CodeSegment   ENDS
              END Start


     Что  здесь  нового?  Совсем  немного.  Во-первых   мы  перетащили  адрес
п/п-мы-обработчика прерывания 10h  из таблицы векторов в тело нашей прогр-мы.
Во-вторых мы теперь делаем JMP Far  не на адрес в таблице векторов (dword ptr
00:[40h]),  а  на  адрес,  сохраненный  в  теле  нашей  прогр-мы  (dword  ptr
CS:[saved_int10]). Есть одна  громоздкость -- данные (saved_int10: DD 0) дол-
жны определяться перед  их использованием (MOV word ptr CS:[saved_int10 ],AX)
и, следовательно, мы должны в начале через них перепрыгнуть. Этот бардак свя-
зан с особенностями TASM-овской компиляции.
Далее
 

 
Интересное в сети
 
10 новых программ
CodeLobster PHP Edition 3.7.2
WinToFlash 0.7.0008
Free Video to Flash Converter 4.7.24
Total Commander v7.55
aTunes 2.0.1
Process Explorer v12.04
Backup42 v3.0
Predator 2.0.1
FastStone Image Viewer 4.1
Process Lasso 3.70.4
FastStone Image Viewer 4.0
Xion Audio Player 1.0.125
Notepad GNU v.2.2.8.7.7
K-Lite Codec Pack 5.3.0 Full


Наши сервисы
Рассылка новостей. Подпишитесь на рассылку сейчас и вы всегда будете в курсе последних событий в мире информационных технологий.
Новостные информеры. Поставьте наши информеры к себе и у вас на сайте появится дополнительный постоянно обновляемый раздел.
Добавление статей. Если вы являетесь автором статьи или обзора на тему ИТ присылайте материал нам, мы с удовольствием опубликуем его у себя на сайте.
Реклама на сайте. Размещая рекламу у нас, вы получите новых посетителей, которые могут стать вашими клиентами.
 
Это интересно
 

Copyright © CompDoc.Ru
При цитировании и перепечатке ссылка на www.compdoc.ru обязательна. Карта сайта.