Перекрестные ссылки и построение графа



 

Некоторыми из большого количества общих вопросов, кроме вопросов о реверсивном проектировании двоичных файлов, являются "Откуда эта функция вызвана?" и "Какие функции получают доступ к этим данным?"

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

 

Перекрестные ссылки

Начиная наше обсуждение, заметим, что перекрестные ссылки в пределах IDA часто упоминаются просто как xrefs. В пределах этого текста мы будем использовать xref только там, где это нужно, чтобы обратиться к пункту меню IDA или диалогового окна. Во всех других случаях мы будем придерживаться термина перекрестная ссылка.

Есть две основных категории перекрестных ссылок в IDA: перекрестные ссылки на код и перекрестные ссылки на данные. В каждой категории мы описываем несколько различных типов перекрестных ссылок. С каждой перекрестной ссылкой связано определенное направление. Все перекрестные ссылки совершают переход от одного адреса к другому. Это могут быть адреса кода или данных.

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

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

Обычный переход - самый простой тип перехода, и представляет собой переход от одной инструкции к другой. Это стандартный переход для всех инструкций, не являющихся командами.

Инструкции, используемые, чтобы вызвать функции, относятся к переходам типа вызова, указывая на передачу управления к целевой функции. В большинстве случаев обычный переход также принадлежит к числу команд вызова, поскольку большинство функций возвращается в место, которое следует за вызовом. Если IDA знает, что функция не возвращает значение, то вызовы этой функции не будут иметь обычный переход.

Прыжок присваивается каждой команде безусловного перехода и команде условного перехода. Условным переходам также присвоены обычные переходы, чтобы управлять переходом по ссылке, когда ответвлений нет. У безусловных переходов нет никакого связанного обычного перехода, потому что в таких случаях всегда берется ответвление. Перекрестные ссылки перехода выводят на экран адрес первоначального расположения (источник перехода). Перекрестные ссылки перехода отличают при помощи суффикса j (J как Jump).

Перекрестные ссылки на данные. Перекрестные ссылки данных используются, чтобы отследить способ получения доступа к данным в пределах двоичного файла. Перекрестные ссылки данных могут быть связаны с любым байтом в базе данных IDA, который связан с виртуальным адресом (другими словами, перекрестные ссылки данных никогда не связываются с переменными стека). Чтобы указать место, откуда считываем, место, куда записываем и адрес расположения объекта, используются три типа перекрестных ссылок данных.

Считывающая перекрестная ссылка используется, чтобы указать, что к содержанию ячейки памяти получают доступ. Считывающие перекрестные ссылки могут выполниться только из адреса команды, но могут обратиться к любому месту программы. Для обозначения считывающей перекрестной ссылки используется суффикс r.

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

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

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

Есть два метода для того, чтобы просмотреть полный список перекрестных ссылок на место. Первый метод - открытие окна перекрестных ссылок, связанных с определенным адресом. Наведя курсор на адрес, который является целью одной или более перекрестных ссылок, выбрать View ► Open Subviews ► Cross-References, Вы можете открыть полный список перекрестных ссылок на данную область

Второй способ получить доступ к списку перекрестных ссылок состоит в том, чтобы щелкнуть правой кнопкой по имени, и выбрать Переход к xref к операнду (горячая клавиша X), чтобы открыть диалоговое окно, которое перечисляет каждое место, которое ссылается на выбранный символ.

Вызовы функций. Специализированный список перекрестных ссылок, имеющий дело исключительно с вызовами функции, доступен, если выбрать View ► Open Subviews ► Function Calls.

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

 

Графы

 

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

 

Построение графа IDA путем наследования

Возможность построения графа наследования IDA доступна в Windows и обеспечена связанным приложением, названным wingraph32. Всякий раз, когда граф наследования требует, источник для графа генерируется и сохраняется во временном файле, когда wingraph32 запущен, чтобы вывести на экран граф. Как только граф был загружен в память, wingraph32 сразу удаляет связанный временный файл графа; однако, Вы можете сохранить выведенный на экран граф, используя wingraph32's File ► Save as. Сгенерированные файлы графа используют Graph Description Language (GDL), чтобы определять графи. Доступные графы наследования включают следующее:

− Функциональная блок-схема.

− Вызов графа для всего двоичного файла.

− Граф перекрестных ссылок на символ.

− Граф перекрестных ссылок от символа.

− Специализированный граф перекрестной ссылки.

Существует много ограничений при контакте с любым графом наследования. Прежде всего, учтем, что графы наследования не являются интерактивными. Манипулирование выведенными на экран графами наследования по существу ограничено изменением масштаба и панорамированием. Невозможно отредактировать граф и управлять контентом дизассемблирования, как Вы привыкли это делать при использовании дизассемблирования IDA или интегрировании представления графа.

Блок-схемы наследования. Когда курсор в пределах функции, нажатие View ► Graphs ► Flow Chart (горячая клавиша F12) генерирует и выводит на экран блок-схему стиля наследования. Эти графы лучше назвать графами потока управления, поскольку они группируют инструкции функции в базовые блоки и используют ребра, чтобы указать, как один блок переходит к другому.

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

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

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

После компиляции динамически соединенного файла с использованием GNU gcc, мы можем попросить IDA сгенерировать граф вызова функции, используя View ► Graphs ► Function Calls.

Графы наследования перекрестной ссылки. Два типа графов перекрестной ссылки могут быть сгенерированы для глобальных символов (функции или глобальные переменные): перекрестные ссылки на символ (View ► Graphs ► Xrefs To) и перекрестные ссылки от символа (View ► Graphs ► Xrefs From).

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

Пользовательские Графы перекрестных ссылок. Пользовательские графы перекрестной ссылки, названные User xref charts в IDA, обеспечивают максимальную гибкость в генерировании графов перекрестной ссылки, чтобы удовлетворить Вашим потребностям. В дополнение к объединению перекрестных ссылок на символ и перекрестных ссылок от символа в единственный граф, пользовательские графы перекрестной ссылки позволяют Вам определять максимальную глубину рекурсии и типы символов, которые должны быть включены или исключены из получающегося графа.

− Начальное направление позволяет Вам решать, искать ли перекрестные ссылки от выбранного символа к выбранному символу, или обоим.

− Параметры. Опция Recursive включает рекурсивный спуск (xrefs To) или подъем (xrefs From) от выбранных символов. Следование только в текущем направлении вынуждает любую рекурсию пройти только в одну сторону.

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

− Проигнорировать. Эта опция диктует, какие типы узлов будут исключены из сгенерированного графа.

− Опции печати управляют двумя аспектами форматирования графа. Комментарии печати заставляют любые функциональные комментарии быть включенными в узел графа функции.

 


Дата добавления: 2018-06-27; просмотров: 869; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!