Assembler - язык неограниченных возможностей


Пассивная резидентная программа - часть 3


Прежде чем это сделать, заметим, что и номер диска, и адрес предыдущего обработчика INT 21h изменяются только при установке резидента и являются константами во время всей его работы. Более того, каждое из этих чисел используется только по одному разу. В этих условиях оказывается, что можно вписать номер диска и адрес перехода на старый обработчик прямо в код программы. Более того, после этого наш резидент не будет больше ссылаться ни на какие переменные с конкретными адресами, а значит, его код становится перемещаемым, то есть его можно выполнять, скопировав в любую область памяти.

; tsrpsp.asm ; Пример пассивной резидентной программы с переносом кода в PSP. ; Запрещает удаление файлов на диске, указанном в командной строке, ; всем программам, использующим средства DOS

.model tiny .code org 2Ch envseg dw ? ; сегментный адрес копии окружения DOS

org 80h cmd_len db ? ; длина командной строки cmd_line db ? ; начало командной строки

org 100h ; СОМ-программа start: old_int21h: jmp short initialize ; переход на инициализирующую часть

int21h_handler proc far ; обработчик прерывания 21h pushf ; сохранить флаги cmp ah,41h ; Если вызвали функцию 41h ; (удалить файл) je fn41h cmp ax,7141h ; или 7141h (удалить файл ; с длинным именем), je fn41h ; начать наш обработчик, jmp short not_fn41h ; иначе - передать ; управление предыдущему обработчику fn41h: push ax ; сохранить модифицируемые push bx ; регистры mov bx,dx ; можно было бы использовать ; адресацию [edx+1], но в старшем ; слове EDX совсем не обязательно 0, cmp byte ptr [bx+1],':' ; если второй символ ; ASCIZ-строки, переданной INT 21h, ; двоеточие, первый символ должен ; быть именем диска, je full_spec mov ah,19h ; иначе: int 21h ; функция DOS 19h - определить ; текущий диск add al,'А' ; преобразовать номер диска ; к заглавной букве jmp short compare ; перейти к сравнению full_spec: mov al,byte ptr [bx] ; AL = имя диска из ASCIZ-строки and al,11011111b ; преобразовать к заглавной букве compare: db 3Ch ; начало кода команды CMP AL,число drive_letter: db 'Z' ; сюда процедура инициализации ; впишет нужную букву pop bx ; эти регистры больше не pop ax ; понадобятся, если диски совпадают - je access_denied ; запретить доступ not_fn41h: popf ; восстановить флаги и передать ; управление предыдущему ; обработчику INT 21h: db 0EAh ; начало кода команды ; JMP, FAR-число old_int21h dd 0 ; сюда процедура инициализации ; запишет адрес предыдущего ; обработчика INT 21h access_denied: popf push bp mov bp,sp ; чтобы адресоваться в стек ; в реальном режиме, or word ptr [bp+6],1 ; установить флаг ; переноса (бит 0) в регистре ; флагов, который поместила команда ; INT в стек перед адресом возврата pop bp mov ax,5 ; возвратить код ошибки ; "доступ запрещен" iret ; вернуться в программу int21h_handler endp




Начало  Назад  Вперед