Автозащита Guardant. Часть вторая

И снова здравствуйте! Во второй части моего блока статей я расскажу об опции RIP_CODE. А точнее о том, как зарождалось решение сделать так, а не иначе. Ведь это, на мой взгляд, гораздо интереснее. Не правда ли?

Итак. В далеком 2008-м году возникла суровая необходимость делать рефакторинг автозащиты. Дело в том, что ее защитные механизмы на тот момент сильно устарели. Фактически, весь антидампинг держался тогда на защите импортов. И этого было просто катастрофически мало!

Конечно, в какой-то момент в сети появилась утилита, которая умела снимать наш конверт автоматически. Дыру эту мы заткнули достаточно быстро, в течение одной-двух недель и утилита не могла больше снять новую автозащиту, хотя достаточно лихо управлялась более чем с двумя сотнями конвертов. Тем не менее, возникновение такой ситуации было нам предупреждением — необходимо в срочном порядке производить усиление защитных механизмов.

Первым делом мы еще более усилили защиту импортов (об опции IMPORT_HOOK я рассказывал в предыдущей статье). Далее, перед нами встал вопрос, а что же делать дальше? Можно было двигаться в сторону обнаружения отладчиков на основе различного рода системозависимых механизмов. Так делали многие в свое время. И почти все от такого подхода отказались, т. к. это ведет к потере совместимости.

У нас есть два готовых решения:

  • Псевдокод Виртуальная машина Guardant, позволяющая выполнять код некоторого виртуального процессора на встроенном в программу интерпретаторе;
  • Генератор полиморфного кода Средство, осуществляющее запутывание машинного кода или, как это называют в науке, обфускацию, с целью максимального затруднения анализа этого кода.

Эти решения используются для защиты драйверов, объектных файлов и утилит Guardant. Возникает резонный вопрос, а почему бы не использовать псевдокод или обфускатор для защиты кода самой программы? Наверняка это повысило бы защищенность. И можно спать спокойно! Однако давайте рассмотрим поподробнее целесообразность использования такого решения в текущей архитектуре автозащиты.

Во-первых, такая серьезная модификация кода, как виртуализация или обфускация серьезно замедляет работу защищенных ими фрагментов программы. Коэффициент замедления начинается от 2-х порядков! Естественно, что здесь нельзя выбирать защищаемый код просто так. Необходимо предварительно профилировать защищаемое приложение для выделения блоков кода, которые можно защищать тем или иным способом.

Можно в принципе дать пользователю выбирать такие блоки кода самостоятельно. Однако и первый, и второй подходы повлекли бы к перекраиванию архитектуры не только самой утилиты автозащиты, но и к соответствующим изменениям в других утилитах, таких, как, например, мастер автозащиты. На все это у нас не было времени. Необходимо было решить задачу усиления защиты в достаточно сжатые сроки. В планируемые доработки входила, кстати сказать, поддержка Time и Sign ключей, улучшение системы лицензирования и ряд других «мелочей».

Во-вторых, «прикручивание» таких вещей, как псевдокод или полиморфный движок к автозащите в ее текущей архитектуре не столь высоко повышает защищенность, как хотелось бы думать! Дело в том, что для обеспечения хорошей защищенности, необходимо «привязать» эти решения к электронному ключу.

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

В результате было принято решение создать так называемую «мини виртуальную машину», которая обрабатывала бы достаточно ограниченный набор инструкций, работала быстро, обеспечивала бы неплохую защищенность посредством контроля других защитных механизмов, что и было сделано. Так родилась опция RIP_CODE.

Таким образом, удалось добиться увеличения защищенности при минимальных накладных расходах. Клиенты получили это решение в сжатые сроки. Мы уложились. Данное решение можно считать временным, однако оно позволило нам выиграть время для создания утилиты автозащиты нового поколения, которая, надеюсь, выйдет уже скоро.