Учет аппаратных особенностей микропроцессоров Intel 80х86
Данные микропроцессоры содержат внутренний конвейер команд, обеспечивающий повышение производительности. Для I80386 он составляет 16 байт. После очистки (командами JMP, INT, CALL, RET, IRET) конвейер заполняется следующими командами, которые выполняются уже с нового адреса. Но при работе отладчика в режиме трассировки конвейер очищается после каждой команды. Это можно использовать, например, так:
test proc
mov bx,offset xxx ; ds=cs
jmp short clr ;очищаем конвейер
clr: mov byte ptr [bx],0c3h ; код команды ret
xxx:mov ah,9
mov dx,offset msg
int 21h
ret
msg db 'Отладочные средства не используются$'
test endp
Противодействие отладчикам, использующим прерывания 1 и 3
Прерывания int1 и int3 считаются отладочными и работают следующим образом:
- int1 - One Step - вызывает очистку очереди команд (конвейера), загружает очередную команду и выполняет ее;
- int 3 - останавливает работу программы в заданной точке.
Изменив вектора этих прерываний, можно обеспечить переход на свою подпрограмму. Это можно сделать функциями ДОС
; Getintvec - запомнить по адресу ds:0 старый вектор прерывания (язык Турбо-Си)
asm{
mov ax,3503h ; 35 - номер функции, 09 - номер
; прерывания
int 21h
mov ds:[0],bx
mov ds:[2],es
; Setintvec - установка нового вектора на свой обработчик
mov ax,2503h
lea dx,i3 ; i3 - процедура обработки
int 21h
}
После завершения программы необходимо восстановить старый вектор прерывания.
Использование аппаратных прерываний таймера (int 8) и клавиатуры (int 9)
Т.к. отладчик берет эти прерывания на себя, одновременно игнорируя запрет прерываний (cli), то программа защиты, перехватив эти прерывания, может в своем обработчике проверять состояние флага IF. В случае IF=1 можно производить действия по предотвращению отладки.
Использование TF
При трассировке процессор устанавливает флаг TF, и в зависимости от состояния этого флага можно производить какие-либо действия.
Пример (ассемблер):
mov bx,offset xxx
pushf
pop ax
and ax,00010000b
add bx,ax
jmp bx
Опытный хакер, если ему не надоест разбираться с защитой, будет неоднократно прогонять непонятые куски программы отладчиком. Некоторые приемы борьбы с этим уже рассматривались.
Очень эффективное средство от пошагового выполнения программы назначение стека в ее тело. А если там находятся данные для работы, то режим отладки усложняется. К тому же частое изменение местоположения стека, поверьте на слово, измотает хакера окончательно.
Напомним, что при пошаговом режиме хакеру рекомендовалось обходить участки, перехватывающие 1-е прерывание. Так вот, чтобы он не смог воспользоваться этим советом, нужно поручить подпрограмме обработки прерывания некоторую полезную функцию. Например, генерацию кодов или дешифрацию.
Напомним также традиционные методы защиты.
Программа должна подсчитывать и проверять контрольные суммы своих участков для определения "контрольных точек" или "точек останова", расставленных хакером. Дело в том, что стандартное применение 3-го прерывания предусматривает запись кода его вызова вместо байта программы, а это меняет контрольную сумму. Периодическая же проверка вовремя проинформирует программу о замене "родных" байт "чужими", то есть о попытке исследования программы под отладчиком.
Известно, что выполнение программы в режиме трассировки значительно уменьшает ее быстродействие. Поэтому по времени "прохода" отдельных кусков защищаемого ПО можно определить работу под отладчиком. По таймеру (например, запустив его 2-й канал) заранее просчитывают скорость выполнения некоторого участка и сравнивают его со значением, полученным в ходе работы программы. Если есть существенное расхождение в полученных результатах, то можно сделать вывод о выполнении данного участка под контролем. Из недостатков метода отметим лишь разное быстродействие процессоров на разных ПЭВМ, которое следует учитывать.
Интересный способ выматывания "исследователя" - применение достаточно больших процедур, производящих некоторую сложную и, на первый взгляд, важную работу, но на самом деле, не имеющих никакого отношения к логике работы программы, так называемых "пустышек". Для лучшей имитации их важности можно включать в них перехват 13h, 21h, 25h и 26h прерываний (обслуживающих ввод-вывод информации на внешние устройства), что, безусловно, заинтересует хакера.
Оригинальный способ защиты ПО от исследования, примененный в пакете COPYLOCK, использует конвейер шины данных микропроцессора. На рис. 4.2 изображен его фрагмент. (Надеемся, что не навлечем на себя гнев цивилизованных пользователей, афишируя некоторые тонкости программы: все равно она безнадежно устарела, да и не вскрыта лишь самыми ленивыми. А начинающим специалистам рекомендуем ознакомиться с ее работой. Полный листинг опубликован в электронном журнале "НСК", N1, 1992 г.). Фрагмент дан со значением смещений относительно кодового сегмента, чтобы читатель смог увидеть, как команда REP STOSW в подпрограмме SUBR затирает значением из регистра AX область ОЗУ, в которой находится и сама подпрограмма. Тем не менее, SUBR нормально отрабатывает и возвращает управление в точку вызова (но только не в пошаговом режиме).