Вы запутываете свой коммерческий код Java?

Интересно, использует ли кто-нибудь коммерческие / бесплатные java-обфускаторы в своем собственном коммерческом продукте. Я знаю только об одном проекте, в котором на этапе сборки муравья для выпусков был этап запутывания.

Вы запутываете? И если да, то почему вы запутываете?

Действительно ли это способ защитить код или это просто лучшее чувство для разработчиков / менеджеров?

редактировать: Хорошо, если быть точным, о своей точке зрения: вы запутываете, чтобы защитить свой IP (свои алгоритмы, работу, которую вы вложили в свой продукт)? Я не буду запутывать меня из соображений безопасности, это неправильно. Так что я говорю только о защите кода вашего приложения от конкурентов.

У @staffan есть хороший аргумент:

The reason to stay away from chaining code flow is that some of those changes makes it impossible for the JVM to efficiently optimize the code. In effect it will actually degrade the performance of your application.

Я еще не видел хорошего обфускатора, но, возможно, вы захотите посмотреть эту ветку, даже если она про .Net: http://stackoverflow.com/questions/12075/should-i-be-worried‌ -about-obfusicating-‌ мой-сетевой-код

John Smithers 15.08.2008 13:16
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
50
1
49 263
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Думаю, все сводится к Какие, для которого предназначен ваш Java-код, как он распространяется и кто ваши клиенты. Мы ничего не скрываем, так как никогда не находили ничего особенно хорошего, и это, как правило, доставляет больше проблем, чем того стоит. Если у кого-то есть доступ к нашим JAR-файлам и есть знания, чтобы обнюхать их, то он может сделать гораздо больше тревожных вещей, чем просто скопировать наш исходный код.

Я использую proguard для разработки JavaME. Это не только очень хорошо для уменьшения размера jar-файлов (важно для мобильных устройств), но и полезно как более приятный способ создания кода для конкретного устройства, не прибегая к недружественным IDE инструментам предварительной обработки, таким как антенна.

Например.

public void doSomething()
{
    /* Generated config class containing static finals: */
    if (Configuration.ISMOTOROLA)
    {
        System.out.println("This is a motorola phone");
    }
    else
    {
        System.out.println("This is not a motorola phone");
    }
}

Это компилируется, запутывается, и файл класса заканчивается так, как если бы вы написали:

public void doSomething()
{
    System.out.println("This is a motorola phone");
}

Таким образом, у вас могут быть варианты кода для обхода ошибок производителя в реализациях JVM / библиотеки без увеличения объема конечных исполняемых файлов классов.

Я считаю, что некоторые коммерческие обфускаторы также могут в определенных случаях объединять файлы классов. Это полезно, потому что чем больше у вас классов, тем больше накладные расходы на размер файла zip (jar).

Фактически, что касается условного кода, спецификация Java требует, чтобы компилятор отбрасывал мертвый код, подобный этому, при условии, что условие назначается через статически ложное выражение. Это все, что умеет Proguard.

Lawrence Dol 10.01.2017 06:13
Ответ принят как подходящий

Если вы делаете обфускацию, держитесь подальше от обфускаторов, которые изменяют код, изменяя поток кода и / или добавляя блоки исключений и тому подобное, чтобы затруднить его дизассемблирование. Чтобы сделать код нечитаемым, обычно достаточно просто изменить все названия методов, полей и классов.

Причина, по которой следует избегать изменения потока кода, заключается в том, что некоторые из этих изменений не позволяют JVM эффективно оптимизировать код. Фактически это снизит производительность вашего приложения.

Для меня это звучит как преждевременная оптимизация.

NateS 30.01.2014 22:48

В этом году я потратил некоторое время на опробование различных обфускаторов Java и обнаружил, что один намного опережает остальных: JBCO. К сожалению, это немного громоздко в настройке и не имеет графического интерфейса, но с точки зрения уровня обфускации он не имеет себе равных. Вы пытаетесь скормить ему простой цикл, и если ваш декомпилятор не выйдет из строя, пытаясь его загрузить, вы увидите что-то вроде этого:

    if (i < ll1) goto _L6; else goto _L5
_L5:
    char ac[] = run(stop(lI1l));
    l7 = (long)ac.length << 32 & 0xffffffff00000000L ^ l7 & 0xffffffffL;
    if ((int)((l7 & 0xffffffff00000000L) >> 32) != $)
    {
        l = (long)III << 50 & 0x4000000000000L ^ l & 0xfffbffffffffffffL;
    } else
    {
        for(l3 = (long)III & 0xffffffffL ^ l3 & 0xffffffff00000000L; (int)(l3 & 0xffffffffL) < ll1; l3 = (long)(S$$ + (int)(l3 & 0xffffffffL)) ^ l3 & 0xffffffff00000000L)
        {
            for(int j = III; j < ll1; j++)
            {
                l2 = (long)actionevent[j][(int)(l3 & 0xffffffffL)] & 65535L ^ l2 & 0xffffffffffff0000L;
                l6 = (long)(j << -351) & 0xffffffffL ^ l6 & 0xffffffff00000000L;
                l1 = (long)((int)(l6 & 0xffffffffL) + j) & 0xffffffffL ^ l1 & 0xffffffff00000000L;
                l = (long)((int)(l1 & 0xffffffffL) + (int)(l3 & 0xffffffffL)) << 16 & 0xffffffff0000L ^ l & 0xffff00000000ffffL;
                l = (long)ac[(int)((l & 0xffffffff0000L) >> 16)] & 65535L ^ l & 0xffffffffffff0000L;
                if ((char)(int)(l2 & 65535L) != (char)(int)(l & 65535L))
                {
                    l = (long)III << 50 & 0x4000000000000L ^ l & 0xfffbffffffffffffL;
                }
            }

        }

    }

Вы не знали, что в Java есть goto? Что ж, JVM их поддерживает =)

На уровне машинного кода (и, следовательно, в байт-коде, который является просто машинно-независимым машинным кодом) все компьютеры используют goto. Циклы - это просто конструкции goto / condition. Между прочим, continue и break - это не что иное, как ограниченный переход с использованием меток (иногда метка подразумевается, а не явно).

Lawrence Dol 27.04.2011 09:55

Обратной стороной JBCO является то, что это качественный исследовательский код. Я даже не могу заставить его работать на простых тестовых примерах, а документации практически не существует.

Antimony 24.10.2012 00:53

Я бы добавил еще одну мысль ... если это действительно результат «простого цикла», то он платит высокую цену за эффективность в обмен на то, чтобы сделать реверсивный код неразборчивым и неясным.

Lawrence Dol 10.01.2017 06:07

Я использую ProGuard и очень рекомендую его. Хотя обфускация действительно защищает ваш код от случайных злоумышленников, ее основным преимуществом является минимизирующий эффект удаления неиспользуемых классов и методов и сокращения всех идентификаторов до 1 или 2 символов.

Мне было интересно, вы когда-нибудь запутывали код, который широко использует отражение? Были ли у вас проблемы?

Cratylus 13.04.2012 12:06

@ user384706: Да, я использую ProGuard с кодом, который широко использует отражение. Вы должны настроить его для сохранения отраженных элементов, за исключением простого использования Class.forName().

Lawrence Dol 13.04.2012 23:12

Я думаю, что по большей части обфускация бессмысленна: даже с полным исходным кодом, как правило, достаточно сложно понять, что это было за чертовски намерение (при условии, что нет комментариев и нет значимых имен для локальных переменных - что имеет место, когда re -генерация исходников из байт-кода). Обфускация просто украшает торт.

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

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

В настоящее время главное - не защищать некоторые алгоритмы, а защищать конфиденциальные данные: логины / пароли / ключи API, код, отвечающий за лицензирование (пиратство все еще здесь, особенно Западная Европа, Россия, Азия, IMHO), идентификаторы рекламных аккаунтов и т. д.

Интересный факт: все эти конфиденциальные данные хранятся в строках. На самом деле Strings - это примерно 50-80% логики наших приложений. Мне кажется, будущее обфускации - это «инструменты шифрования строк».

Но теперь функция «Шифрование строк» ​​доступна только в коммерческих обфускаторах, таких как: Аллатори, Зеликс КлассМастер, Дымовая завеса, Набор инструментов для обфускации Java Stringer, DashO.

N.B. Я генеральный директор Licel LLC. Разработчик Stringer Java Obfuscator.

Это очень верно. В наши дни существует так много проектов с открытым исходным кодом, что никого не волнует коммерческий исходный код других людей. Главное - защитить некоторую (небольшую) конкретную информацию, такую ​​как ЧАСТНЫЕ КЛЮЧИ и ПАРОЛИ.

marcolopes 09.03.2014 21:06

Другие вопросы по теме