В настоящее время вычислительная техника интенсивно развивается, с каждым днем количество пользователей персональных компьютеров неуклонно растет. Но такое развитие информационных технологий приводит к возникновению новых проблем, связанных с защитой информации [1].
Для взлома программ потенциальный злоумышленник чаще всего пользуется двумя средствами:
К сожалению, объем одной статьи не
позволяет рассмотреть методы защиты от обоих
средств, поэтому здесь ограничимся лишь
рассмотрением методов защиты от отладчиков [2].
Эти методы получены автором статьи на основе
анализа системы защиты популярного в недалеком
прошлом текстового редактора W&D, вирусов и
некоторых программных комплексов.
Для защиты от отладчиков используется тот факт, что при своей работе отладчик вносит возмущения в среду выполнения программы, которые почти всегда могут быть зарегистрированы. Рассмотрим некоторые методы защиты от отладчиков.
1. Использование аппаратных особенностей процессора.
1.1. Конвейер. Метод с использованием конвейера не следует использовать по той причине, что на процессорах Pentium и выше он уже не работает.
1.2. Использование того факта, что при выполнении команды изменения значения регистра SS (mov Seg, r/m и pop Seg) происходит потеря одного трассировочного прерывания (только для микропроцессоров 80386+).
2. Выявление изменений операционной среды, вносимых отладчиками.
2.1. Проверка количества свободной памяти, векторов прерываний и т.п.
2.2. Проверка временных характеристик программы позволяет выявлять работу в режиме трассировки и остановки по контрольным точкам. Причем проверять следует не абсолютные временные характеристики, а относительные, т.к. абсолютные временные характеристики сильно зависят от быстродействия процессора.
2.3. Проверка правильности начальных значений в регистрах при запуске программы.
3. Противодействие установке контрольных точек и изменению кода программы.
3.1. Периодический подсчет контрольных сумм различных участков кода программы.
3.2. Чередование команд запрета и разрешения прерываний.
4. Нарушение интерфейса с пользователем приводит к тому, что пользователь не может пронаблюдать за ходом выполнения программы.
4.1. Блокировка клавиатуры. Причем блокировать клавиатуру лучше не командой cli, а следующим кодом:
CS:0100 E421 in al,21h
CS:0102 0C02 or al,00000010b
CS:0104 E621 out 21h,al
или
CS:0100 E461 in al,61
CS:0102 0C80 or al,10000000b
CS:0104 E661 out 61h,al
или
CS:0100 B4AD mov al, 0ADh
CS:0102 E664 out 64h,al
В этом случае следует проверять действительное запрещение аппаратных прерываний. Это можно проверить двумя способами.
4.1.1. Перехватить весь ввод с клавиатуры и анализировать его наличие. Если прерывания действительно запрещены, то ввод будет отсутствовать.
4.1.2. Перехватить содержимое от таймера и анализировать его вызов. При запрещении аппаратных прерываний обработчик таймера вызываться не будет.
4.2. Искажения при выводе на терминал.
5. Использование аппаратуры напрямую (через порты ввода-вывода).
6. Переход на свои подпрограммы система защиты можно осуществлять из обработчиков прерываний (Invalid Opcode, Devide by Zero, int 01h, int 03h и др.). При этом неверный код операнда не должен получаться явно.
7. Использование отладочных прерываний (int 01h и int 03h) для собственных нужд. При запрещении защитным механизмом пошагового режима выполнения программы взломщик может обходить участки перехвата 1го прерывания. Для того, чтобы этого нельзя было сделать модуль защиты должен "поручать" подпрограмме обработки соответствующего прерывания некоторую "полезную" работу. Например, это может быть генерация участков программы, дешифрация и т.п. В этом случае взломщику придется кропотливо изучать работу соответствующей подпрограммы, а это резко увеличивает сроки снятия защиты. Так же причинить неудобства взломщику можно большим количеством вызовов int 3h в цикле (т.к. практически все отладчики используют этот вектор), но это легко обходится заменой int 3h на команду nop. Для избежания таких замен следует периодически проверять CRC. Можно также переустанавливать этот вектор (и int 1h тоже) на вектора завершения программы.
8. Назначение стека программы непосредственно в область испольняемого кода и неоднократная его смена.
9. Контроль размера стека и использования того свойства, что некоторые отладчики используют стек отлаживаемой программы. Можно также использовать метод затирания отладчиком важного кода программы при помещении в стек отладчиком каких-либо значений.
10. Следует обнулять стек после извлечения адреса возврата, т.к. через незатертый стек можно отследить цепочку вызовов подпрограмм.
11. Для перехвата векторов отладчика и избежания контроля отладчиком действительности перехвата можно использовать сплайсинг. Т.к. практически все отладчики используют int 1h и int 3h, то процедура сплайсинга очень сильно усложняется, но позволяет обойти антитрассировочные приемы.
12. Данный метод используется вирусом OneHalf.
call sub_1
. . .
sub_1:
pop bx
push bx
cmp [bx], 0CCh ;проверка точки останова сразу после
команды
;вызова
je _Debug_ ;подпрограммы
ret
Приведенный список методов защиты не
является полным [3], но комбинируя описанные
методы, учитывая общие принципы построения
аналогичных систем, можно построить достаточно
мощную систему защиты.
ЛИТЕРАТУРА
Кафедра вычислительной техники
Смоленский филиал Московского энергетического института
(Технический университет)
Поступила в редакцию 2.07.99.