Pull to refresh

Comments 15

Защитить кода от реверс инженеринга невозможно, можно только его осложнить.

de4dot распаковывает конфузер из статьи за 5 секунд, автор статьи видимо не в курсе современных инструментов для кракинга.

Как он восстанавливает переименованные идентификаторы и какие современные инструменты?

Безусловно, стоковый ConfuserEx будет обнаружен за 5 секунд. Но можно несколько усложнить жизнь de4dot. В статье об этом говорится в пунке «Кастомизация защиты».

Получается как-то вот так
image

А что такого критичного в обнаружении обфускатора? Использовать такую скрытность как фичу — сомнительная идея. Тем более можно и по характеру защиты вычислить обфускатор. Важно не что, а как.

Вопрос только в требуемом уровне квалификации и потраченном времени на реверс. Идеально заобфускаченная сборка — это сборка, реверс которой нецелесообразен.

Я всего лишь хотел сказать, что можно легко изменить стандартные сигнатуры, и тогда распространенные средства деобфускации не смогут снять защиту в автоматическом режиме. И для продолжения потребуется более высокая квалификация и намного больше времени.
EAZ с толикой виртулизации нормально защищает. Для персональных небольших проектов можно использовать народную версию.
ConfuserEx (http://yck1509.github.io/ConfuserEx/) один из бесплатных обфускаторов для .Net с открытым исходным кодом.

Не советую использовать данный обфускатор — он давно умер, собственно как раз в 2016.


Но живет и процветает его форк: https://github.com/mkaring/ConfuserEx В нем пофикшено много багов и реализованы новые фичи. Причем большинство защит реально работает, в отличие от оригинала, где они часто ломаются и приходится долго искать причину, что-то отключать. Самый большой недостаток — нет поддержки .NET Core, но такой поддержки я вообще не встречал в опенсорсных обфускаторах.


Кстати, на гитхабе есть репозиторий со списком платных/бесплатных/опенсорсных/живых/мертвых обфускаторов: .NET-Obfuscator.


Защита Name Protection нарушает работу механизмов Reflection и сериализации.

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


Кстати, если программа поставляется как единое целое, не библиотека и не API, то имеет смысл использовать public ринейминг, который затирает намного больше информации.


Дизассемблированый код в dotPeek

Также удобно использовать dnSpy.

К обфускации стоит подходить очень осторожно. Уже на этом примере заметно, насколько медленнее становится код((( Бедный JIT(

На мой взгляд минимально нужно использовать ринейминг — при этой защите происходит потеря информации без влияния на производительность.


При других обфускациях информация либо не теряется (resource encryption), либо добавляется лишняя (control flow, invalid metadata). Но шифрование можно хакнуть в динамике, а убрать лишнюю логику легче, чем восстановить отсутствующую. Кроме того, есть опция ринейминга, которая позволяет восстанавливать оригинальные имена. Например, если у клиента возникла проблема на конкретной сборке. Для этого генерируется секретный файл symbols.map, который используется во время деобфускации.

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

Мне буквально недавно пришлось делать выбор обфускатора для одного нашего проекта.
Пересмотрел целую кучу, в результате сделал для себя следующее резюме:
1) Для .Net Core 3.1+ свободных и поддерживающих все фичи платформы для всех 3 нужных нам платформ попросту нет. Если что-то и есть, то или это строго под винду или оно работает ровно в той части, которая нужна автору. Садиться и допиливать своё требует дополнительных ресурсов (как финансовых, так и временнЫх).

2) Есть куча коммерческих, при этом разброс цен буквально на порядок — от $180 до $3к в год за 1 рабочее место. И очень часто ценник никак не влияет на отсутствие поддержки конкретного обфускатора в деобфускаторе типа de4dot :) Последний очень хорошо деобфусцирует работу коммерческого обфускатора со стоимостью лицензии за 3к в год.

3) Самый лучший вариант — это выбрать 5-6-8 утилит и провести тесты — как с замерами производительности, так и с исследованиями сопротивляемости деобфускации.

4) Control flow obfuscation/virtualization — это ужасный удар по производительности, местами в 7-10 раз. Чудес, конечно, никто не ожидал, но чтобы прямо вот в разы падала скорость — было огромным разочарованием.

Огромную надежду вселяет проект нативной компиляции CoreRT — да, отказ от Reflection-а не всем по душе, но на практике оно того стоит. Код получается быстрым, хотя не всегда (надеюсь, что пока) стабильным. Хотелось бы, чтобы его довели до ума, пусть и через год-два. И очень надеюсь, что MS не загадит белый и пушистый шарп, как это сделал комитет с С++ к тому времени :)

И какой обфускатор вы в итоге выбрали?

Я в итоге остановился на .Net Reactor-е (ссылку не даю, но гуглится легко) — он лучше всех справился с деобфускатором, техподдержка отвечала на мои вопросы очень быстро и по делу. Ко всему прочему мне понравилась их политика лицензирования — на компанию, без учёта количества рабочих мест. Хотя последнее не очень важно при использовании билд-машин для подготовке финального релиза, но мне нравятся компании, у которых ценник написан сразу, а не «по запросу».
Возможно, у меня очень кривая выборка жизненного опыта, но она показывает, что обфусцриурют, как правило, те проекты, которые в этом не нуждаются: либо это Неуловимые Джо, либо легаси-код, над нативной обфускацией которого потопталось не одно поколение погромистов.
Sign up to leave a comment.

Articles