Отказоустойчивый способ обхода байт-кода JVM до текстового представления и обратно - PullRequest
3 голосов
/ 20 сентября 2009

Я ищу отказоустойчивый способ обхода между файлом класса JVM и текстовым представлением и обратно.

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

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

Самое простое решение - использовать декомпилятор Java, такой как JAD, для генерации текстового представления, которое в этом случае будет просто воссозданным исходным кодом Java. А затем используйте javac для генерации байт-кода. Однако, учитывая состояние свободных Java-декомпиляторов, этот подход не работает при любых обстоятельствах. Довольно просто создать обфусцированный байт-код, который не сохраняется в полном циклическом файле классов / java-source / class-file (отчасти потому, что просто отсутствует отображение 1: 1 между байт-кодом JVM и Исходный код Java).

Существует ли отказоустойчивый способ выполнения циклического переключения файла класса JVM / представления текста / файла класса с учетом приведенных выше требований?

Обновление: Перед ответом - сэкономьте время и усилия, ознакомившись со всеми приведенными выше требованиями и особо отметив:

  • «Текстовое представление байт-кода JVM» не обязательно означает «исходный код Java».

Ответы [ 5 ]

6 голосов
/ 23 сентября 2009

Проект BCEL предоставляет JasminVisitor , который преобразует файлы классов в jasmin сборку.

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

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

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

Жасмин и Кимера?

1 голос
/ 03 марта 2013

Я написал инструмент, предназначенный именно для этого.

Кракатау дизассемблер и ассемблер предназначен для обработки любого допустимого файла класса, независимо от того, насколько он причудлив. Он использует формат сборки, основанный на формате Jasmin, но расширен для поддержки всех функций файла классов, которые Jasmin не может обработать. Он даже поддерживает некоторые неясные или недокументированные «возможности» Hotspot, такие как предварительно 45.3 файлы классов, использующие меньшую ширину для полей атрибута кода.

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

Обновление: Krakatau теперь поддерживает точную двоичную обработку файлов классов. Передача флага -roundtrip сохранит порядок записей в постоянном пуле и т. Д.

1 голос
/ 16 сентября 2011

Похоже, ASM делает это. (Это тот же ответ, что и у ShuggyCoUk, но с другим инструментом.) Jarjar говорит, что он использует ASM именно для того, о чем вы говорите.

0 голосов
/ 20 сентября 2009

Нет. Существует допустимый байт-код без соответствующей Java-программы.

Проект Soot имеет довольно сложный декомпилятор - http://www.sable.mcgill.ca/dava/ - который может быть полезен для тех байтовых кодов, поступающих из компилятора Java. Это, однако, не идеально.

Ваша лучшая ставка по-прежнему получить исходный код для файлов классов.

...