Консультация № 143350
08.09.2008, 14:38
0.00 руб.
08.09.2008, 14:41
0 2 2
Вопрос по рассылке Калашникова №10(резидент). Её код в приложении.
Мне непонятно место [pushf ;Так надо! Позже рассмотрим]. Мы же в самом начале процедуры сохраняли регистры флагов, зачем это делается еще раз перед переходом на оригинальный обработчик? и всеравно потом востанавливаем со стека регистры только один раз...

Приложение:
CSEG segment
assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG
org 100h

Start:

;Переходим на метку инициализации. Нам нужно будет перехватить прерывание 21h,
;а также оставить программу резидентной в памяти
jmp Init

; ==== Обработчик 21h-ого прерывания ====

;Ниже идет, собственно, обработчик 21h прерывания (он будет резидентный).
;После того, как программа выйдет, процедура Int_21h_proc останется в памяти
;и будет контролировать функцию 09 прерывания 21h.

Int_21h_proc proc
pushf
cmp ah,9 ;Проверим: это функция 09h?
je Ok_09 ;Если так, то на метку Ok_09
popf
;Если нет, прейдем на оригинальный обработчик прерывания 21h.
;Всё. На метку Ok_09 программа уже не вернется.
jmp dword ptr cs:[Int_21h_vect]

Ok_09:
push ds ;Сохраним регистры
push dx
push cs ;Адрес строки должен быть в DS:DX
pop ds

;Выводим нашу строку (My_string) вместо той, которую должна вывести
;программа, вызвавшая 21h-ое прерывание
mov dx,offset My_string
pushf ;Так надо! Позже рассмотрим
call dword ptr cs:[Int_21h_vect]

pop dx ;Восстановим использованные регистры
pop ds
popf
iret ;Продолжим работу (выйдем из прерывания)
;Программа, выводящая строку, считает, что на экран было выведено ее
;сообщение. Но на самом деле это не так!

;Переменная для хранения оригинального адреса обработчика 21h
Int_21h_vect dd ?

;Строка, которая будет выводится
My_string db 'Моя строка!$'

int_21h_proc endp

; ==== Конец обработчика 21h-ого прерывания ====




;Со следующей метки нашей программы уже не будет в памяти
;(это нерезидентная часть). Она затрется сразу после выхода (после
;вызова прерывания 27h).

Init:
;Установим наш обработчик (Int_21h_proc) (адрес нашего обработчика,
;если быть точнее) на 21h прерывание. Это позволяет сделать функция
;25h прерывания 21h.
;Но прежде нам нужно запомнить оригинальный адрес этого прерывания.
;Для этого используется функция 35h прерывания 21h:

mov ah,35h ;AH содержит номер функции (это понятно)
mov al,21h ;AL указывает номер прерывания, адрес (или вектор)
;которого нужно получить
int 21h ;Теперь в ES:BX адрес (вектор) 21h прерывания
;(ES - сегмент, BX - смещение)

mov word ptr Int_21h_vect,bx
mov word ptr Int_21h_vect+2,es ;! Обратите внимание на форму записи

;Итак, адрес сохранили. Теперь перехватываем прерывание:
mov ax,2521h
mov dx,offset Int_21h_proc ;DX должен указывать на наш
;обработчик (т.е. Int_21h_proc)
int 21h

;Все! Теперь, если какая-либо программа вызовет 21h, то вначале компьютер
;попадет на наш обработчик (Int_21h_proc).
;Что осталось? Завершить программу, оставив ее резидентной в памяти
;(чтобы никто не затер наш обработчик, иначе компьютер зависнет).

mov dx,offset Init
int 27h
;Прерывание 27h выходит в DOS (как 20h), при этом оставив нашу программу
;резидентной. DX должен указывать на последний байт, остающийся в памяти
;(это как раз метка Init). Т.е. в памяти остается от 0000h до адреса,
;по которому находится метка Init.

CSEG ends
end Start

Обсуждение

давно
Старший Модератор
31795
6196
08.09.2008, 14:59
общий
это ответ
Здравствуйте, Draft3!
mov dx,offset My_string
pushf ;Так надо! Позже рассмотрим
call dword ptr cs:[ Int_21h_vect ]

Из программного прерывания возврат происходит с помощью команды IRET, котороая помимо сегмента и смещения в сегменте точки возврата извлекает ещё и регистр флага. Эти строки имитируют фунцию 09h/21h, но если подставить вместо них прерывание 21h, то мы снова попадем в свой обработчик - т.е. закнутый круг, а так вызываем старый обработчик прерывания, возвращаемся в свой обработчик, востанавливаем используемые регистры и возвращаемся в программу.
pushf ;тут сохранили регистр
cmp ah,9 ;Проверим: это функция 09h?
je Ok_09 ;Если так, то на метку Ok_09
popf ;а тут востановили его, т.к. это может и не наша функция

Команда стоит для того, чтобы не влиять на значения регистра флага, т.к. в самом обрабочике происходит сравнение.
Удачи!
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
08.09.2008, 15:59
общий
это ответ
Акктуально если только их анализирует перехваченный обработчик, он тоже может быть не оригинальный.
Форма ответа