Pull to refresh

JBFD: декомпилятор из Brainfuck в Java

Reading time 2 min
Views 3.9K
Кто-то когда-то сказал: «Возьмите несколько произвольных латинских букв, допишите перед ними J, и вы получите очередную Java-технологию». В этой статье речь пойдет о технологии JBFD, что означает Java BrainFuck Decompiler. Технология еще достаточно молодая (от силы 3 часа), так что не судите строго.

Идея создания декомпилятора возникла не случайно. Всему виной большое количество статей по BrainFuck в Интернете вообще и на Хабре в частности. Интерпретаторов этого замечательного языка существует огромное множество, но вот средств для отладки BF кода мне удалось найти крайне мало.

А что если преобразовать код с BF на свой «родной» язык и воспользоваться всеми преимуществами своей любимой IDE для обнаружения трудноуловимых ошибок, покрытия кода тестами, оптимизации и т.д.? Все это и много другое становится возможным с JBFD.

Для нетерпеливых, ссылка на скачивание исходного кода декомпиляторя находится здесь — JBFD.java. Код работает на JDK версии 1.5 и выше.

После компиляции JBFD.java и запуска программы без аргументов получаем:

Usage: java JBFD <<filename>> <<options>>
Options:
	-p - just print cleaned up source code

Опция -p не является обязательной. Может кому-то будет полезно для валидации кода и выкидывания из исходников переводов строк и комментариев. При валидации пока что обнаруживаются только лишние или недостающие символы ']' и '['. В случае с лишним ']' еще указывается номер строки и символа в исходном файле.

Для примера попробуем декомпилировать простую echo.bf программу:

,+[-.,+]

После выполнения команды 'java JBFD echo.bf' в текущей папке появится файл echo.bf.java со следующим содержимым:

class Program {
    static class FuckedByte {
        char value;

        FuckedByte(int value) {
            this.value = (char) value;
        }

        char get() { return value; }

        void inc(int i) {
            value += i;
            value %= 256;
        }
        void dec(int i) {
            value -= i;
            value %= 256;
            if (value < 0)
                value += 256;
        }

        static FuckedByte read() {
            try {
                return new FuckedByte(System.in.read());
            } catch (Exception e) {
                throw new RuntimeException("Error reading from System.in");
            }
        }
        void write() {
            System.out.print(value);
        }
    }

    public static void main(String[] args) {
        FuckedByte fb0 = new FuckedByte(0);

        fb0 = FuckedByte.read();
        fb0.inc(1);
        while (fb0.get() != 0) {
            fb0.dec(1);
            fb0.write();
            fb0 = FuckedByte.read();
            fb0.inc(1);
        }

    }
}


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

Декомпилятор тестировался пока что только на самых простых программах типа echo, hello world и т.д. Код декомпилятора писался на скорую руку и будет дорабатываться. Тем не менее уже сейчас буду благодарен за любые замечания и предложения по улучшению.

Всем удачи.
Tags:
Hubs:
+6
Comments 10
Comments Comments 10

Articles