Есть ли примеры кода, который трудно декомпилировать? - PullRequest
3 голосов
/ 20 июля 2009

Иногда при декомпиляции Java-кода декомпилятору не удается правильно декомпилировать его, и в результате вы получаете небольшие биты байт-кода в выводе.

Каковы недостатки декомпиляторов? Есть ли примеры исходного кода Java, который компилируется в сложный для декомпиляции байт-код?

Обновление:

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

Тем не менее мне все еще интересно выяснить, какой код лисицы сегодня используют для декомпиляции.

Ответы [ 6 ]

3 голосов
/ 20 июля 2009

Драйверы JDBC типа 4 для DB2 Connect - это классика. Все называется одно- или двухбуквенными именами, нерелевантным кодом, который в итоге не имеет никакого эффекта, и многим другим. Однажды я попытался взглянуть, чтобы отладить особо неприятную проблему, и в основном сдался. Я надеюсь (но отнюдь не уверен), что это было передано через обфускатор, а не код, который на самом деле выглядит так.

Еще одна любимая уловка (хотя я не могу вспомнить продукт) - переименовать все объекты, которые должны быть сконструированы из набора {'0','O','l','1'}, что затрудняло его чтение.

3 голосов
/ 20 июля 2009

Любой байт-код Java, прошедший через обфускатор, будет иметь «нелепый» вывод из декомпилятора. Кроме того, если у вас есть другие языки, такие как Scala, которые компилируются в байт-код JVM, нет правила, что байт-код можно легко представить обратно в Java и, скорее всего, нет.

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

Редактировать: в качестве примера в .NET, следующий код:

lock (this)
{
    DoSomething();
}

компилируется в это:

Monitor.Enter(this);
try
{
    DoSomething();
}
catch
{
    Monitor.Exit(this);
}

Декомпилятор должен знать, что C # (в отличие от любого другого языка .NET) имеет специальный синтаксис, предназначенный именно для этих двух вызовов. В противном случае вы получите неожиданные (подробные) результаты.

2 голосов
/ 04 сентября 2009

Предполагая, что вы можете декомпилировать обратно к разумному стилю исходного кода (вы не всегда можете это сделать), то, что трудно "реконструировать", - это алгоритмы, которые работают в незнакомых проблемных областях. Если вы не понимаете быстрых преобразований Фурье, не имеет большого значения, сможете ли вы вернуть код, который реализует FFT Butterfly. (Если эта фраза вам незнакома, я уже выиграл, если закодировал ее. Если она знакома , вы довольно хороший инженер и, вероятно, не интересуетесь кодом обратного инжиниринга. ). [Ваш пробег с северокорейцами может отличаться.]

0 голосов
/ 20 июля 2009

Java-байт-код не соответствует напрямую Java-конструкциям, поэтому декомпиляция подразумевает, что вы знаете, что определенная последовательность Java-байт-кода соответствует конструкции Java-кода.

Платформа Soot для декомпиляции Java-байтового кода содержит много информации по этому вопросу, но их веб-страница сейчас недоступна для меня.

http://www.sable.mcgill.ca/soot/

0 голосов
/ 20 июля 2009

Исключения часто трудно декомпилировать. Однако любой код, который был запутан или написан на другом языке, трудно декомпилировать.

Кстати: с чего бы вам это знать?

0 голосов
/ 20 июля 2009

Java хранит много информации в байт-коде (например, много имен). Так что относительно легко декомпилировать. Трудно декомпилировать байт-код, в основном, генерируется трудно читаемым исходным кодом (так что на самом деле это не вариант). Если вы действительно хотите запутать свой код, используйте обфускатор, который переименовывает все методы и переменные в неузнаваемые вещи.

...