ASM: защита удаления файлов

Тема в разделе "WASM.BEGINNERS", создана пользователем Einior, 30 май 2011.

  1. Einior

    Einior New Member

    Публикаций:
    0
    Регистрация:
    30 май 2011
    Сообщения:
    14
    Здравствуйте.
    Есть задание на курсовую - написать резидент, запрещающий удаление файлов определённого расширения. Программа должна быть написана под ДОС, 16-битный COM.
    В принципе, со всем уже разобрался, кроме самого главного - защиты от удаления.
    Нашёл в справочнике функцию 41h прерывания ДОС 21h - удаление файла. В DX - ASCIIZ-строка с именем файла.
    Предположил, что при удалении файла в ДОС (например, командой del e:\test.txt) вызывается именно это прерывание, поэтому решил написать собственный обработчик. Однако обнаружил, что даже в этом случае файлы всё равно удаляются. При этом сам алгоритм, вроде бы, правильный - проверял пошагово в эмулятора emu8086
    Может быть, это делается как-то по-другому?
    На всякий случай, участок кода с обработчиком (он не дописан до конца, в отладке) и с необходимыми переменными прилагаю.

    Код (Text):
    1. extensions  db  'asmbinbatcomdatdocexeinimp3nfoobjtxtsys'
    2. ex_len      =   $ - extensions
    3. new_21h     proc
    4.  
    5.     cmp     AH, 41h             ;функция удаления
    6.     je      work                ;работаем по нашей функции    
    7.     jmp     exit_21h            ;иначе уход в старый обработчик без возврата
    8.    
    9. work:
    10.     push    CS
    11.     pop     DS
    12.    
    13.     push    AX
    14.     push    BX
    15.     push    CX
    16.     push    SI
    17.     push    DI
    18.    
    19.     mov     SI, DX              ;адрес имени удаляемого файла
    20.     search_null:                ;перемещение на конец строки
    21.         mov AL, [SI]
    22.         inc SI
    23.         cmp AL, 0h
    24.     jne search_null
    25.     sub     SI, 2h              ;в SI содержится адрес последнего символа имени файла
    26.     mov     BX, SI              ;копируем SI в BX - понадобится при поиске
    27.    
    28.     mov     AX, offset extensions   ;адрес extensions
    29.     add     AX, ex_len              ;длина
    30.    
    31.     std                             ;флаг DF = 1 - движение назад
    32.     search_string:
    33.         dec     AX                  ;на первой итерации AX и DI содержат адрес последнего символа в extensions
    34.         mov     DI, AX              ;на последующих - продвижение на 1 символ назад
    35.         cmp     DI, offset extensions + 1   ;дошли до второго символа, а совпадений не найдено
    36.         je      delete_file         ;файл можно удалять
    37.         mov     CX, 3h              ;ожидаемая длина расширения
    38.         repe    cmpsb               ;сравниваем содержимое SI - имя файла и DI - блокируемые расширения
    39.         mov     SI, BX              ;возвращаем SI в предыдущее состояние
    40.         cmp     CX, 0h              ;найдено совпадение
    41.         je      found
    42.     jmp     search_string
    43.        
    44. found:
    45.        
    46. not_delete_file:
    47.     cli
    48.    
    49.     pop     DI
    50.     pop     SI
    51.     pop     CX
    52.     pop     BX
    53.     pop     AX
    54.    
    55.     mov     AL, 20h             ;EOI
    56.     out     20h, AL
    57.     iret
    58.    
    59. delete_file:
    60.  
    61.     pop     DI
    62.     pop     SI
    63.     pop     CX
    64.     pop     BX
    65.     pop     AX
    66.  
    67.     mov     AL, 20h             ;EOI
    68.     out     20h, AL
    69.    
    70. exit_21h:
    71.     jmp     DWPTR CS:[old_21h]
    72.    
    73. new_21h     endp
     
  2. Einior

    Einior New Member

    Публикаций:
    0
    Регистрация:
    30 май 2011
    Сообщения:
    14
    В процессе отладки обнаружил вот ещё что.
    При вызове команды del действительно срабатывает прерывание 21h, но не функция 41h, а какая-то другая. В участке кода:

    Код (Text):
    1.     cmp     AH, 41h                ;функция удаления
    2.     je      work                   ;работаем по нашей функции    
    3.     jmp     exit_21h               ;иначе уход в старый обработчик без возврата
    4.    
    5. work:
    6. ...
    Программа идёт не по ветке work, а на ветку exit_21h.
     
  3. skomarov

    skomarov New Member

    Публикаций:
    0
    Регистрация:
    14 май 2008
    Сообщения:
    389
    Einior
    1) Перед началом обработки не происходит сохранение регистра DS, теряется исходное значение.
    2) Команда cmpsb сравнивает значения по указателям DS:[SI] и ES:[DI], но значение сегментного регистра ES не сохраняется и не инициализируется. Значение сегментного регистра DS изменено и не соответствует переданным функции данным, а значит не указывает на переданный путь к файлу.
    3) Команды mov AL, 20h; out 20h, AL используют для завершения аппаратного прерывания. В данном случае они не требуются.
    4) Перед переходом к системному обработчику затирается исходное значение регистра AL.
    5) Тоже самое происходит при выходе из собственного обработчика. При невозможности выполнить операцию системная функция выставляет флаг CF и возвращает код ошибки в регистре AX. Было бы хорошо, также сообщать об отказе удаления файла.
     
  4. skomarov

    skomarov New Member

    Публикаций:
    0
    Регистрация:
    14 май 2008
    Сообщения:
    389
    Einior
    Будет лучше, если разделить задачу на две части. Сначала сделать нерезидентную программу, которая будет проверять имя файла на необходимые условия, затем сделать резидентную часть, которая будет полностью блокировать функцию 41h (AX=5), и только после этих подготовительных этапов объединить эти две части.
     
  5. Einior

    Einior New Member

    Публикаций:
    0
    Регистрация:
    30 май 2011
    Сообщения:
    14
    Хм, по большей части понял все ошибки. Правда, не совсем разобрался с сегментными регистрами. Надеюсь, я правильно их инициализировал и сохранил в новой версии.

    Код (Text):
    1. new_21h     proc
    2.  
    3.     cmp     AH, 41h             ;функция удаления
    4.     je      work                ;работаем по нашей функции    
    5.     jmp     exit_21h            ;иначе уход в старый обработчик без возврата
    6.    
    7. work:
    8.     call    clear
    9.    
    10.     push    AX
    11.     push    BX
    12.     push    CX
    13.     push    DI
    14.     push    SI
    15.     push    DS
    16.     push    ES
    17.    
    18.     push    CS
    19.     pop     ES
    20.    
    21.     mov     SI, DX              ;адрес имени удаляемого файла
    22.     search_null:                ;перемещение на конец строки
    23.         mov AL, [SI]
    24.         inc SI
    25.         cmp AL, 0h
    26.     jne search_null
    27.     sub     SI, 2h              ;в SI содержится адрес последнего символа имени файла
    28.     mov     BX, SI              ;копируем SI в BX - понадобится при поиске
    29.    
    30.     mov     AX, offset CS:extensions    ;адрес extensions
    31.     add     AX, ex_len                  ;длина
    32.    
    33.     std                             ;флаг DF = 1 - движение назад
    34.     search_string:
    35.         dec     AX                  ;на первой итерации AX и DI содержат адрес последнего символа в extensions
    36.         mov     DI, AX              ;на последующих - продвижение на 1 символ назад
    37.         cmp     DI, offset CS:extensions + 1    ;дошли до второго символа, а совпадений не найдено
    38.         je      delete_file         ;файл можно удалять
    39.         mov     CX, 3h              ;ожидаемая длина расширения
    40.         repe    cmpsb               ;сравниваем содержимое SI - имя файла и DI - блокируемые расширения
    41.         mov     SI, BX              ;возвращаем SI в предыдущее состояние
    42.         cmp     CX, 0h              ;найдено совпадение
    43.         je      found
    44.     jmp     search_string
    45.        
    46. found:
    47.        
    48. not_delete_file:
    49.     pop     ES
    50.     pop     DS
    51.     pop     SI
    52.     pop     DI
    53.     pop     CX
    54.     pop     BX
    55.     pop     AX
    56.    
    57.     iret
    58.    
    59. delete_file:
    60.     pop     ES
    61.     pop     DS
    62.     pop     SI
    63.     pop     DI
    64.     pop     CX
    65.     pop     BX
    66.     pop     AX
    67.    
    68. exit_21h:
    69.     jmp     DWPTR CS:[old_21h]
    70.    
    71. new_21h     endp
    И всё равно не работает.
    Кроме того, можно заметить, что сразу после метки вставлен вызов процедуры clear, которая очищает экран. Т.о. очистка должна производится при любом вызове функции 41h. Но этого не происходит. Т.е. программа по ветке work не идёт, о чём я уже писал выше.
    В качестве тестового примера используется файл e:\asm\test.txt
    Программу запускал через cmd, Volkov Commander, FAR (ходят слухи, что через эти файловые менеджеры запускать программы, написанные под ДОС, предпочтительней; почему - не пойму).

    И ещё я совсем не понял, что имеется ввиду здесь:
    При чём здесь AX=5?
     
  6. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    То есть вы все это под виндой таки делаете? а удалять файл как пробуете?

    Поясню: перехваченное прерывание остается перехваченным только пока не закрыто окно консоли... То есть возможно валидной будет проверка "под Volkov Commander'ом установить резидента, и тут же не закрывая VC, средствами VC (а не в проводнике) - попытаться что-нибудь удалить". Вопрос конечно из разряда "а не чайник ли ты", но убедиться надо ;)
     
  7. Einior

    Einior New Member

    Публикаций:
    0
    Регистрация:
    30 май 2011
    Сообщения:
    14
    Да, всё именно так. Например, под cmd запускается
    >e:\asm\asm1.com
    Затем пробуем удалить
    >del e:\asm\test.txt
     
  8. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    не-е, все-таки в Волкове попробуйте. cmd - это НЕ ДОС. И del там вовсе не через int 21h работает. Есть у меня такое предчувствие...
     
  9. Einior

    Einior New Member

    Публикаций:
    0
    Регистрация:
    30 май 2011
    Сообщения:
    14
    Волков пробовал, всё так же - файлы удаляются.
    Но опять же вопрос, может, через него по-другому как-то нужно запускать? У меня Волков версии 4.99.08. Запускаю из винды волковский com и там уже работаю.
     
  10. skomarov

    skomarov New Member

    Публикаций:
    0
    Регистрация:
    14 май 2008
    Сообщения:
    389
    Einior
    Если не получается удалить файл, то обработчик выставляет флаг CF и возвращает код ошибки в AX, среди которых:
    2 - Файл не найден.
    5 - Нет доступа.
    В случае, когда твой обработчик будет блокировать удаление файла, было бы хорошо поступать также, как это делает системный обработчик.

    Перед вызовом прерывания флаги сохраняются в стеке, а после извлекаются командой iret, поэтому надо в стеке изменить значение флага CF, а в регистр AX записать необходимый код ошибки. Посмотри какой возвращает системный обработчик, но по документации - это 5.
    Код (Text):
    1. not_delete_file:
    2.     ...
    3. ; Подготавливаем указатель
    4.     push BP
    5.     push SP
    6.     pop BP
    7.  
    8. ;[bp+0] bp
    9. ;[bp+2] ip
    10. ;[bp+4] cs
    11. ;[bp+6] flags
    12.  
    13. ; Устанавливаем флаг CF
    14.     mov AL, 1
    15.     or [BP+6], AL
    16.  
    17. ; Восстанавливаем регистр BP и устанавливаем код ошибки.
    18.     pop BP
    19.     mov AX, 5
    20.     iret
     
  11. Einior

    Einior New Member

    Публикаций:
    0
    Регистрация:
    30 май 2011
    Сообщения:
    14
    Хорошо, это понял. Но тем не менее, программа не идёт на ветку work, а сразу уходит в старый обработчик. Т.е. при удалении, судя по всему, не отлавливается функция 41h (и 7141h тоже).
     
  12. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    Есть только два нормальных варианта :
    1) запускать волкова из себя, чтобы перехват int 21 работал.
    2) Использовать чистый ДОС - проще всего Dosbox
    --------------------------------------
    Про Волкова:
    Имеет систему управления резидентными программами (вызывается по "Alt+F5") с возможностью удалять резидентные программы (функциональность этой системы довольно мала из-за ущербности DOS).
    Поэтому легко проверить осталась твоя прога в памяти или в Винде все не так как в ДОС.
     
  13. Einior

    Einior New Member

    Публикаций:
    0
    Регистрация:
    30 май 2011
    Сообщения:
    14
    Попробовал сейчас запустить и Волкова из себя же, а из него уже программу, и через Досбокс - результат один, удаляет файл.
    Точнее с досбоксом забавная штука - если удаляемый файл существовал до запуска Досбокс, то файл удаляется. Если же создан уже после запуска, то не удаляется. Но это никак не зависит от загрузки в память програмы.
    Кстати, Alt+F5 в Волкове почему-то не работает.
     
  14. dinoweb

    dinoweb Дмитрий

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    129
    Адрес:
    Россия. Красноярск
    попробуйте в command.com
    cmd - 32 битная командная строка.
    command.com - 16 битная, почти что дос.
    может быть волков тоже перехватывает это прерывание..
     
  15. Einior

    Einior New Member

    Публикаций:
    0
    Регистрация:
    30 май 2011
    Сообщения:
    14
    Нет, command.com тоже не работает.
     
  16. skomarov

    skomarov New Member

    Публикаций:
    0
    Регистрация:
    14 май 2008
    Сообщения:
    389
    Einior
    Может быть неправильно устанавливаешь обработчик и твой код совсем не вызывается?
     
  17. Einior

    Einior New Member

    Публикаций:
    0
    Регистрация:
    30 май 2011
    Сообщения:
    14
    Устанавливается правильно.
    Есть такой участок кода в обработчике

    clear - процедура очистки экрана. Добавлена для отладки.
    Так вот, если её перенести в начало обработчика - она срабатывает.
     
  18. skomarov

    skomarov New Member

    Публикаций:
    0
    Регистрация:
    14 май 2008
    Сообщения:
    389
    Einior
    Если обработчик срабатывает, попробуй отследить какие функции вызываются.
     
  19. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    Раз в Досбоксе работает - значит Волков что-то химичит. А под Волковым экран-то гаснет?
    А не удаляет свежий - наверно кешируется что-то или ты или Волков не освобождаете файл и он не удаляется...
     
  20. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    Я сейчас смутно вспоминаю, что в ДОС есть два класса файловых прерываний : старые и новые. Рой в этом направлении.