Содержание статьи
Сегодня я предлагаю познакомиться с некоторыми непростыми видами защитных механизмов, их описанием, примерами реализации и оценкой. И начнем мы с самых простых реализаций, которые ломаются в один заход и один байтом, а закончим хардкорными сооружениями в стиле StarForce Protection System, над взломом которых надо много думать. Итак, поехали!
Классика
Самое удивительное (и к некоторому сожалению — разочаровывающее), что довольно много программистов предпочитают идти по пути наименьшего сопротивления и меньших затрат! Наивно полагать, что если механизм защиты в программе состоит из примерно таких программных строк:
if Enter_User_key = Real_Programm_Key then
Call Registration_Success (Enter_User_key)
else
MessageBox.Show ("Wrong KEY!")
end if
то можно на 100% рассчитывать, что абсолютно все пользователи добросовестно и бескорыстно будут покупать у Вас активационный ключ. Это очевидная глупость, но есть много shareware-приложений с подобным кодом и они продолжают выходить из под программистского пера! Отличительной чертой такой простой реализации собственно и является упомянутое выше выделенное условие и отсутствие каких-либо других «защитных стенок».
В качестве примера возьмем уже затертый до дыр Total Video Converter 3.12. Как показано на рисунке, сначала идет проверка самого ключа (дикое количество CMP, JMP и остаток всей функции выше), затем (после того как бедный ключ прошел проверку), вызывается функция для успешной регистрации (onOk). Очевидно, что так как все неправильные ключи ведут в API MessageBoxA, то первое, что приходит в голову (но можно сделать и по другому — как тебе нравится) — поставить в начало MessageBox (по адресу 42151С) безусловный переход на функцию успешной регистрации (JMP 421508). Все! Регистрация проходит без участия разработчиков и самым быстрым способом :).
Ах, да! При каждом запуске будет вылезать окошко с требованием ввести ключ и каждый раз он все-таки будет восприниматься, но ведь мы хотим чтоб все было стопроцентно зарегистрировано! В таком случае, либо купи софт у разработчика (ведь, по сути, ломать программы нехорошо, а я только указал на плохую реализацию защиты), либо напиши свой генератор ключей (а как он генерируется — видно из программы!). Еще один способ сводится к патчингу очередного перехода защиты, который просто сохраняет введенный ключ в реестре, а затем в самом начале, после его извлечения, сравнивает. Какие можно сделать выводы? Главный плюс — чрезвычайно простая реализация, которую может исполнить любой начинающий программист! И в тоже время значительно более громадный минус — такой защитный механизм (если это еще можно назвать защитным механизмом!) может сломать абсолютно любой начинающий хакер! Поэтому в скором времени оказывается, «Trial» эта программа или «Free» — разницы нет. Стоит ли при такой тривиальной реализации защитного модуля говорить о больших прибылях от продаж программы? Очевидно, нет.
Когда разработчики хорошо думают…
Самое главное — думают они сами, что и является критерием среднестатистической защиты. Вот основные «защитные стены» и «рвы», которые они воздвигают против злостных хакеров:
- средний размер защитного механизма (некоторые элементы антиотладки, неявные вызовы функций, множественные вызовы функций в теле защитного механизма) и его клоны в разных частях программы;
- вызов проверки (Trial-времени, сверки ключа) более одного раза и из разных частей программы;
- переплетение защитного механизма с рабочей частью программы;
- замусоривание защитного механизма для усложнения исследования; как вариант: использование подложных (фейковых) защитных функций.
Возможно, что программисты решат упаковать исполняемый файл для уменьшения его размера. Чаще всего в этой роли выступает UPX. Так же стоит отметить, что кроме основного исполняемого файла, зона ответственности защитного механизма может распространяться и на dll’ки самой программы.
Здесь придется затратить больше времени, чем с программной, описанной выше. И придется немного поработать головой так же хорошо, как и разработчикам. Впрочем, и удовольствия от снятой защиты будет гораздо больше. Ярким примером среднего уровня сложности взлома является HDTunePro 3.50. Тут программеры не промах: окошко и функция инициализации жестких дисков оказывается неразлучными друзьями, да и заподлянок немного наставили в стиле — первично пропатченая нами прога будет работать ровно 1 минуту. Также учли, что после 15 дней триал-периода даже повторная переустановка софта не прибавит халявных дней пользования. Мы понимаем, что придется пропатчить полдесятка условных переходов (точнее перед первым переходом в цикле с постусловием заменить число 12 на число, большее чем 16, нам ведь не нужен наг?!; второй инвертируется, где расположена проверка на прошедшую минуту, по сути там кусок основного защитного механизма.
Остальные фишки по мелочи — например, оказалось, что прога вполне работоспособна и без обращений к реестру) и зарегистрировать программу можно банальным обнулением регистра EAX (потому, что 15-0=15). Все! Мы опять зарегистрировали программу без помощи разработчиков! Сюда можно также отнести софтину world-famous CnC3:
Tiberium Wars от Electronic Arts (игрушка требует диск).
Повинуясь традициям, идем в папку с игрой и грузим первый попавшийся exe-файл, который мирно покоитсяв в корне папки с игрой. Убеждаемся, что упаковщиков нет! А вот при запуске в Оле мы получаем сообщение, что какой-то там Secure Mode Failed (по-русски, софт просит выгрузить отладчик!). Но самое интересное: даже если просто запустить Олю и стартануть игру без нее, сообщение вылезет вновь! Вот это да! Выходит, ребята из Electronic Arts считают, что всякий просто запущенный в системе дебаггер (независимо, что мы там отлаживаем или только собираемся отлаживать) может развязать Четвертую тибериумную войну и поэтому должен быть немедленно выгружен! Впрочем, после окончания исследования cnc3.exe мы понимаем, что после GetDriveTypeA, не может быть инструкции CMP EAX, 5, потому что EAX после этой API будет превращен в ноль или единицу.
Антиотладчного механизма в программе в упор не видно.
Создается впечатление, что нас разводят. А где настоящий защитный механизм? Смотрим в диспетчере задач, а там «висит» cnc3game.dat. Теперь понятно, почему игра палит любой запущенный в системе дебаггер! Дочерний процесс (судя по всему) не знает, какой процесс будет (или уже отлаживается) в дебаггере, поэтому у него есть только догадки, что отлаживаемый процесс — cnc3.exe!
Ну а дальше Четвертая тибериумная война будет остановлена или продолжена уже в самом cnc3game.dat (который находится в папке с игрой\RetailExe\[версия игры]\ cnc3game.dat)… Ах, да! Наш дебаггер палится через IsDebuggerPresent и флаг трассировки (впрочем, последнее неактуально). Единственная программа, которую я видел на данный момент и которая (подчеркиваю: на первый взгляд!) максимально укладывается в рамки идеального защитного механизма средней степени — BlueSoleil от IVT Corporation.
Из основных особенностей стоит отметить:
- создание в общей сложности 12(!) потоков при работе (ребята не понаслышке знают о многопроцессорных системах). Неплохо! Попробуй-ка разберись в каком потоке (или даже потоках) плывет защитный механизм.
- использование API LoadString для загрузки строковых сообщений, неплохо усложнит нам навигацию — теперь сразу выйти на нужное место защитного механизма не получится, открытые строки будут только после LoadString со своим персональным идентификатором в стеке. Большой плюс в защите!
- присутствие IsDebuggerPresent и OutpudDebugString. Может антиотладка и есть, но какого нибудь движения в свою сторону я не обнаружил. Ну и ладно! Я не мешаю ей, она — мне.
- за вывод информации о пятимегабайтном лимите и Evaluation версии в разных частях программы (иконка, окно About),а также регистрацию лицензионного ключа отвечают разные функции… И это очень правильно!
Но при углубленном исследовании мой зоркий глаз заметил, что все связанное с регистрацией и Evaluation версией экспортируется из BsSDK.dll (отмечу, что по имени функции можно прочитать, что она делает. Это касается и защитного механизма, что сразу бросится в глаза), в которой все функции, отвечающие за вывод сообщений об Evaluation версии и пятимегабайтном лимите, имеют под собой основу в одну единственную общую ключевую функцию, которая, в зарегистрированной версии, должна возвратить в регистре EAX бублик! Правда еще надо будет «подправить» переход, когда вводится ключ и ловится он на MessageBoxA. Ну, а под занавес хотел добавить, что просто так выгрузить процессы программы не получится — произойдет необработанное исключение в специально установленном драйвере программы. Как результат — после завершенного процесса считаем белые буквы на синем фоне :).
Как видно, защитные механизмы среднего типа, при должном приложении сил защищают неплохо, хотя при наличии опыта и головы все равно будут сняты. Но ведь не за десять же секунд как в TVC! Плюс такого подхода: даже при тесном переплетении и довольно нелегкой реализации будет минимальная глючность, ведь сами разработчики программы учтут все тонкости ее работы. Минус: агрессивных методик противодействия взломщику нет. Ничто не мешает по перекрестным ссылкам добраться до защитного механизма (неприменимо к BlueSoleil), а дальше — дело чисто техническое.
Когда разработчики предпочитают думать чужой головой…
Здесь имеется ввиду приобретение и установка на программный продукт готовых программных и аппаратных реализаций защиты. Весьма условно сложные типы (в данном контексте будем называть их так) защитных механизмов можно разделить на протекторы (например, ASProtect) и программноаппаратные защитные комплексы. Последние делятся собственно на программные и аппаратные. Если смотреть на все это дело трезво, то все это выглядит как Большой черный замок, висящий на картонной двери дома, в котором сидит радостный разработчик и свято верует в создателей замка, а также думает, что он на 100% защищен от всех и вся, забыв к тому же закрыть окна. В конце концов, если эту дверь вместе с домом не завалит тяжелый замок, то хакеры ее гарантированно снесут или же найдут обходной путь. Надеюсь, основная мысль понятна. Теперь перенесу теорию на практику и применю ее к протекторам. Фундаментальная задача этого программного творения — не допустить просмотра и патчинга дизассемблированного листинга защищаемой программы. Обеспечивается все это антиотладочной защитой и многослойным шифрованием, а последний рубеж — помехи в работоспособности снятого дампа (например, подлянки в стиле кражи байт с OEP).
В качестве примера берем ResourceBuilder.
Исполняемый файл и две дочерних dll’ки защищены ASProtect. Посмотри на приведенный рисунок и попробуй ответить на вопрос — обязательно ли нужно для регистрации программы бегать по всему образу в поисках OEP, снимать дамп и возиться с ним?
С защитными комплексами больше интимной лирики по отношению к твоим мозгам.
Большими защитными комплексами занимаются большие компании (коих, кстати, немало), они день и ночь занимаются тем, что придумывают новые гадости для хакеров, дабы максимально обезопасить защищаемое приложение. Очень часто результат их дум получается с противоположным знаком.
Если территория «боевых действий» протектора в основном не выходит за целевой образ защищаемого исполняемого файла, то создатели защитных комплексов предпочитают распространять свои правила на всю систему, не поинтересовавшись при этом ничьим мнением и не спросив твоего разрешения. С одной стороны их продукты частично дают хороший результат в защите, но по поводу обратной стороны медали тут хранят молчание! Где ты видел, к примеру, чтоб в рекламе StarForce внизу маленькими буквами говорилось (хотя бы так): наш продукт имеет ошибки, поэтому стабильность в работе не гарантируется? Также не обижайся, что несколько упадет производительность. В мануале данной защиты этот аспект отражен вообще как анекдот: чтобы убедиться в отсутствии потери производительности, необходимо просто протестировать скорость Вашего жесткого диска до установки драйвера и после («выкрутились», называется).
Поэтому и получается, что синий экран, постоянно вылетающий у Славы — проблемы самого Славика, а не программистов из компании StarForce, ну и тем более это не проблемы МелкоСофта. А то Славик взял у друга новую игрушку, дык мало, что игрушка сама с тонной багов (кстати, на одном баге можно выехать при снятии дампа), тут еще проблемы самой защиты. Да и вообще Славик взял игрушку, а все что взял, рано или поздно надо отдавать, а поиграть хочется! Поэтому приходится Славику сначала брать SoftIce, но чтоб запхнуть защиту в холодильник, придется обработать ее драйвер йодом (в смысле Идой) :).
Вобщем, хорошего очень и очень мало, поэтому получается, что сами разработчики защитного комплекса частично вынуждают пользователя объявить защите бойкот и взяться за дебаггер!
Даже если бы Славик спросил, не могли бы программисты этой самой игры написать свой защитный механизм (как у Electronic Arts) — последовал бы ответ в стиле: нам еще надо движок самой игры отладить и смоделировать нового суперпупермонстра в 3ds Studio Max! А успеть до даты релиза ой, как хочется. Блин! Пристают тут всякие, мешают работать, о какой дате релиза может идти речь… К слову, таких программистов понять отчасти можно, самое главное — сделать игрушку конфеткой. Так что использование коробочных решений в чем-то оправдано.
В отладочном микроскопе такие защиты как StarForce представляются громадными и неповоротливыми осьминогами, раскинувшими свои щупальца по системным библиотекам, некоторым файлам игры ну и, возможно, часть щупалец лежит на нулевом кольце системы (а вы что хотели? надо же беззаботного пользователя баловать синими экранами). Невооруженным глазом мы лишь видим, как процессорные мощности считают какую-то геометрию диска — лучше было бы, если эти самые мощности в данный момент обрабатывали данные самой защищаемой программы. Сплошная деоптимизация!
Самое худшее, что есть еще более страшные вещи: У меня более пяти раз «падал» том жесткого диска! Исходя из этого, лишь подтверждаю утверждение Криса Касперски — не устанавливай ничего недокументированного или плохо документированного. В большинстве случаев это не даст ничего хорошего и полезного! Ты же видишь, что защита устанавливает какой-то специальный драйвер, но не знаешь точно, как этот драйвер куролесит в операционной системе. Особенно это заметно, когда appdrvrem.exe в IdaPro и видишь зашифрованный ассемблерный код. SafeDisk в этом отношении намного более «благороден» к хакерам. Если создатели StarForce ждут, пока реверсера стошнит от бесконечного мусорного кода, то некоторое исключение составляет SafeDisk 4.x с его «лягушкой» (свои люди поймут), одна из функций которой — возвратить 42h при активной отладке приложения и 41h — если отладчика нет. Диковинка подхода к реализации защиты — один из важных козырей ее разработчика. Важно сохранить этот аспект и в новых версиях защиты!
Подведем итог. Специальные комплексы (коробочные решения) защит по своей сути средства действительно мощные и сложносочиненные. Но есть несколько неприятных обстоятельств.
- при такой сложности они тащат за собой вагон багов, проблем и иногда даже серьезных уязвимостей;
- очень мало пользователей, которым нравится вставлять/вынимать каждый раз диск и вообще иметь хоть какое-то дело с графической частью защиты;
- серьезно страдает производительность и стабильность системы в целом;
- если сломали одну версию такой защиты, то паровоз поедет и дальше! Под этим понимаются две основных проблемы новых версий сложных защитных комплексов: отсутствие чего-то фундаментально нового для защиты и излишняя ненужная сложность, которая не несет в себе полезных качеств. В StarForce единственное громадное изменение — это количество «мусора», его становится больше (казалось, куда еще, видимо словосочетание «в разумных пределах» вообще никак не применимо к разработчикам), незначительно мутируют (видоизменяются) ключевые функции защиты и добавляется пара новых бяк, которые легко обнаружить (например, в последней версии protect.dll — «охота» на OllyDbg).
Отсюда мораль: разработчикам абсолютно лень переделывать все заново (или хотя бы большую часть) и в каждой новой версии ее внутренности меняются незначительно.
Ведь даже если в последних версиях protect.dll море мусора, мы ведь знаем что ищем, если до того терзали более старые версии, где мусора намного меньше.
Описание: Звездное командование имеет свою собственную KeBugCheckEx, которая призвана остановить любопытных хакеров при исследовании защиты.
И это далеко не все…
Как видите, дорогие читатели (особенно программисты), идеальных защитных механизмов не существует! Факт! Или разработчики уделили внимание одним аспектам, но оставили без внимания другие немаловажные или вообще не уделили никакого внимания к защите своего детища. Лично мой выбор — это средний тип защитного механизма. Сравнивая его с двумя остальными, получим следующую картину: защитный механизм, длина которого во много раз более чем один условный переход по праву может называться защитным механизмом. Для хорошей реализации понадобится много времени, но сломать его сразу в один байт уже не получится. Протектор — настоящая русская рулетка! Никогда не будет 100% уверенности, что на всех компьютерах защищаемое приложение будет работать корректно или вообще работать хоть както. Программно-аппаратные защитные комплексы — крайне опасный перегиб палки. За свой век они уже успели найти достаточно противников и их интеграция в свой продукт не приветствуется. Наконец самый весомый аргумент: все коробочные решения давно уже взломаны и в интернете предостаточно статей, которыми могут руководствоваться даже начинающие хакеры. Поэтому, если взялись за это дело, не упустите все аспекты, упомянутые в статье. Рекомендую самим взяться за отладчик и взломать свою же защиту, затем при необходимости ее доработать.
Под конец подумай — реально ли требуется защищать твое приложение на данном этапе? Нехитрая формула показывает, за какое время может быть сломлена Ваша защита:
[Время затраченное на взлом защиты] = [Уровень защищенности и стойкость самой защиты] * [Новизна используемых методов] / [Уровень взломщика(начинающий, продвинутый, гуру)] * [Распространенность Вашей программы]) * [Количество взломщиков]
Средний тип защиты — это Ваша креативность и гарантия работы программы у конечного пользователя. Ведь если я знаю все тонкости своей программы и она работает без глюков (хотя насчет Tiberium Wars с его недружелюбностью к запущенному дебаггеру надо помнить, Четвертая тибериумная война — не шутки), что мне помешает посидеть еще пару часов и грамотно раскидать защитный модуль?
В итоге остаются довольны все: разработчик (в получении большей части заветной прибыли), конечный пользователь (в дружелюбности защиты по отношению к нему), ну и, в конце концов — хакеры…