Как стать автором
Обновить
33
0
Алексей Скурыдин @Anakonda

Пользователь

Отправить сообщение
Да, спасибо Вам за замечание, мы убрали вставку пароля в письмо.
Для примера выкладываю обфусцированную OpenSource программу NClass
Обфускация проведена со всеми параметрами по умолчанию, без явных исключений, все алгоритмы защиты включены:
public.66bit.ru/files/2013.02.15/2abc87810a9a9963d7ee81e3434a36b5/NClass.rar (смотреть в ILSpy, Reflector и т.п.)
Оригинальный код: nclass.sourceforge.net/
Сервис может обфусцировать любые .NET сборки, поэтому если WinRT приложение написано на .NET, то все должно работать.
Страничка с тарифами обязательно будет, как я уже писал выше, что мы проглядели этот вопрос.
Нет, пароль доступен только в момент регистрации из формы, а в БД сохраняется уже хеш md5 с солью.
Не существуют защиты, которую не возможно обойти. Единственная цель любых средств защиты — максимально повысить стоимость взлома и, в идеале, сделать его нерентабельным.
Большое спасибо, действительно мы слишком увлеклись работой над программой, и совсем забыли про обновление сайта. Битую ссылку поправили, страницу с нормальным прайсом сделаем в самое ближайшее время.
А Вы попробуйте одновременно включить все режимы защиты в обфускаторе (кроме галочки Library mode, т.к. это не защита). В совокупности они дают особенно красивый эффект :)
Да, но это вырожденный случай, как правило в switch оказывается не одна ветка а множество. При этом значение счетчика устанавливается в предыдущем шаге для следующего, чтобы усложнить анализ. Кроме того, в некоторые моменты, выполнение уходит за пределы switch блока, и обрабатывается другими инструкциями перехода. Там так же применяется переход на базе счетчика, с разделенной на разные блоки инциализацией и инструкцией перехода.
Спасибо, мы будем стараться.
> Этим обычно не занимаются, а ломают защиту, меняют логотип и продают как свою
Чтобы сменить лого, совсем не обязательно лезть в код, достаточно открыть ресурсы. А вот чтобы снять защиту, особенно когда она хорошо распределена по программе и программа при этом обфусцированна, нужно очень много сил и времени, а главное после выпуска новой версии, все придется повторять вновь, что делает такой «взлом» абсолютно нерентабельным.

> К сожалению вы неправы. Имена классов/членов класса не используются, используются только токены метаданных
Это не так, токен каждого метода храниться отдельно и если не учитывать связи между типами, то программа работать не будет :) Можно конечно все методы «a» переименовать разом в одно имя, а все методы «b» в другое, но учитывая что таких методов «a» несколько сотен, они все разные и никак друг с другом не связаны, это очень вряд ли хоть чуть-чуть поможет с читаемостью кода.

> IL Оптимизатор ничего не знает о calli, в итоге вы эффективно мешаете оптимизатору инлайнить методы
Суть External Method Call Hiding как раз в том, что скрываются вызовы только _внешних_ методов из других сборок. Вызовы методов внутри сборки остаются нетронутыми. А касательно inline, Вы сильно переоцениваете оптимизатор, как правило он может заинлайнить внешние вызовы только с атрибутом TargetedPatchingOptOut (только в случае NGen), MethodImplAttribute (FW 4.5) и подобными. С уверенностью скажу что никаких «неявных» точек в стеке не появляется и «асинхронные» эксепшены не происходят. Если бы это было не так, из среды .NET не возможно было бы обращаться к неуправляемому коду, а это не так, более того, множество методов внутри самой CLR заканчиваются неуправляемым кодом.

> Если проект тяжело сидит на рефлекшене то взломщику придётся разбирать что и куда идёт
Намного интереснее это выглядит после нашего обфускатора, когда вместо какого-нибудь type.GetMethod(«GetPrice») увидит:
1. calli по которому еще надо догадаться, что это был вызов GetMethod
2. Вызов какого-нибудь «d(int, int)» по которому нужно догадаться что это String Encription
3. Расковыряв всю эту цепочку пользователь получит строку, пусть это будет «a» (скорее всего примерно так и будет) и по нему надо каким-то волшебным образом восстановить, что это бывший «GetPrice»
И так почти на каждой строчке.

> Возникла мысль. Вы дебаг символы надеюсь вытираете? Mono.Cecil их старается сохранить, было бы приятно их обнаружить.
Нет, конечно мы их не сохраняем, они там и не могут оказаться, т.к. как я говорил чуть раньше, мы не правим старую сборку а создаем с нуля полностью новую.

> Именно, обфускация бесполезная трата денег.
Как раз наоборот, покупать аппаратные ключи и встраивать их в необфусцированную .NET программу — столь же глупо как и пытаться добавить защиту хардверными ключами в Open Source приложение выложенное на github (разницы фактически никакой). Только комплексная защита может дать желаемый эффект.
На словах все очень просто, а Вы бы попробовали ;)

> мне нужен «оригинальный» код.
Оригинального кода уже нет, взломщику точно так же нужно строить все связи и искать сложные зависимости для того чтобы внести изменения и не сломать работу программы. Допустим есть классы a, b и их интерфейс IBase. Если в одном из них переименовать метод а в другом — нет, то программа просто вылетит при загрузки этого типа данных. Аналогично и с рефлекшином, только теперь имена бессмысленны и скрыты под String Encryption. И как и нам хакеру придется выявлять атрибуты содержащие в себе строковые имена.

> Только размазываете тонким слоем, теряя производительность, портируемость и другие качества проекта.
А можно конкретнее, в чем потеря портируемости и особенно производительности? Cтатические функции медленнее чем методы экземпляров или короткие имена вида a,b,c работают хуже чем оригинальные?

> Причем «запускаемость» кода часто не нужна.
Если цель только посмотреть один маленький кусочек исходного кода — то это ошибка не обфускатора, а разработчика лицензионных ограничений. Правильная защита строиться по другому, и никакой обфускатор здесь не поможет. Для того чтобы защиту трудно было снять, она должна быть очень плотно интегрирована в программу, и проверки лицензии должны быть во множестве мест программы. А как самый идеальный случай, для особенно надежной защиты, я бы порекомендовал использовать ключи с собственным процессором для защищенного выполнения кода внутри них. В такой ключ можно вынести несколько реальных алгоритмов из программы и этим усложнить обход защиты на несколько порядков.
Абсолютно согласен защита должна быть комплексной от технических мер до административных.
Разницы между явной и неявной реализацией интерфейсов для обфускатора нет, т.к. и те и другие всегда будут виртуальными функциями, которые не попадают под декомпозицию. А renamer умеет строить умные деревья зависимостей чтобы дать правильные имена. Про делегаты уже писал выше, конструкторы остаются на месте, статические методы тем более прекрасно декомпозитятся.

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

> Например, всякие системы плагинов, MEF-ориентированные сборки и свои Dependency Injection велосипеды.
Если писать их правильно, то все будет работать. Я лично, очень рекомендую использовать Reflection вызовы по пользовательским атрибутам, а не по жестко забитым в коде именам, а так же проверять типы через typeof а не сравнением строк. Ряд достаточно простых правил, позволяет писать Reflection код, хорошо совместимый с любым умным обфускатором.

> Пробовали отлаживать на сложных расширяемых приложениях?
Да, тестирование и разрешение всяких сложных случаев растянулось у нас больше чем на 5 месяцев, поэтому с одной стороны могу с уверенностью сказать что многие сложные системы заработают без малейшего изменения кода. С другой стороны — точно есть случаи в которых потребуется вмешательство программиста.
Не существует защиты, которую в принципе невозможно снять, и единственный важный критерий оценки — соотношение стоимости взлома защищенного продукта со стоимостью его приобретения. Соответственно единственное что должна делать защита — делать это соотношение крайне не выгодным для хакера.
Если кто-то заявляет что его защита дает 100% гарантии, то значит он врет :)

> Получается что для «восстановления» достаточно переместить тело метода обратно
Теоретически да, но фактически далеко не всегда возможно определить где был этот метод.

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

External Method Call Hiding — не совсем табличка, опять же можно написать анализатор который по типовым конструкциям пытается найти скрытые методы, там так же используются переменные различные в разных контекстах, но взломщик при очень большом желании сможет написать программу для анализа. Точно так же как мы можем изменив всего пару строчек кода полностью уничтожить все зацепки на которые он рассчитывал (например тот же calli всего лишь один из вараинтов, и взят он лишь по причине своей необычности на сегодняшний день). А с онлайн сервисом такие обновления производить особенно удобно.

По String Encryption, в текущий момент времени — соглашусь, способ описанный Вами весьма не плох (кроме сложности покрытия тестами, как правило никогда не удастся извлечь из программы все строки). Но решается это столь же просто — несколько алгоритмов проверки целостности кода, отказ от одной точки шифрования строк, в пользу нескольких (динамически генерируемых и разбрасываемых по отдельным классам) + возможно интеллектуальный алгоритм предотвращения «сдапливания».

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

И что еще более важно, сейчас у нас есть большая фора, пока сервис не набрал очень большой популярности, никто не станет писать специализированные анаизаторы под придуманные лично нами алгоритмы. И за это время, мы планируем добавить еще очень много всего вкусного и интересного (в частности небольшую собственную виртуальную машину для самых любопытных хакеру частей кода :)
[параноик mode on]Перед отправкой сборки на наш сервис, добавляйте в нее специальную пометку (класс/строку/атрибут), и если она уйдет через нас, то это легко можно будет отследить ;)[/параноик mode off]

А если серьезно, то репутация зарабатывается только долгой безупречной работой и больше никак. Разве что косвенными подтверждениями серьезности намерений могут быть давно зарегистрированное юр. лицо, аттестат продавца от 2009 года, прошлые успешные проекты.
По поводу технологий — в основе ядра нашего обфускатора лежит пропатченный и доработанный нами mono.cecil и поверх него строится вся логика дерева разбора, перименования, линковки библиотек и т.д.

Никакие другие технологии типа того же ilmerge мы не используем. Более того, мы не производим никаких изменений в пришедшей на вход сборке, а на основе механизмов cecil создаем полностью новую.
Да, как верно заметил mayorovp, виртуальные методы мы не выносим т.к. одно из главных правил декомпозиции не ломать логику CLR, а с делегатами все ок, от декомпозиции их суть не меняется — просто вместо метода, которому указатель на this передается не явно через стандартный механизм CLR, мы делаем статический метод, которому этот указатель передается явно. Если так можно выразится, то бинарная совместимость в этом случае полная, а логическая связь метода и типа к которому он относился ранее — нарушается.
Куда-то не туда попал, прошлый комментарий — ответ на неоднозначность с облаком Azure.

По теме WCF:
1. Программа исключает из обфускации типы, переименование которых анализатор считает небезопасным. Я сейчас честно говоря, сходу не вспомню прописывали ли мы конкретно WCF исключения, но многие стандартные базовые классы/атрибуты уже добавлены, и мы постепенно расширяем список исключений
2. WCF объекты можно сохранить в отдельной сборке, и вообще не добавлять ее при обфускации, а обфусцировать только тело программы
3. Можно исключать из обработки любые отдельные классы с помощью стандартного атрибута ObfuscationAttribute
Как-то не подумал о такой неоднозначности, пожалуй подправлю.
Офлайн версия, ориентированная на крупных клиентов, есть в наших планах. Но ею мы займемся немного позже, в первую очередь сейчас мы ориентированны на небольшие компании и для них SaaS доступ — возможность существенного сокращения расходов.

Информация

В рейтинге
Не участвует
Откуда
Екатеринбург, Свердловская обл., Россия
Дата рождения
Зарегистрирован
Активность