Ресурсы для декомпиляции x86 - PullRequest
1 голос
/ 08 июля 2010

Я бы хотел получить четкое представление о низкоуровневом процессе представления и запуска программы. Я решил сделать это, написав программу для анализа и отображения информации об объектных файлах (заголовки, разделы и т. Д.). Я почти закончил эту часть. Естественным расширением является декомпиляция оставшихся соответствующих данных в инструкции по сборке. Сначала я сосредоточусь на x86.

Где я могу найти ресурсы, связанные с этой декомпиляцией (двоичный файл -> ASM)? Я читал, что x86 имеет однозначное соответствие с ASM, хотя я не знаю лучшего источника, из которого можно получить таблицы перевода.

Кроме того, пока я занимаюсь этим, мне будет интересно отслеживать любую предоставленную отладочную информацию. Есть ли ссылки на формат, используемый для этой информации (допустим, ELF и GCC с опцией -g)?

У кого-нибудь из вас есть общие советы? Цель здесь - практический проект, чтобы улучшить мое понимание.

Ответы [ 3 ]

1 голос
/ 14 июля 2010

Вы можете найти тщательно документированный дизассемблер Python для 8086 по адресу google-code: http://code.google.com/p/dasm3/

1 голос
/ 02 октября 2010

x86 - переменная длина команды, что означает, что ее очень трудно разобрать. Не рекомендуется, если это ваш первый дизассемблер.

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

Как вы узнаете коды операций из других байтов? Вам нужно пройти все возможные пути выполнения, звучит как проблема рекурсии, и может быть, но это не обязательно. Посмотрите на таблицу векторов прерываний и / или все аппаратные точки входа в код. Это дает вам короткий список байтов кода операции. Подход без рекурсии состоит в том, чтобы сделать много проходов по двоичному файлу, просматривая каждый байт, помеченный как код операции, декодировать его настолько, чтобы узнать, сколько он потребляет байтов. Вам также необходимо знать, является ли это безусловной ветвью, условной ветвью, возвратом, вызовом и т. Д. Если это не безусловная ветвь или возврат, вы можете предположить, что байт после этой инструкции является первым байтом следующей инструкции. Каждый раз, когда вы сталкиваетесь с ответвлением или каким-либо вызовом, вычислите адрес назначения, добавьте этот байт в список. Продолжайте делать проходы, пока вы не сделаете проход, который не добавляет новых байтов в список. Вы также должны убедиться, что если, скажем, вы нашли байт, который является 3-х байтовой инструкцией, но байт после того, как он помечен как инструкция, то у вас есть проблема. Такие вещи, как условные ветви, которым предшествует то, что гарантирует, что они никогда не будут ветвиться. Вы не увидите этого много, если вообще с высокоуровневым кодом, скомпилированным в двоичный файл, но старые добрые времена написанного вручную ассемблера или люди, которые хотят защитить свой код, будут делать такие вещи.

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

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

Я не удивлюсь, если где-нибудь в эльфе будет что-то, что указывает, какие части двоичного файла являются исполняемыми, а какие - данными. может быть, даже настолько, что вам не нужно проходить пути данных, я сомневаюсь, что objdump выполняет такую ​​задачу, что он, вероятно, использует что-то в файле elf.

Формат файла elf задокументирован во многих местах. Существует базовая структура, и поставщики могут добавлять определенные типы блоков, которые будут задокументированы поставщиком.

1 голос
/ 08 июля 2010

Посмотрите учебник по моей виртуальной машине: http://www.icemanind.com

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

...