Pull to refresh

Обфускаторы (и деобфускаторы) для .NET §0

Reading time 3 min
Views 21K
Ни для кого не секрет, что из скомпилированных сборок (exe и dll) для платформы .NET может быть легко восстановлен код на языках высокого уровня (C#, VB.net). Это означает не только то, что если в программе имеется система лицензирования, то она может быть легко снята; но и то, что ваш исходный код могут скопировать, например, нечистые на руку конкуренты. Чтобы обезопасить себя от подобных угроз большинство разработчиков коммерческого софта используют разного рода обфускаторы.

Зачем и от кого защищаемся?


Очевидно, что обфускация как один из этапов защиты актуальна только для коммерческого софта.
Защищать программу, если в ней используется система регистрации по серийному номеру или активация, требуется от «кракеров», которые либо за неимением денег (если программа дорогая), либо из любви к искусству пишут краки. Выяснить, где находится нужный условный переход, или проверка серийника намного тяжелее, если перед вами в лучшем случае «узел» из IL-кода, чем если мы видим легко понятный C#-код. Это, конечно, не панацея, но добавляет n-ное количество минут, необходимое для взлома. (Если n достаточно велико, то пытаться ломать будут только очень упорные индивиды ;)

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

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

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

Обфускаторы и упаковщики


.NET-приложения пытаются защищать двумя основными методиками: непосредственно обфускацией IL-кода (когда на выходе получается почти-валидная* .net-сборка, и её можно выполнять на немодфицированном MS.NET или mono). И упаковкой — модификацией сборки так, что на выходе получается winapi-приложение, содержащее в себе распаковывающий модуль и упакованый IL-код.
* — сборка может содержать невалидные IL-инструкции, которые однако не будут выполняться. И сборка в целом выглядит «нормальной» и может быть запущена на любом поддерживаемом рантайме
С обфускацией вроде всё ясно: подаём на вход .net сборку, получаем на выход .net сборку, всё работает примерно так же. Никаких лишних «спрятанных» данных, всё находится на месте, только запутано и переименовано в что-то бесполезное.
В случае с упаковщиком нас ожидают некоторые проблемы:
  • Наша сборка будет выполняться теперь только под виндой (либо аккуратно настроенным mono+wine)
  • Упаковщик, который передаёт на вход mscoree оригинальную сборку, снимается за 1 минуту, и не имеет смысла для защиты. Упаковщики, которые перехватывают внутренние функции mscoree очень сильно зависят от версии фреймворка, и вызывают у некоторых антивирусов false positive реакции. Перехват внутренних функций вообще дело тонкое и неблагодарное.
  • Упаковщики являются native-программами, и не дают скомпилироваться вашему приложению в x86-64 код там, где это доступно (а в некоторых случаях это даёт большой прирост производительности)
  • Для нормального выполнения среде .net в любом случае требуется доступ к оригинальному IL-байткоду. И даже preJITted-сборки должны его в себе содержать. А значит и получить этот байткод тоже реально.
  • И, на последок, цитата: «if it runs it can be unpacked»

Разнообразные «защитники» (protectors) обычно объединяют в себе оба подхода и будут рассмотрены в обеих частях данного обзора.

Инструменты реверсера


Первым и самым основным инструментом является рефлектор. Обычно каждый качает к нему плагины на свой вкус. Я порекомендую лишь один: reflexil, он позволяет менять байткод методов, свойства сборки, и содержит удобную утилиту удаления strong-name. С помощью этого плагина очень удобно делать краки ;)
Если сборка подверглась обфускации, то просматривать её в рефлекторе не очень удобно, поэтому перед изменением (или вытаскиванием кода) её надо «деобфусцировать», для этого применяются разнообразные готовые деобфускаторы (коих в интернете можно найти очень много).
Также полезно иметь собственный деобфускатор, который всегда легко «допилить» до нужд определённой задачи.
Если мы будем иметь дело с упаковщиками, то нам понадобятся различные инструменты для native reverse engineering, такие как дебаггер (WinDbg, OllyDbg), дампер (PE tools), редактор PE-файлов (например CFF Explorer). А так же специфичные для .net-распаковки инструменты: Generic .NET Unpacker, .net dumper (KDD), .Net Assembly Rebuilder. С ними мы познакомимся во второй части обзора.

Всё, на этом моё словоблудие заканчивается, следующий пост будет содержать в себе больше подробностей (даже с картинками) ;)

Продолжение →

Примерное содержание следующих постов:
  • 1. Обфускаторы.
    • 1.1. Методики
    • 1.2. Обзор обфускаторов
    • 1.3. Методики деобфускации
    • 1.4. Деобфускаторы
  • 2. Упаковщики.
  • 3. Использованные источники, и что ещё почитать по теме
Tags:
Hubs:
+13
Comments 30
Comments Comments 30

Articles