Лидеры рейтинга

ID: 259041

Алексеев Владимир Николаевич

Мастер-Эксперт

1757

Россия, пос. Теплоозёрск, ЕАО


ID: 400669

epimkin

Профессионал

685


ID: 226425

Konstantin Shvetski

Мастер-Эксперт

564

Россия, Северодвинск


ID: 400828

mklokov

10-й класс

269

Россия, Санкт-Петербург


ID: 404373

aDair

1-й класс

165


ID: 137394

Megaloman

Мастер-Эксперт

158

Беларусь, Гомель


ID: 400484

solowey

Профессор

122


8.1.0

30.11.2020

JS: 2.1.8
CSS: 4.1.7
jQuery: 3.5.1


 

• Assembler

Создание программ на языке Assembler.

Администратор раздела: Зенченко Константин Николаевич (Старший модератор)


Коцюрбенко Алексей Владимирович
Статус: Старший модератор
Рейтинг: 2162
Зенченко Константин Николаевич
Статус: Старший модератор
Рейтинг: 243
Лысков Игорь Витальевич
Статус: Мастер-Эксперт
Рейтинг: 0
 

Перейти к консультации №:
 

Консультация онлайн # 175115
Раздел: • Assembler
Автор вопроса: Земцов Дмитрий Анатольевич
Дата: 10.12.2009, 22:31
Поступило ответов: 2

Доброго времени суток уважаемые эксперты. С целью ознакомления решил написать резидентную программу ОС MS-DOS, которая запрещала создавать файл с определенным именем. Написал резидентную часть программы перехватывающее прерывание 21h функции 3Ch — Создание файла(резидент приведен в приложении).
Функция DOS 3Ch — Создать файл

Ввод: AX = 3Ch
СХ = атрибут файла
бит 7: файл можно открывать разным процессам в Novell Netware
бит 6: не используется
бит 5: архивный бит (1, если файл не сохранялся)
бит 4: каталог (должен быть 0 для функции 3Ch)
бит 3: метка тома (игнорируется функцией 3Ch)
бит 2: системный файл
бит 1: скрытый файл
бит 0: файл только для чтения
DS:DX = адрес ASCIZ-строки с полным именем файла (ASCIZ-строка ASCII-символов, оканчивающаяся нулем)
Вывод: CF = 0 и АХ = идентификатор файла, если не произошла ошибка
CF = 1 и АХ = 03h, если путь не найден
CF = 1 и АХ = 04h, если слишком много открытых файлов
CF = 1 и АХ = 05h, если доступ запрещен

Следовательно, для достижения цели нам нужно при перехвате прерывания функции создания нового файла:
1)Сравнить имя создаваемых с именем запрещенным
2) Если совпадают вызвать ошибку(как я понял флаг CF в 1 и любой код ошибки в AX)
3) Если нет вернуть управление.

Возникшие вопросы:
1) При создании имя файла храниться DS:DX, при перехвате прерывания где будет храниться название создаваемого файла
2) Как можно будет сравнить имена файлов? Циклом посимвольно или есть другой способ?
3) Вызвать ошибку будет достаточно установить флаг CF в 1 и любой код ошибки в AX и вернуть управление или я ошибаюсь?
4) Я не много не уверен в правельности вектора прерывания в моей резиденте...

Приложение:

Состояние: Консультация закрыта

Здравствуйте, Земцов Дмитрий Анатольевич.
Всегда приятно не делать за кого-то, а помочь разобраться... Итак:
1) Совершенно верно, при создании имя файла хранится в DS:DX, т.е. используются длинные указатели.
Поэтому при прехвате там его надо и искать.
2) Сравнивать две строки лучше всего следующим образом

mov si, dx ;DS:SI - адрес имени создаваемого файла
les di,TestName ;загрузка ES:DI адресом строки с тестовым именем
mov cx,TestNameLen ;длина тестового имени с завершающим нулем
repe cmpsb ;сравниваем, пока равно
je Equal ;делаем выводы
NotEqual:
Не забываем о том, что работаем в прерывании, поэтому сохраняем все используемые регистры
3) В принципе, верно: устанавливаем CF=1 и даем код ошибки в AX.
Только код надо давать не любой, а соответствующий. Лучше всего, пожалуй, подойдет 5 (Access denied)
4) Код вполне рабочий, за исключением:
Меняем вектор прерывания 21h, а не 3Ch, поэтому надо писать MOV AX,3521h и, соответственно, MOV AX,2521h
Только код же ничего не делает :)
Надо же, хотя бы, проверять на номер перехватываемой функции...
5) Файл можно еще создать при помощи функции 16h
6) Желательно принимать меры, чтобы резидент не устанавливался повторно и/или имел возможность выгрузиться
Удачи!
В приложении исправленная Ваша программа

Приложение:


Консультировал: Лысков Игорь Витальевич (Мастер-Эксперт)
Дата отправки: 11.12.2009, 09:49

5
Спасибо огромное за советы, а так же за помощь в изучении работы с флагами и сравнение строки в асм
-----
Дата оценки: 11.12.2009, 23:44

Рейтинг ответа:

0

[подробно]

Сообщение
модераторам

Отправлять сообщения
модераторам могут
только участники портала.
ВОЙТИ НА ПОРТАЛ »
регистрация »

Здравствуйте, Земцов Дмитрий Анатольевич.

В дополнение ответа Игоря Витальевича, в приложении код, который:
- устанавливает свой обработчик;
- контролирует повторный запуск;
- контролирует функцию создания файла 3С и подменяет её;
- возвращает стандартную ошибку.
Приблизительно так это работает:

Контроль повторного запуска, приведен в учебных целях, как возможный вариант, но он не дает полной гарантии, т.к. вполне возможен перехват другим резидентом. Но он показывает способ сравнения строк.

В регистрах DS:DX хранится адрес памяти с именем файла, но тамже может хранится дополнительно ещё и путь к нему, т.е. приблизительно в таком виде D:\_CAT\_LANG\my_LIB\check.txt. Если путь к файлу не указан, то файл создается в текущем каталоге, иначе в указаном. Этот момент тоже нужно учитывать при анализе имени файла.

Удачи!

Приложение:


Консультировал: Зенченко Константин Николаевич (Старший модератор)
Дата отправки: 11.12.2009, 15:32

5
Спасибо огромное за советы, а так же за детальный пример разидентной программы прерыванием 21h функции 3Ch
-----
Дата оценки: 11.12.2009, 23:46

Рейтинг ответа:

0

[подробно]

Сообщение
модераторам

Отправлять сообщения
модераторам могут
только участники портала.
ВОЙТИ НА ПОРТАЛ »
регистрация »

Мини-форум консультации № 175115

Зенченко Константин Николаевич

Старший модератор

ID: 31795

1

= общий = |  11.12.2009, 10:48 |  цитировать |  профиль |  личное сообщение

Лысков Игорь Витальевич:
smile

Цитата:
MOV AX,353Ch

Прерывание не то:
Цитата:
Int 3C - FLOATING POINT EMULATION - INSTRUCTIONS WITH SEGMENT OVERRIDE

smile

=====
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.
smile

Лысков Игорь Витальевич

Мастер-Эксперт

ID: 7438

2

= общий = |  11.12.2009, 10:56 |  цитировать |  профиль |  личное сообщение

Земцов Дмитрий Анатольевич:
А-а-а, ну да.... smile На автомате не заметил...
Меняем на MOV AX,3521h и, соответственно, MOV AX,2521h

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

Зенченко Константин Николаевич

Старший модератор

ID: 31795

3

= общий = |  11.12.2009, 15:35 |  цитировать |  профиль |  личное сообщение

Забыл добавить, ниже тестовая программа:

model tiny
.code
.186
org 100h
begin:
mov	ah,3ch
xor	cx,cx
mov	dx,offset myName
int	21h
jc	isStop
mov	bx,ax
mov	ah,3eh
int	21h
xor	ax,ax
int	16h
ret
isStop:
mov	ah,9
mov	dx,offset myName
int	21h
xor	ax,ax
int	16h
ret
myName	db	'error.fil',0,'$'
end	begin

Удачи!

=====
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.
smile

неизвестный

4

= общий = |  11.12.2009, 22:20

Спасибо большое разобрался в ваших кодах, но хотелось бы доделать поставленую задачу, а имеено запрещать создавать файл с опр именем файла(пока что без учета пути). Ниже приведен код на основе программы Зенченко Константина Николаевича. Не могу найти ошибку(разрешает создавать все возможные файлы) помоему возможны 1 ошибки
а) ошибка в сравнении имен файлов(Лысков Игорь Витальевич, у вас в строке кода les di,TestName мне кажеться ошибка, кроме как оператора lea мне больше не чего не вспомнилось)
б) ошибка в переходах(где я уже помоему сам запутался)

И еще если можно пару вопросов:
1) Назначение этой сторки CALL CS:OLD_VEC как я понимаю вызов старого прерывания, но для чего?
2) При создании файла в MS-DOS командой copy con или copy создаеться файл при помощи какого прерывания и какой функции, можно ли это отследить резидентной программой?

model tiny
.code
.186
org	100h
begin:		
		jmp	init
;данные о старом векторе
		old_vec21	label	dword
		old_21o		dw	?
		old_21s		dw	?
;контролируемая строка
		check_name	db	'check.txt',0
;наш обработчик
new_vec21:
		cmp	ah,3Ch
		je	isInterupt
		
		jmp 	notInt
;наша функция
isInterupt:
		pusha
		push SI
		push DI
		push CX
		mov si,DX  		
		mov di,offset check_name
		mov cx,9	 	
		repe cmpsb		
		jne notintf 		

Equal:
		STC
		mov ax,5
		pop CX
		pop DI
		pop SI
		popa
		jmp exit1
notint:
		jmp	cs:old_vec21
notintf:
		pop CX
		pop DI
		pop SI
		popa
		jmp	cs:old_vec21
exit1:
		iret
;инициализация
init:		mov	ax,3521h
		int	21h
;запоминаем старый вектор
		mov	old_21o,bx
		mov	old_21s,es
;контролируем присутсвие
		mov	cx,9h
		mov	si,107h
		mov	di,107h
		repe	cmpsb
		or	cx,cx
		jz	isStop
;сообщение о начале работы
isGo:		mov	ah,9
		mov	dx,offset dbMessageGo
		int	21h
;ставим свой вектор
		mov	ax,2521h
		mov	dx,offset new_vec21
		int	21h
;выходим
		mov	dx,offset init
		int	27h
dbMessageGo	db	'interupt set up$'
dbMessageNo	db	'Im here$'
сообщаем о повторе
isStop:		mov	ah,9
		mov	dx,offset dbMessageNo
		int	21h
		xor	ax,ax
		int	16h
		ret
		end	begin

=====
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.
smile

Зенченко Константин Николаевич

Старший модератор

ID: 31795

5

= общий = |  11.12.2009, 22:29 |  цитировать |  профиль |  личное сообщение

Земцов Дмитрий Анатольевич:

		mov si,DX  		
		mov di,offset check_name
		mov cx,9	 	
		repe cmpsb

Этой команде нужны пары регистров ds:si и es:di, на момент вызова обработчика у Вас известно только cs:ip, остальное принадлежит прерваной программе.

Цитата:
(Лысков Игорь Витальевич, у вас в строке кода les di,TestName мне кажеться ошибка, кроме как оператора lea мне больше не чего не вспомнилось)

У Вас есть книга С.В.Зубкова, т.к. Ваша цитата именно из неё, проверьте команду les и ещё lds

=====
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.
smile

Лысков Игорь Витальевич

Мастер-Эксперт

ID: 7438

6

= общий = |  11.12.2009, 23:14 |  цитировать |  профиль |  личное сообщение

Земцов Дмитрий Анатольевич:
Я добавил в ответ подправленную Вашу программу. Внимательно сравните со своей...
Хочу объяснить один момент:
Когда происходит прерывание, то в стек засылаются регистр флагов, сегмент и смещение.
При возврате по iret все восстанавливается, включая регистр флагов. Поэтому установка флага С по STC ничего не дает,
т.е. после возврата из прерывания восстановится старое значение.
Поэтому надо взводить бит в стеке, там, где хранится старое значение регистра флагов.
После iret сохраненное значение попадет в регистр флагов и, ву-аля, CF взведен!

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

Возможность оставлять сообщения в мини-форумах консультаций доступна только после входа в систему.
Воспользуйтесь кнопкой входа вверху страницы, если Вы зарегистрированы или пройдите простую процедуру регистрации на Портале.