Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие 50072.doc
Скачиваний:
5
Добавлен:
30.04.2022
Размер:
1.46 Mб
Скачать

1.2. Методы и средства структурного обнаружения потенциально опасных фрагментов унитарного кода

Анализ исполняемого кода проводится в несколько этапов.

На первом этапе выполняется исследование заголовков двоичного исполняемого модуля и его дизассемблирование. Анализ заголовков исполняемого модуля и извлечение из них информации о секциях кода, инициализированных или неинициализированных данных представляет собой тривиальную задачу. Единственная особенность заключается в том, что инструментарий должен быть оснащен модулями разбора заголовков для всех известных форматов исполняемых модулей. Для ОС Windows это DOS EXE, Win16 EXE (NE), VxD (LE), Win32 (PE). Для ОС Linux - a.out и ELF.

Второй этап анализа - дизассемблирование кода. Под дизассемблированием понимается восстановление ассемблерного текста программы по ее исполняемому (двоичному) коду.

1.2.1. Метод неинтеллектуального дизассемблирования

В состав любого дизассемблера обычно входят (рис. 1.1):

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

  • управляющую часть, которая определяет адрес очередной ассемблерной команды, которая будет распознаваться;

  • конечные автоматы-распознаватели отдельных ассемблерных команд, которые извлекают из памяти по адресу последовательность байт, выделяют из нее одну ассемблерную команду и вычисляют ее размер.

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

Рис. 1.1. Структура классического дизассемблера

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