You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 8 Next »

Общая информация

Существует множество технологий, обеспечивающих защиту данных программы. Некоторые технологии используют шифрование, а другие технологии основаны на других принципах. Защищенность, как правило, достигается комплексом мер, т.е. комбинированием технологий защиты.

Для нативных программ

Конверт

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

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

Защита функций

Для защиты конкретных функций программы используются нескольких техник одновременно. Все они основаны на преобразовании кода функции тем или иным способом.

Виртуализация кода

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

Естественно, технология виртуализация требует дополнительных вычислений, что дает заметный оверхед (деградацию производительности) во время выполнения виртуализованного кода, по сравнению с машинным кодом. По этой причине применять виртуализацию рекомендуется не повсеместно, а лишь к отдельным функциям.

Мутация кода

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

Как правило, для этого в код программы добавляется заведомая избыточность (в плане объема исполняемого кода), что негативно сказывается на скорости исполнения защищаемых функций.

Извлечение кода

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

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

Для программ .NET

Программы (сборки) .NET имеют некоторые особенности, по сравнению с нативными программами. Это связано с тем, что для выполнения кода используется среда .NET, использующая промежуточное представление в виде байт-кода на языке CIL (MSIL). В конечном итоге, байт-код интерпретируется на виртуальной машине .NET, которая преобразует байт-код в машинный код и выполняет его. Оказывается, что в файле программы .NET содержатся данные, аналогов которым нет в файле нативной программы.

Обфускация символов

Обфускация символов (символьная обфускация, лексическая обфускация, переименование символов) состоит в переименовании символов, определенных в файле программы .NET, в соответствии с определенной схемой. Суть этой техники состоит в том, чтобы символы программы - классы (типы), методы и их параметры, поля, свойства, события и т.д. - получили вместо значащих имен трудночитаемые или неосмысленные имена. Обычно используются непечатаемые символы (часто диакритические знаки), однобуквенные имена или имена, представляющие собой значения контрольной суммы в закодированном виде.

Обфускация символов, в отличие от остальных техник защиты, не требует наличия ключа Guardant для работы защищенного приложения.

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

Если в защищаемой программе используется Reflection API, то работоспособность программы может быть нарушена. Это связано с тем, что имена символов изменяются в процессе защиты. В таких случаях следует исключить из символьной обфускации соответствующие символы.

Результат обфускации символов:

Необходимо принимать во внимание тот факт, что разные символы программы имеют различные уровни доступа. Так, некоторые символы - внешние интерфейсы (внешние символы) - должны оставаться видимыми извне файла программы (особенно это касается библиотек), в то время как остальные символы должны быть инкапсулированы и недоступны извне.

Обфускация потока управления

Поток управления программы представляет собой последовательность переходов между инструкциями, объединенными в блоки кода. Переходы между блоками кода осуществляются с помощью инструкций if-else, циклов, switch, вызовов функций. Обфускация потока управления заключается в разбиении блоков на более мелкие (вплоть до отдельных инструкций), перемешивании блоков, добавлении лишних блоков и скрытии порядка их выполнения (с помощью динамических переходов goto) и шифрования вспомогательного значения, идентифицирующего следующий блок кода, с использованием ключа Guardant.

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

Результат обфускации потока управления:

Шифрование строк

Строковые константы, хранящиеся в файле программы, могут содержать информацию, которая также подлежит защите. Например, в файле программы могут содержаться в текстовом виде API-ключи. Также некоторые строки могут дать подсказку потенциальному злоумышленнику насчет логики программы и облегчить поиск определенных фрагментов кода. Чтобы избежать раскрытия этих данных потенциальным злоумышленником, строки шифруются с использованием ключа Guardant.

Шифрование строк связано с замедлением работы программы, поэтому необходимо соблюсти компромисс между защищенностью и быстродействием программы. В программах, активно использующих фиксированные строки, например для формирования или парсинга данных в форматах JSON и XML, имеет смысл исключить из шифрования строк определенные классы, методы или поля.

Результат шифрования строк:

Защита методов

Во многом защита методов в программах .NET схожа с защитой функций в нативных программах. Код метода точно так же представим в виде массива байт, может быть извлечен из файла программы .NET и перемещен в библиотеку защиты, предварительно будучи зашифрованным с использованием ключа Guardant.

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

  • No labels