Неявный самоконтроль как средство создания не ломаемых защит [Крис Касперски] (pdf) читать постранично, страница - 2

Книга в формате pdf! Изображения и текст могут не отображаться!


 [Настройки текста]  [Cбросить фильтры]

на
кладно, да и фантазии у разработчика не хватит и хакер, обнаружив и проанализи
ровав пару – тройку защитных функций, настолько проникнется "духом" и ходом
мысли разработчика, что все остальные найдет без труда.
Между тем существует и другая возможность – неявная проверка целостно
сти своего кода. Рассмотрим следующий алгоритм защиты: пусть у нас имеется за
шифрованная (а еще лучше упакованная) программа. Мы, предварительно скопи
ровав ее в стековый буфер, расшифровываем (распаковываем) ее и… используем
освободившийся буфер под локальные переменные защищенной программы.
С точки зрения хакера, анализирующего дизассемблерный код, равно как

О

Крис Касперски

3

Неявный самоконтроль как средство создания не ломаемых защит
и гуляющего по защите отладчиком, все выглядит типично и "законно". Обнару
жив защитный механизм (пусть для определенности это будет тривиальная па
рольная проверка), хакер правит соответствующий условный переход и с удовле
творением убеждается, что защита больше не ругается и программа работает.
Как будто бы работает! – через некоторое время выясняется, что после взлома ра
бота программы стала неустойчивой, – то она неожиданно виснет, то делает из чи
сел "винегрет", то… Почесав репу, хакер озадаченно думает: а как это вообще ло
мать? На что ставить точки останова? Ведь не анализировать же весь код целиком!
Весь фокус в том, что некоторые из ячеек буфера, ранее занятого зашифро
ванной (упакованной) программой при передаче их локальным переменным не
были проинициализированы! Точнее, они были проинициализированы теми зна
чениями, что находились в соответствующих ячейках оригинальной программы.
Как нетрудно догадаться, именно эти ячейки и хранили критичный к изменениям
защитный код, а потому и неявно контролируемый нашей программой. Теперь
я готов объяснить зачем вся эта котовасия с шифровкой (упаковкой) нам вообще
понадобилась: если бы мы просто скопировали часть кода программы в буфер,
а затем "наложили" на него наши локальные переменные, то хакер сразу бы заин
тересовался происходящим и, бормоча под нос "чтото здесь не так", вышел бы
непосредственно на след защиты. Расшифровка нам понадобилась лишь для усы
пления бдительности хакера. Вот он видит, что код программы копируется в бу
фер. Спрашивает себя "а зачем?" и сам же себе отвечает: "для расшифровки!".
Затем, дождавшись освобождения буфера с последующим затиранием его содер
жимого локальными переменными, хакер (даже проницательный!) теряет к этому
буферу всякий интерес. Далее – если хакер поставит контрольную точку останова
на модифицированный им защитный код, то он вообще не обнаружит к ней обра
щения, т. к. защита контролирует именно зашифрованный (упакованный) код,
содержащийся в нашем буфере. Даже если хакер поставит точку останова на
буфер, он быстро выяснит, что: а) ни до, ни в процессе, ни после расшифровки
(распаковки) программы содержимое модифицированных им ячеек не контроли
руется (что подтверждает анализ кода расшифровщика/распаковщика – проверок
целостности там действительно нет); б) обращение к точке останова происходит
лишь тогда, когда буфер затерт локальными переменными и (по идее!) содержит
другие данные.
Правда, ушлый хакер может обратить внимание, что после "затирания" зна
чение этих ячеек осталось неизменным. Совпадение? Проанализировав код, он
сможет убедиться, что они вообще не были инициализированы и тогда защита па
дет! Однако, мы можем усилить свои позиции: достаточно лишь добиться, чтобы
контролируемые байты попали в "дырки", образующиеся при выравнивании струк
туры (этим мы отвечает хакеру на вопрос: а чего это они не инициализированы?),
а затем скопировать эту структуру целиком (вместе с контролируемыми "дырка
ми"!) в десятокдругой буферов, живописно разбросанных по всей программе.
Следить за всеми окажется не такто просто: вопервых, не хватит контрольных то
чек, а, вовторых, это просто не придет в голову.

Крис Касперски

4

Неявный самоконтроль как средство создания не ломаемых защит

Рисунок 1.

Практическая реализация
равила хорошего тона обязывают нас проектировать защитные меха
низмы так, чтобы они никогда, ни при каких обстоятельствах не могли
нанести какой бы то ни было вред легальному пользователю. Даже если вам очень
очень хочется наказать хакера, ломающего вашу программу, форматировать диск
в случае обнаружения модификации защитного кода, категорически недопустимо!
Вопервых, это просто незаконно и попадает под статью о умышленном создании
деструктивных программ, а вовторых… задумайтесь, что произойдет, если искаже
ние файла произойдет в результате действий вируса или некоторого сбоя? Если вы
не хотите, чтобы пострадали невинные, вам придется отказаться от всех форм вре
да, в том числе и