Построение графика потока управления с использованием результатов из Objdump - PullRequest
9 голосов
/ 25 ноября 2010

Я пытаюсь построить контрольный граф результатов сборки, которые возвращаются через вызов objdump -d. В настоящее время лучший метод, который я придумал, состоит в том, чтобы поместить каждую строку результата в связанный список и выделить адрес памяти, код операции и операнды для каждой строки. Я разделяю их, полагаясь на обычную природу результатов objdump (адрес памяти - от символа 2 до символа 7 в строке, представляющей каждую строку).

Как только это будет сделано, я запускаю собственно инструкцию CFG. Каждый узел в CFG содержит начальный и конечный адрес памяти, указатель на предыдущий базовый блок и указатели на любые дочерние базовые блоки. Затем я просматриваю результаты objdump и сравниваю код операции с массивом всех кодов операций потока управления в x86_64. Если код операции является управляющим потоком, я записываю адрес как конец основного блока и в зависимости от кода операции добавляю два дочерних указателя (условный код операции) или один (вызов или возврат).

Я нахожусь в процессе реализации этого в C, и кажется, что это будет работать, но чувствует себя очень незначительным. У кого-нибудь есть предложения или что-то, что я не принимаю во внимание?

Спасибо, что нашли время, чтобы прочитать это!

редактирование:

Идея состоит в том, чтобы использовать его для сравнения стековых трассировок системных вызовов, генерируемых DynamoRIO, с ожидаемым CFG для целевого бинарного файла. Я надеюсь, что его создание будет способствовать этому. Я не использовал повторно то, что доступно, потому что A) я действительно не думал об этом, и B) мне нужно поместить график в пригодную для использования структуру данных, чтобы я мог проводить сравнения путей. Я собираюсь взглянуть на некоторые утилиты на странице, на которую вы ссылались, спасибо, что указали мне правильное направление. Спасибо за ваши комментарии, я действительно ценю это!

Ответы [ 2 ]

3 голосов
/ 13 сентября 2011

Вы должны использовать IL, который был разработан для анализа программы. Есть несколько.

В проекте DynInst (dyninst.org) есть лифт, который может преобразовывать двоичные файлы ELF в CFG для функций / программ (или это было в последний раз, когда я смотрел). DynInst написан на C ++.

BinNavi использует выходные данные IDA (интерактивный дизассемблер) для создания IL-кода из потоковых графов управления, которые IDA идентифицирует. Я также рекомендовал бы копию IDA, она позволит вам визуально проверить CFGs. Как только у вас есть программа в BinNavi, вы можете получить ее IL-представление функции / CFG.

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

Удачи! Вы уже получаете много информации из трассировки DynamoRIO, я предлагаю вам использовать как можно больше информации из этой трассировки ...

0 голосов
/ 02 ноября 2015

Я нашел ваш вопрос, так как мне было интересно искать то же самое. Я ничего не нашел, написал для этого простой скрипт на python и бросил его на github: https://github.com/zestrada/playground/blob/master/objdump_cfg/objdump_to_cfg.py

Обратите внимание, что у меня есть некоторые эвристики для работы с функциями, которые никогда не возвращаются, защита стека gcc на 32-битной x86 и т. Д. Вы можете или не можете хотеть такие вещи.

Я отношусь к косвенным вызовам аналогично тому, как вы это делаете (в основном есть узел на графике, который является источником при возврате из косвенного).

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

...