Есть ли примеры кода, который сложно декомпилировать?

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

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

Обновление:

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

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


person izb    schedule 20.07.2009    source источник


Ответы (6)


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

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

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

lock (this)
{
    DoSomething();
}

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

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

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

person Sam Harwell    schedule 20.07.2009

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

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

person paxdiablo    schedule 20.07.2009
comment
Я не знаком с вашей системой обозначений. Можете ли вы подробнее рассказать об этом? - person ojblass; 20.07.2009
comment
Я думаю, он просто имел в виду, что алфавит, используемый для именования всех объектов, методов, переменных и т. Д., Использовал только те символы, которые трудно читать и которые выглядят одинаково в некоторых гарнитурах. - person Coxy; 20.07.2009
comment
Да, такие имена, как O01ll10, O01l1l0, OO1ll10 и O0l1l1O, очень затрудняют чтение (и делают имена довольно бесполезными с точки зрения понимания того, что они делают). - person paxdiablo; 20.07.2009

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

person Ira Baxter    schedule 04.09.2009

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

person Mnementh    schedule 20.07.2009

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

BTW: Зачем вам это знать?

person Peter Lawrey    schedule 20.07.2009

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

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

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

person Thorbjørn Ravn Andersen    schedule 20.07.2009