Търся добър начин за дефиниране на правила за декомпилатора, имам нужда от съвет

Работя върху много прост декомпилатор за MIPS архитектура и докато напредвам, трябва да дефинирам много правила за анализ на кода, например „ако този код на операция е lui и следващият код на операция е addiu< /em> след това връща var = value" или "ако този код на операцията е bne и се отнася за адрес преди текущия - създайте дефиниция на loop при анализиране дърво". Проблемът - има тонове такива правила и не мога да намеря добър начин да ги дефинирам. Опитах се да напиша отделни функции за всяко правило, да дефинирам хубави OOP базови логически класове и да ги разширя, за да създавам правила, дори опитах регулярни изрази върху разглобен код (за моя изненада това работи по-добре от очакваното), но независимо от това, което опитах, кодът ми скоро стана твърде голям и труден за четене, без значение колко добре се опитвам да го документирам и структурирам.

Това ме навежда на заключението, че се опитвам да реша тази задача с помощта на грешни инструменти (да не говорим, че съм твърде глупав за такава сложна задача :) ), но нямам реална идея какво да опитам. В момента имам две непроверени идеи, едната е да използвам някакъв вид DSL (нямам абсолютно никакъв опит в това, така че може да греша напълно), а другата е да напиша някакъв вид инструменти, подобни на бинарен regexp, за съвпадение на код на операция.

Надявам се, че някой може да ме насочи в правилната посока, благодаря.


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
Методът на двоичен regex всъщност звучи като доста добра идея. Единственото друго нещо, за което мога да се сетя, е да напиша интерфейс на 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