В поисках хорошего способа определить правила для декомпилятора, нужен совет

Я работаю над очень простым декомпилятором для архитектуры MIPS, и по мере продвижения мне приходится определять множество правил для анализа кода, например, «если этот код операции lui, а следующий код операции addiu< /em>, затем верните var = value" или "если этот код операции bne и ссылается на адрес перед текущим - создайте определение цикла при синтаксическом анализе дерево". Проблема в том, что таких правил множество, и я не могу найти хороший способ их определить. Я пытался писать отдельные функции для каждого правила, определяя хорошие классы базовой логики ООП и расширяя их для создания правил, даже пробовал использовать регулярные выражения в дизассемблированном коде (к моему удивлению, это работает лучше, чем ожидалось), но независимо от того, что я пробовал, мой код вскоре стал слишком большим и трудным для чтения, независимо от того, насколько хорошо я пытаюсь его документировать и структурировать.

Это подводит меня к выводу, что я пытаюсь решить эту задачу, используя неправильные инструменты (не говоря уже о том, что я слишком глуп для такой сложной задачи :)), но я понятия не имею, что мне попробовать. В настоящее время у меня есть две непроверенные идеи: одна использует какой-то DSL (у меня нет абсолютно никакого опыта в этом, поэтому я могу ошибаться), а другая — написание каких-то бинарных инструментов, подобных регулярным выражениям, для сопоставления кодов операций.

Я надеюсь, что кто-то может указать мне правильное направление, спасибо.


person Riz    schedule 25.07.2010    source источник
comment
Я не думаю, что возможно написать декомпилятор, просто глядя на шаблоны инструкций. Поток кода и анализ данных необходимы для правильного построения блоков кода и выражений.   -  person Vladimir Panteleev    schedule 26.07.2010
comment
Наблюдение за шаблоном кода операции AFAIK - это способ получить поток кода, как в моем втором примере (вы найдете код операции bne, который ссылается на адрес перед собой = это цикл), но вы правы, что это только один из шагов, как я нужно рассчитать условие для этого цикла, а это значит, что мне нужно посмотреть код до и проверить изменения в памяти\регистрах. Итак, это двухпроходный анализ - сначала строим дерево потока, затем вычисляем все внутри.   -  person Riz    schedule 26.07.2010
comment
Метод двоичных регулярных выражений на самом деле звучит как довольно хорошая идея. Единственное, что я могу придумать, это написать интерфейс MIPS для LLVM и использовать серверную часть C для получения кода (хотя я понятия не имею, насколько читабельным будет сгенерированный код, например, он может использовать gotos для циклов и перерабатывать переменные , так далее.)   -  person Zifre    schedule 28.07.2010
comment
Спасибо за предложение, я обязательно попробую LLVM, но я боюсь, что он будет создавать код, не зная внутренностей MIPS и точного оборудования, которое иногда может помочь в получении дополнительной информации. Я сейчас тестирую подход DSL, пытаясь скопировать способ декомпиляции кода на бумаге. :) И спасибо за исправление тегов.   -  person Riz    schedule 28.07.2010


Ответы (1)


Я предполагаю, что некоторые из ваших правил слишком низкоуровневые, и поэтому они становятся неуправляемыми.

Распознавание lui, за которым следует addiu, как 32-битной постоянной загрузки, безусловно, кажется очень разумным; но попытка получить поток управления из инструкций ветвления на уровне отдельного кода операции кажется более подозрительной - я думаю, вы хотите работать там с базовыми блоками.

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

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

person Matthew Slattery    schedule 28.07.2010
comment
Боже мой, это отличный источник статей, которые хуже читаются, я не могу выразить, насколько я благодарен (пожалуйста, не спрашивайте меня, как я мог пропустить это :) ) - person Riz; 29.07.2010