Обфускация – есть такое слово - Подготовка проекта к обфускации

ОГЛАВЛЕНИЕ

 

Рекомендации по подготовке проекта(продукта) к обфускации:


  1. Для усложнения дизассемблирования вы можете использовать подмену типов (которую не всегда возможно реализовать из-за sealed типов) Имеется ввиду такой приемчик – некий системный тип SomeType наследуется в новом типе AnotherType, который подходит для O! (скажем, он лежит в пределах видимости вашей сборки, его можно назначить как internal) и вы его спокойно обфусцируете. На выходе мы получаем испоьзование SomeNamespace.0 вместо известного System.SomeType. Конечно можно установить что AnotherType – это простой наследник от SomeType, но на это уйдет время, не так ли? А нам и нужно тратить время злоумышленника покусившегося на ваш код.

  2. Если вы планируете использовать некоторые типы как публичные но хотели бы их максимально защитить, стоит их поместить "защитную скорлупу" наследования. Некий тип public SomeType можно превратить в два класса : internal _SomeType (underground class), который несет всю реализацию класса, кроме публичных свойств, необходимых для сериализации и для использования во внешнем для сборки коде, и public SomeType, который будет наследоваться от _ SomeType (front class), но нести внешнюю нагрузку – иметь публичные свойства, необходимые для сериализации, конверсии, использования во внешнем для сборки коде. Таким образом у вас будет еще возможность воспользоваться приемчиком 1. для порождения класса SomeType- подобных типов но наследуемых от SomeType.

  3. Внимательнее с атрибутами. Не стоит забывать об использовании атрибутов в вашем коде. Многие из них достаточно тесно помогают взаимодействовать среде .Net с вашими классами. Например атрибут TypeConverterAttribute – им вы привязываете к вашему классу класс конвертера SomeConverter. Не каждый обфускатор «знает» об этом – и поэтому стоит уберечь класс конвертера от обфускации или проверить как обфускатор работает с атрибутами. Иначе связь, установленная между двумя классами посредством атрибута может быть разрушена.

  4. Если ваш класс идет под нож обфускации, стоит также задуматься о механизме его сериализации. Скажем класс- наследник Form сериализует себя таким образом что если обфускатор изменил имя его типа SomeForm на 0, то возникнет проблема при инициализации десериализации такого класса – он просто не сможет найти ресурс 0.resources, так как сериализовался в в SomeForm.resources.

  5. Используйте static string обьявления вместо const string – это затруднит поиск инициализации этого поля (в метаданных оба обьявления будут представлены как поля).

  6. Если вы имеете список строк, которые у вас представлены как список строковых констант, лучше список строк обьявите/ опишите как строковый массив, а в константах храните индекс к необходимой строке в строковом массиве.

  7. Если вы хотите защитить некий алгоритм от лишнего просмотра – отдайте его выполнение нескольким классам, этим вы распределите задачу, может быть разгрузите память, но безусловно затрудните задачу исследователя понять, что у вас тут происходит.

  8. Пользуйтесь такими фичами как nested types, это не повлияет на производительность, но повлияет на «трудноизучаемость» вашего кода.

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

  10. Инициализируйте класс формы без использования .resx и .resources файлов - к ним лучше обращаться по индексу во избежание проблем при обфускации ресурсов.

После обфускации:

  • Обязательное тестируйте обфусцированную сборку. Обфускатор не Господь Бог, повторюсь. Он всего лишь делает свою работу, а вы – свою. Поэтому не стоит пренебрегать тестами сборки после обфускации.

  • После обфускации, обязательно проверьте сборку утилитой peverify, которая идет с .Net Framework SDK – эта утилита проверяет метаданные вашей сборки на корректность. Если ваша сборка помечена как CLS-compliant – это тестирование обязательно. Есть халявщики, которые некорректно обфусцированную сборку прикрывают специальным разрешением из PermissionSet.SkipVerification для избежания встречи результирующей сборки с ее верификацией. Проверьте – не появилось ли такое разрешение в вашей сборке после обфускации, понятно на что намекаю. Правда managed C++ сборки имеют изначально такое разрешение, даже если вы о нем не упоминали в вашем коде, это тоже намек :) ).

  • Немного о качестве обфускации – не поленитесь, посмотрите как обфусцирован сам обфускатор. Если обфускатор написан в native code – возможно авторы сомневаются в качестве своей обфускации?

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

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

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