Comments 24
Великолепно!
Надо было ещё через proguard прогнать. Тогда расшифровка дала бы не слишком много.
Почему именно proguard? Это далеко не лучший обфускатор для java. Но целью ставилось обойти именно эту защиту, а работа с обфусцированными классами это уже вообще другая история.
Ну я и имею в виду, что защита куцая. При том, что заморочились с шифрованием, не провели простейшую обфускацию.
Кстати, а какой лучший обфускатор, по вашему мнению?
Кстати, а какой лучший обфускатор, по вашему мнению?
Сам пользуюсь yGuard, если нормально настроить, он обеспечивает приемлемую степень защиты. И zelix, как по мне — один из самых лучших, но он платный.
И я бы не сказал, что защита куцая. Минусы обфускаторов налицо — снижение производительности, слабый thread-safe, сложности с диагностикой ошибок на конечном релизе.
Типа у вас вскочил NPE в методе s_$aa012q43 класса QClassQ123. Офигенно понятно.
Данная защита тоже имеет сносную степень защиты и не имеет минусов, присущих обфускаторам. К тому же, мы имеем доступ к именам методов и следовательно возможность наследования классов и.т.д. Вдобавок она была немного изменена мною так, что воспользоваться способом, описанным в этой статье будет невозможно.
Есть решения с отличной криптостойкостью, они вообще не передают байткод клиенту, а исполняют все по RMI/CORBA. Т.е. у клиента — скелетоны, а серванты с кодом — на сервере разработчика.
Типа у вас вскочил NPE в методе s_$aa012q43 класса QClassQ123. Офигенно понятно.
Данная защита тоже имеет сносную степень защиты и не имеет минусов, присущих обфускаторам. К тому же, мы имеем доступ к именам методов и следовательно возможность наследования классов и.т.д. Вдобавок она была немного изменена мною так, что воспользоваться способом, описанным в этой статье будет невозможно.
Есть решения с отличной криптостойкостью, они вообще не передают байткод клиенту, а исполняют все по RMI/CORBA. Т.е. у клиента — скелетоны, а серванты с кодом — на сервере разработчика.
> Типа у вас вскочил NPE в методе s_$aa012q43 класса QClassQ123. Офигенно понятно.
Вообще, для этого существует детрейс логов, есть у всех нормальных обфускаторов.
Только в таком случаее надо точно знать версию сборки и хранить карты преобразований для каждой сборки.
Вообще, для этого существует детрейс логов, есть у всех нормальных обфускаторов.
Только в таком случаее надо точно знать версию сборки и хранить карты преобразований для каждой сборки.
К сожалению, не знаю что там делают yGuard и zelix, но proguard никак производительность не уменьшает, а наоборот, может, даже слегка увеличивает за счет более коротких имен. Собственно, всё, что он делает — это просто убирает (заменяет) информацию об исходном коде, которая во время выполнения совершенно не нужна. Мало того, по полученным «непонятным» стектрейсам легко восстановить исходный стектрейс, так что всё именно офигенно понятно.
А вот понимание декомпилированного кода с бессмысленными именами переменных и функций — занятие значительно более трудозатратное, чем готового исходного кода. Сколько усилий надо потратить, чтобы найти класс Ranger, если все классы теперь называются aa, ab, ac и тд.? Так что замена имен переменных это, можно сказать, естественный и необходимый шаг, если вы не хотите открывать свой код. А в описанной вами защите этот шаг сделан не был.
А насчет клиента-сервера — тут уже неважно на чем написан сервер и вообще, зашифрован ли его код, код сервера вы никак получить не сможете (без физического доступа к нему и при реализации без ошибок, разумеется).
А вот понимание декомпилированного кода с бессмысленными именами переменных и функций — занятие значительно более трудозатратное, чем готового исходного кода. Сколько усилий надо потратить, чтобы найти класс Ranger, если все классы теперь называются aa, ab, ac и тд.? Так что замена имен переменных это, можно сказать, естественный и необходимый шаг, если вы не хотите открывать свой код. А в описанной вами защите этот шаг сделан не был.
А насчет клиента-сервера — тут уже неважно на чем написан сервер и вообще, зашифрован ли его код, код сервера вы никак получить не сможете (без физического доступа к нему и при реализации без ошибок, разумеется).
UFO just landed and posted this here
В java названия переменных используются и в байткоде. Например, загрузка класса происходит по его имени. Длиннее имя класса — слегка дольше надо сравнивать строки. Разумеется, это всё очень маленькие накладные расходы, но тем не менее, они есть.
В этом смысле производительность, наоборот, возрастет, т.к. обычно обфускаторы сокращают имена переменных и классов: a, aa, aA (зависит от конкретного обфускатора и настроек). Заодно и размер сократится.
Производительность ухудшается по другой причине — если включены агрессивные опции, то во flow добавляются ложные/холостые условия, методы и т.д.
Производительность ухудшается по другой причине — если включены агрессивные опции, то во flow добавляются ложные/холостые условия, методы и т.д.
Сколько усилий надо потратить, чтобы найти класс Ranger, если все классы теперь называются aa, ab, ac и тд.?Любая библиотека для работы с байт-кодом (например, BCEL) + немного времени и вот уже эти непонятные aa, ab и ac превратились в Class_12, Interface_23, Exception_34.
Ещё немного времени + IDE с поддержкой рефакторинга — и вот уже интересующие нас участки вполне себе читаемы.
Может мы и не узнаем никогда, что в юности Class_42 звался Ranger, но так ли нам важна его девичья фамилия?
Если обфускатор занимается только переименованием идентификаторов, он ни на что серьёзное не годен. Правильный обфускатор должен корёжить граф наследования, тасовать методы и поля, запутывать алгоритм непрозрачными вычислениями. Последнее, правда, влияет на быстродействие.
Да зачем библиотека? На это годен и ProGuard со специальными словарями имен (как раз из Class_N и Member_N). Локалы приводятся в нормальный вид простым гроханьем их таблицы.
Пользуясь случаем, поздравляю всех с Новым Годом!
А теперь по делу, описанный подход известен довольно давно: blogs.oracle.com/sundararajan/entry/retrieving_class_files_from_a, еще одна статья — www.javaworld.com/javaworld/javaqa/2003-05/01-qa-0509-jcrypt.html
Метод не является универсальным, т.к., например, zenofx ClassGuard попытки подключения через Agent блокирует. Здесь, на Хабре, я публиковал статью с хорошим методом обхода подобной защиты: Против лома нет приёма: OpenJDK hack vs. Class Encryption
А теперь по делу, описанный подход известен довольно давно: blogs.oracle.com/sundararajan/entry/retrieving_class_files_from_a, еще одна статья — www.javaworld.com/javaworld/javaqa/2003-05/01-qa-0509-jcrypt.html
Метод не является универсальным, т.к., например, zenofx ClassGuard попытки подключения через Agent блокирует. Здесь, на Хабре, я публиковал статью с хорошим методом обхода подобной защиты: Против лома нет приёма: OpenJDK hack vs. Class Encryption
В немного измененной версии защиты я запретил запуск с не-oracle JVM. Тем более, что этот метод (а точнее, уже существующая утилита) делает это намного быстрее, проще и удобнее.
И по поводу блокирования подключения агента. Один мой знакомый колдовал над усовершенствованием данной защиты, сказал, что в нативной части запретил подключения агента. Не знаю, как и что он там делал, но утилита беспрепятственно сдампила все классы приложения без остатка.
И по поводу блокирования подключения агента. Один мой знакомый колдовал над усовершенствованием данной защиты, сказал, что в нативной части запретил подключения агента. Не знаю, как и что он там делал, но утилита беспрепятственно сдампила все классы приложения без остатка.
Это все конечно клево. Но в чем поинт? Если бы вы научились классы релоадить как это делает JRebel — меня бы это если честно больше впечатлило, чем перевод простенького туториала под Java Agant'у +ClassLoader'у и дописывания 10 строк кода.
Где Вы тут видите перевод туториала? А в чем понт написано в самом начале статьи, прочтите внимательнее.
Раз: docs.oracle.com/javase/tutorial/ext/basics/load.html
Два: dhruba.name/2010/02/07/creation-dynamic-loading-and-instrumentation-with-javaagents/
Как я сказал выше, было бы интереснее увидеть нечто нестандартное, а не то, что можно в гугле и так за пол минуты нагуглить.
Два: dhruba.name/2010/02/07/creation-dynamic-loading-and-instrumentation-with-javaagents/
Как я сказал выше, было бы интереснее увидеть нечто нестандартное, а не то, что можно в гугле и так за пол минуты нагуглить.
Sign up to leave a comment.
Шифруются? Вытаскиваем байткод из JVM