Обычно, для защиты Java-программ используются обфускаторы. Обфускаторы позволяют переименовать классы, методы, переменные, изменить поток управления (control flow) байт-кода. Эти функции умеют делать все обфускаторы включая бесплатные и платные.
Целью обфускации байт-кода является построение такого набора команд JVM из которого декомпилятор не мог бы построить корректный исходный код на языке Java.
Противостояние обфускаторов и декомпиляторов продолжается постоянно.
Например в рамках исследовательского проекта Soot одновременно разрабатываются обфускатор JBCO и декомпилятор DAVA, разработчики которых соревнуются друг с другом.
Для чего злоумышленниками и добросовестным разработчикам нужно декомпилировать Java-программы?
Классический обфускатор относительно хорошо справляется с защитой от второго типа атак. От реверс-инжиниринга он помогает слабо, потому что Java-программы используют Java API, которое публично и обфускатор не может его изменить. Есть одно исключение, но это даже не обфускатор, а полноценная виртуальная машина с нативной реализацией Java API — Excelsior JET.
Ни для кого не секрет, что в настоящее время наблюдается «бум» троянов, которые, используя уязвимости в JVM, проникают на компьютер пользователя для осуществления своих зловредных действий, в наибольшей степени по отношению к программам, которые работают с финансовой и другой ценной информацией.
Современные средства защиты Java кода должны скорее не защищать его от декомпиляции, а организовывать «песочницу» внутри «песочницы» Java :)
С этими проблемами мы столкнулись, разрабатывая систему лицензирования для Java/Java FX приложений — C3. И так родился Stringer.
Теперь вернемся к реальности. Большая часть логики которую хотели бы защищать раработчики коммерческих Java-приложений (в том числе и различные приложения для Android) завязана на строки… Ох уж эти java.lang.String's.
Например. У нас есть графический клиент, который получает с интернет-ресурса данные в определенном формате, парсит и отображает их пользователю. Злоумышленнику достаточно получить доступ к констант-пулу Java класса и для него не составит никакого труда сделать программу-клон.
Обычно разработчики для защиты от этих атак используют свои функции шифрования строк или пользуются обфускаторами с поддержкой этих функций.
Stringer отлично умеет выполнять эту задачу:
Плюс упомянутая выше возможность организации песочницы: защита от использования reflection, защита private-полей классов и методов, защита final-полей классов от модификации.
Мы считаем, что функция шифрования строк нужна практически каждому разработчику, а для компаний которые хотят защитить пользователей своих продуктов от кражи информации Stringer позволяет организовывать защищенную среду внутри Java-приложения, но эта тема достойна отдельного поста…
В настоящее время мы занимаемся разработкой Stringer для Android-приложений.
Stay tuned :)
P.S.
Кстати, наш CrackMe так никто и не взломал.
Кроме пользователей Хабра, очень активное участие принимали пользователи Javalobby. Суммарно скачиваний было около тысячи, и только один из участников дошел до этапа взаимодействия с сервером лицензирования.
Целью обфускации байт-кода является построение такого набора команд JVM из которого декомпилятор не мог бы построить корректный исходный код на языке Java.
Противостояние обфускаторов и декомпиляторов продолжается постоянно.
Например в рамках исследовательского проекта Soot одновременно разрабатываются обфускатор JBCO и декомпилятор DAVA, разработчики которых соревнуются друг с другом.
Для чего злоумышленниками и добросовестным разработчикам нужно декомпилировать Java-программы?
- Реверс-инжиниринг проприетарного API
- Модификация байт-кода для отключения различных механизмов лицензирования
- Получение доступа к «чувствительной» информации
Классический обфускатор относительно хорошо справляется с защитой от второго типа атак. От реверс-инжиниринга он помогает слабо, потому что Java-программы используют Java API, которое публично и обфускатор не может его изменить. Есть одно исключение, но это даже не обфускатор, а полноценная виртуальная машина с нативной реализацией Java API — Excelsior JET.
Ни для кого не секрет, что в настоящее время наблюдается «бум» троянов, которые, используя уязвимости в JVM, проникают на компьютер пользователя для осуществления своих зловредных действий, в наибольшей степени по отношению к программам, которые работают с финансовой и другой ценной информацией.
Современные средства защиты Java кода должны скорее не защищать его от декомпиляции, а организовывать «песочницу» внутри «песочницы» Java :)
С этими проблемами мы столкнулись, разрабатывая систему лицензирования для Java/Java FX приложений — C3. И так родился Stringer.
Теперь вернемся к реальности. Большая часть логики которую хотели бы защищать раработчики коммерческих Java-приложений (в том числе и различные приложения для Android) завязана на строки… Ох уж эти java.lang.String's.
Например. У нас есть графический клиент, который получает с интернет-ресурса данные в определенном формате, парсит и отображает их пользователю. Злоумышленнику достаточно получить доступ к констант-пулу Java класса и для него не составит никакого труда сделать программу-клон.
Обычно разработчики для защиты от этих атак используют свои функции шифрования строк или пользуются обфускаторами с поддержкой этих функций.
Stringer отлично умеет выполнять эту задачу:
- Шифрование реализовано на базе алгоритма AES с динамическими ключами шифрования для каждого защищаемого Java-пакета
- Логика функций дешифрования динамически встраивается в уже имеющиеся class-файлы:
Фрагмент декомпилированного class-файла до встраивания защиты:
public class App { public static void main(String args[]) { System.out.println("Hello World!"); } }
Фрагмент декомпилированного class-файла после встраивания защиты:
public class App { public static void main(String args[]) { System.out.println(main("\u916E\u2E67\uCB8D\u16B9\u479D\u7669\u3F20\uD7DC\u75C5\u30F1\uEC7E\uA26B\uEEB0\u2F0E\u4828\u19C6")); } .... }
- Защита контекста вызова функций дешифрования
Плюс упомянутая выше возможность организации песочницы: защита от использования reflection, защита private-полей классов и методов, защита final-полей классов от модификации.
Мы считаем, что функция шифрования строк нужна практически каждому разработчику, а для компаний которые хотят защитить пользователей своих продуктов от кражи информации Stringer позволяет организовывать защищенную среду внутри Java-приложения, но эта тема достойна отдельного поста…
В настоящее время мы занимаемся разработкой Stringer для Android-приложений.
Stay tuned :)
P.S.
Кстати, наш CrackMe так никто и не взломал.
Кроме пользователей Хабра, очень активное участие принимали пользователи Javalobby. Суммарно скачиваний было около тысячи, и только один из участников дошел до этапа взаимодействия с сервером лицензирования.