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

Автор работы: Пользователь скрыл имя, 14 Мая 2012 в 16:48, курсовая работа

Описание

В данной работе рассмотрено явление, которое в операционной системе MSDOS играет роль многозадачности. С истинной многозадачностью можно столкнуться, рассматривая программирование в операционной системе Windows. Многозадачность же, рассматриваемая в этой курсовой работе, может быть названа нелегальной. Термин TSR происходит от английской фразы Terminate State Resident, т.е. "завершить и остаться резидентным". Резидентная программа, находясь в памяти, выполняет свои функции через перехваченные прерывания. Связь с резидентной программой также осуществляется посредством прерываний.

Содержание

1 РЕЗИДЕНТНЫЕ ПРОГРАММЫ 4
2 ЗАЩИТА РЕЗИДЕНТНЫХ ПРОГРАММ ОТ ПОВТОРНОЙ УСТАНОВКИ .....8
3 ВЫГРУЗКА РЕЗИДЕНТНЫХ ПРОГРАММ ИЗ ПАМЯТИ 12
4 ОПИСАНИЕ ПРОГРАММЫ 13
Заключение 21
Литература 22
Приложение-листинг 23
Приложение-рисунок 35

Работа состоит из  1 файл

Kura.doc

— 148.00 Кб (Скачать документ)

mov si,80h lodsb cmp al,3 jl bue inc si lodsw cmp ax,'u/' jne bue



 

mov ax,3528h int21h push ds

 

Ids dx,dword ptr es:old_09

mov ax,2509h

int21h

 

Ids dx,dword ptr es:old_l С

mov ax,251Ch

int21h

Ids dx,dword ptr es:old_28 mov ax,2528h int 21h

Ids dx,dword ptr es:old_2F

mov ax,252Fh

int 21h

pop ds

mov ah,49h

int 21h

mov es,word ptr es:[0()2ch] mov ah,49h int 21h

bue:

mov ax,4c00h

int 21h TSRprog   endp code_seg ends end begin

 

Во-первых, сразу запросим прерывание 2F - нет ли нашей программы в памяти. Для этого занесем в АХ запланированный нами код функции (см. выше процедуру New_2F - мы там решили занять для своих нужд функцию 80 и подфункцию 00 . Проверим поступивший из прерывания «отзыв». Наша программа должна отозваться кодом 0ABCD (см.выше процедуру New_2F).

Если это так, то мы пытаемся второй раз установить программу - это не нужно, а может быть мы хоти выгрузить ее из памяти? Надо проверить ключ в строке параметров запуска программы, поэтому перейдем к метке analiz.

В противном случае начинаем установку программы резидентом в памяти. Для этого сначала сохраним адреса старых векторов прерываний, которые мы планируем заместить своими процедурами. Начнем с вектора 28h. Используя стандартную функцию 35h прерывания 21h получим этот вектор в ES:BX и сохраним его в специально подготовленной ячейке old_28 (см.выше).

С помощью стандартной функции 25п прерывания 21h на место старого вектора установим адрес нашей процедуры, и затем то же самое проделаем с вектором 2Fh и с вектором 1 Ch.

Разместим в регистре dx адрес начала не резидентной части программы с помощью прерывания 27h завершим нашу программу, оставив ее в памяти резидентной:

 

lea dx,start int 27h

Теперь удем анализировать содержимое строки параметров нашей программы. После запуска программы, содержимое командной строки операционная система размещает по смещению 80h в PSP программы. Точнее по самому смещению 80h находится байт, в котором размещается число, равное количеству символов в строке параметров. Получим его из PSP, для чего смещение интересующего нас байта занесем в SI. Потом загрузим этот байт в AL:

 

lodsb

и проверим, не меньше ли длина строки параметров 3-х символов. Если меньше, то выйти из программы , иначе перейдем на адрес следующего байта командной строки и возьмем из нее в АХ два байта. Проверим, это наш ключ /и:

 

cmp ах,'и/'

если не равно, то это не наш ключ и программу завершаем. В противном случае начинаем модуль выгрузки программы из памяти. Для начала загрузим регистры ES:BX адресом нашей программы в памяти для чего возьмем вектор любого из контролируемых ею прерываний, например, 28h:

 

mov ax,3528h int 21h

Теперь сохраним регистр ds.

Загрузим регистры DS:DX адресом старого вектора прерывания 1С взятого из памяти нашей программы, которая сейчас стоит резидентом:

 

Ids dx,dword ptr es:old_09

mov ax,2509h

int21h

Ids dx,dword ptr es:old_lC

 

To же сделаем с прерыванием 28h и прерыванием 2F. Восстановим регистр DS. Используя стандартную функцию 49h прерывания 21h, освободим память, занимаемую нашей резидентной программой. Функция освобождает память, сегмент которой стоит в ES. А там как раз адрес начала нашей резидентной программы:

 

mov ah,49h int 21h

 

Теперь надо освободить память, занятую блоком окружения программы. Возьмем оттуда этот адрес и поместим его в ES:

mov es,word ptr es:[002ch] после чего дадим команду освободить этот блок:

mov ah,49h

int 21h

Когда блок окружения программы свободен,   завершить программу и возвратиться в операционную систему: bue:

mov ax,4c00h

int 21h TSRprog   endp code_seg ends end begin

Заключение

 

Многие программы, обеспечивающие функционирование вычислительной системы (драйверы устройств, программы сжатия или шифрования данных, русификаторы, интерактивные справочники и др.), должны постоянно находиться в памяти и быстро реагировать на запросы пользователя или на какие-то события, происходящие в вычислительной системе. Такие программы носят название программ, резидентных в памяти (Terminate and Stay Resident, TSR), или просто резидентных. Сделать резидентной можно любую программу, однако ввиду того, что резидентная программа должна быть максимально компактной, чаще всего в качестве резидентных используют программы типа .СОМ.



 

Литература

1.      Пирогов В.Ю. ASSEMBLER Учебный курс Москва Издатель Молгачева СВ., 2001

2.      Зубков С. В. ASSEMBLER -язык неограниченных возможностей Издательство «ДМК Пресс», 1999

3.      АССЕМБЛЕР И ПРОГРАММИРОВАНИЕ ДЛЯ IBM PC Под редакцией Ершова В.Г.

4.      В. И. Юров ASSEMBLER Учебник для вузов. 2-е изд. / В. И. Юров — СПб.: Питер, 2003. —637 с: ил.

5.      Рудаков П. И., Финогенов К. Г. Язык ассемблера: уроки программирования. - М.: ДИАЛОГ-МИФИ, 2001. - 640 с.

6.      Интернет.

Приложение-листинг

 

 

code_seg segment TSRprog proc far

assume cs:code_seg

org lOOh begin:

jmp start

 

 

old_09      dw ? dw?

 

 

New_09 Proc pushf

call cs:dword ptr old_09 cli

mov ah, 0lh int 16h jz exit_int

cmp al,'q'; clear Cnt, key combination 'q'

jne exit_int

mov cs:cnt,0

exit_int:q sti iret

New_09 endp

 

 

New_2F Proc

;обработка мультиплексного прерывания



24

 



24

 

 

 

 

 

 

 

 

 

 

 

 

exit:


cli

cmp ax,08000h

jne exit

mov ax, OABCDh

sti

iret

 

 

sti

jmp cs:[O1d_2F] Old 2F DD 0


;запретим на время все прерывания в ОС ; проверим, а нашу ли программу вызывают? ;если нет, то выйти из процедуры. ;иначе - отправить пароль «я здесь» разрешить опять все прерывания в ОС. ; выйти из прерывания

 

 

разрешить опять все прерывания в ОС. ;и перейти по адресу старого обработчика прерывания 2F.

 

 

;это место под адрес старого обработчика прерывания 2F.



21

New_2F endp

 

 

 

 

 

 

 

New 1С Proc

 



21

 

 

 

 

 

 

 

 

 

 


cmpcs:Cnt,9      1              ;проверяем прошло ли 5 сек.?

jb М2              ;если нет, то переход на увеличение счетчика jb

mov cs:flg_timer,l              

 

 

M2:

 

 

 

 

 

 

 

;проверяем, прошло ли 5 секунд?

;если нет, то переход на увеличение счетчика jb

;сообщение можно выводить, поэтому установим

;в ячейке флага истечения

контрольного времени 1

 

 

 

 

inc byte ptr cs:Cnt              увеличить счетчик времени на 1

jmp cs:[O1d_lC]              ;перейти по адресу обработчика прерывания 2F.

01d_lC DD 0              ;адрес обработчика прерывания 2F.

Cnt DB 0              ;ячейка для счетчика тиков



21

 

flg_timer DB 0              ;ячейка для флага истечения заданного времени

New_lC endp

 

 

 

 

New_28 proc

;сохраним регистр флагов процессора

 

 

pushf

; проверим - в ячейке флага контроля истечения заданного времени установлена ли единица?

cmp cs:flg_timer,l

;если нет, то время до вывода сообщения на экран ;еще не истекло и мы переходим на старый ;обработчик прерывания 28h

jne Ml

;в противном случае активизируем модуль вывода

;сообщения на экран. Для чего

;сначала сохраним в стеке регистры, которые

;сейчас начнем использовать. Иначе

;мы испортим в них данные прерванной нами

программы.

push ах push bx push bp push es push cx

;3апретим прерывания нашей программы другими программами

        mov ah, OFh                                         ;Читаем текущий видео режим

int 1 Oh                                         ;bh <- номер активной страницы дисплея

 

 

mov ax,cs

mov es,ax              ;Выводимая строка

   ;Количество строк

  ;Вызов random

;Строка начала вывода

mov bp,offset curtime

 

mov cl,25

call random

mov dh,al

 

 

mov cl,73              ;Количество колонок - количество символов

;(80-7)

call random              ;Вызов random

mov dl,al              ;Колонка начала вывода

 

 

mov bl,2Eh              ;Атрибуты строки: желтые буквы на

;зеленом фоне

mov сх,7              ;Длина строки

mov ax,1300h              ;Вывод

int 10h

 

 

jmpql

 

 

random:

;Сохраняем в стек регистры

push es



 

 

push bx push dx push cx

 

 

mov ah,0              ;Читаем часы

int lAh              ;cx - старшая часть значения

;dx - младшая часть значения

mov es,cx mov bx,dx

mov al,byte ptr es:[bx]           ;Возвращаемое значение



 

 

 

11:

 

 

 

 

 

 

 

 

 

12:


pop cx

 

 

cmp al,cl jb 12

sub al,cl jmp 11


;Восстанавливаем

 

 

; Сравнение

;Если ниже

;Иначе CL - AL ;Повторная проверка

 

 

;Восстанавливаем сохраненные регистры



 

pop              dx

pop              bx

pop              es
ret

 

 

 

 

 

 

mov cs:flg_timer,0 mov cs:cnt,0


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

;разрешим внешние прерывания



 

 



 

 

 

 

 

 

 

 

 

 

 

 

 

 

Ml:


sti

 

 

pop cx pop es pop bp pop bx pop ax

 

 

popf


 

восстановим все сохраненные регистры



 

 

 

 

 

 

jmp cs:[old_28]


;В заключение процедуры передадим управление старому обработчику

 

 

;А это область данных нашей процедуры New_28. ; Здесь хранится текстовая строка выводимая на ;экран ПЭВМ



 

curtime db "Message'

old_28 dd 0

New_28 endp

 

 

start:



 

 

 

 

 

 

 

 

 

 

 

 

 

mov ax,08000h


;Во-первых, сразу запросим прерывание 2F - нет

ли нашей программы в памяти?

;Для этого занесем в АХ запланированный нами

;код функции (см. выше процедуру

;New_2F - мы там решили занять для своих нужд

функцию 80 и подфункцию 00

 

 

; Обратимся к функции 2F



 

int 2Fh



 

 

;Проверим поступивший из прерывания «отзыв». ;Наша программа должна отозваться кодом

;0ABCD (см.выше процедуру New_2F)

cmp ax,0ABCDh

;Если это так, то мы пытаемся второй раз

установить программу - это не нужно,

;а может быть мы хоти выгрузить ее из памяти?

;Надо проверить ключ в строке

параметров запуска программы, поэтому

перейдем к метке ANALIZ

je analiz

;В противном случае начинаем установку программы резидентом в памяти ;Для этого сначала сохраним адреса старых ; векторов прерываний, которые мы ;планируем заместить своими процедурами. ;Начнем с вектора 28h. Используя стандартную функцию 35h прерывания 21h ;получим этот вектор в ES:BX

mov ax,3528h

int 21h

;и сохраним его в специально подготовленной ;ячейке old_28 (см.выше)

mov word ptr old_28,bx

mov word ptr old_28+2,es

;C помощью стандартной функции 25h прерывания 21h на место старого вектора установим адрес нашей процедуры

mov ax,2528h

lea dx,new_28

int21h

; Теперь то же самое проделаем с вектором 2Fh

mov ax,352Fh

int 21h

mov word ptr old_2F,bx

mov word ptr old_2F+2,es

mov ax,252Fh

lea dx,New_2F

int21h

;и с вектором lCh

mov ax,351Ch

int21h

mov word ptr old_lC,bx

mov word ptr old_lC+2,es

mov ax,251Ch

lea dx,New_lC

int21h

 

 

mov ax,3509h

int21h

mov word ptr old_09,bx

mov word ptr old_09+2,es

mov ax,2509h

lea dx,New_09

int21h



27

 



27

 

 

 

 

lea dx, start

 

 

 

 

int 27h analiz:


;Разместим в регистре dx адрес начала НЕ РЕЗИДЕНТНОЙ части программы

 

;с помощью прерывания 27h завершим нашу

программу, оставив

;ее в памяти резидентной



27

занесем в SI

mov si,80h

 

 

lodsb

 

 

cmp al,3

jl bue

;Будем анализировать содержимое строки

щараметров нашей программы.

Информация о работе Резидентные программы