Ноутбуки   
   Софт   
   Компьютеры   
   Компьютерные фирмы   
  Меню сайта

BIOS

SSD-накопители

Акустика для ПК

Видеокарты

Видеокарты - История

Джойстики, клавиатуры и мыши

Дигитайзеры

Жесткие диски

Жесткие диски - история

Звуковые карты

Именитые люди компьютерной индустрии

История компьютеров

Карманные компьютеры

Компьютер десктоп - готовая сборка

Компьютерные фирмы

Компьютеры в теории и практике

Копировальные аппараты

Корпуса, вентиляторы, блоки питания

Маршрутизаторы, коммутаторы, хабы

Материнские платы

Модемы

Модули памяти

Мониторы

Мониторы и видеокарты - история

Новости

Ноутбуки и субноутбуки

Оборудование беспроводной связи, bluetooth, wi-fi

Оптические накопители CD, DVD, Blueray

Оргтехника

Память - история

Плоттеры

Принтеры

Процессоры

Процессоры - история

Сетевые карты

Сетевые фильтры, ИБП

Сети

Сканеры

Сменные жесткие диски

Советские ПК

ТВ-тюнеры

Типы компьютеров

Устройства архивации данных и стримеры

Факс

Флоппи-дисководы

Флэшки и всяко-разно

Шины и чипсеты - история




Главная страница Прайс-лист Интернет-магазин

Анализ содержимого ПЗУ - метод деассемблирования

Наш следующий шаг в решении задачи исследования содержимого ПЗУ и использования программы DEBUG состоит в знакомстве с особенностями процесса деассемблирования. Команда "U" программы DEBUG - означает "деассемблирование" - осущеcтвляет преобразование произвольных кодов памяти в мнемонические коды языка ассемблера. Деассемблер реализует: перевод абсолютных шестнадцатеричных кодов программ, в коды команд на языке ассемблера (например: AX или DS). Деассемблер не делает две вещи.
Первое. Деассемблер не интерпретирует смысл программы и не обучает пользователя. Для понимания листинга, выдаваемого деассемблером, необходимо либо знать язык ассемблера, либо иметь желание покопаться в справочном руководстве и, установив смысл мнемонических обозначений, постараться понять суть дела. (Для этой цели могут быть использованы следующие источники: "Руководство по языку ассемблера фирмы IBM", справочники по системе команд микропроцессора 8086/8088, такие как "Учебное пособие по микропроцессору 8086" С.Морса или "Описание микропроцессора 8086" Ректора и Алекси).
Для понимания программы на языке ассемблера (или программы, приведенной к языку ассемблера), знания одного языка Ассемблер недостаточно, необходимо также иметь некоторое представление о функциональной ориентации программы.
Постижение программы представляет собой занимательное умственное упражнение, своего рода головоломку. Со временем эта процедура становится все проще и проще, отчасти потому, что времени на поиск смыслового описания команды уходит все меньше и меньше, а отчасти потому, что усваиваются приемы программирования на ассемблере и способы достижения целей. Далее мы остановимся на этих вопросах более подробно.
Второе, что не под силу программе деассемблера - это установка так называемой абсолютной синхронизации. Известно, что команды машинного языка для микропроцессора INTEL 8086/8088 имеют переменную длину - от одного до шести байтов. После того как деассемблеру сообщена конкретная позиция памяти он приступает к процедуре прямого декодирования, не отличая кодов команд от данных. Достаточно ошибиться в выборе исходной позиции памяти (например, попасть не на границу между командами или в область данных) и результат окажется неверным.
Если начальная точка набора команд известна, то никаких проблем не возникает. Если какие-либо предварительные сведения отсутствуют, то следует провести необходимое исследование. Первое, что необходимо сделать - это выбрать исходную точку в наборе команд и запустить операцию деассемблирования. После этого следует предпринять попытку интерпретировать результат работы деассемблера. Если осмысленные программные участки отсутствуют (ниже мы приводим некоторые соображения по их выявлению),то следует повторить процедуру, сместив начальную точку на один, два или три байта по отношению к предыдущей попытке. Мы таким образом пытаемся отыскать точку синхронизации, расположенную на стыке двух команд, после чего может быть восстановлен оригинальный набор команд. Если очередная попытка закончилась неудачно, то следует попробовать еще раз.
Поскольку большинство команд имеют длину один или два байта, то точку синхронизации отыскать как правило несложно. Кроме того, необходимо учитывать, что процессу деассемблирования присущ элемент самосинхронизации. Даже если в качестве начальной точки для деассемблирования выбрана точка, расположенная внутри команды, то часто случается, что процесс деассемблирования при обработке последуюющих команд самопроизвольно попадает в нужную точку. После этого все идет гладко, по крайней мере в сторону увеличения адресов. (В обратную сторону это приходится делать вручную).
Выполняя деассемблирование программы необходимо внимательно следить за данными (это нечто противоположное командам), которые деассемблер превращает в причудливые ассемблерные конструкции. Основной и наиболее быстрый способ обнаружения данных состоит в использовании команды "D", для представления информации в шестнадцатеричном коде и коде ASCII. Здесь в первую очередь следует обращать внимание на самые очевидные вещи - содержательно осмысленную последовательность символов ASCII (фразы), такую, например, как "неверный вызов функции". После этого можно приступать к выявлению более тонких признаков данных.
В обычных программах (т.е. в программах, размещаемых вне ПЗУ) наличие полей, заполненных шестнадцатеричными нулями является признаком рабочей области данных, то есть такой области, которая будет использоваться в ходе выполнения программы; в процессе деассемблирования данные этой области неактуальны. ПЗУ не может использоваться для хранения рабочих данных, поскольку запись в эту память невозможна. Таким образом, наличие полей, состоящих из шестнадцатеричных нулей нетипично для ПЗУ-программ.
Признаком возможного наличия данных являются байты или двухбайтовые слова, для которых второй или старший байт содержит 0 или F. Дело в том, что значительное число констант программ являются малыми числами, положительными (т.е. начинающихся с 0), либо отрицательными (т.е. начинающихся с F). Если будет обнаружена последовательность байтов, удовлетворяющая этим требованиям, то весьма вероятно, что найдена область памяти, используемая для хранения одного или двухбайтовых чисел. Эта часть программы не может содержать команды.
Пытаясь осмыслить структуру листинга, выдаваемого деассемблером, необходимо иметь в виду следующие положения. Обычные программы, прошедшие этап редактирования связей, будут хранить команды в одном месте, а данные в другом. Такой подход является элементом хорошего стиля программирования; именно так работает редактор связей дисковой операционной системы. Описанный принцип характерен для программ всех типов, однако для программ типа EXE он справедлив в большей степени чем для программ типа COM. С другой стороны, ПЗУ-программы, подобные тем, которые рассматривались нами выше, часто разрабатываются вне концепций технологии программирования. Данные в этих программах могут следовать вперемешку с командами.
Если предположительно обнаружен участок программы, в котором вслед за командами следуют некоторые данные, то существует по крайней мере один достоверный способ отличить конец последовательности команд от расположенных вслед за ними данными, и таким образом избежать необходимости рассматривать недостоверный протокол деассемблирования. Последняя команда фактического участка программы должна представлять собой ту или иную разновидность команды перехода или ветвления. Команды ветвления включают любые команды переходов, кроме команд условных переходов. В качестве общеупотребительной команды завершения программы принято использовать команду возврата (RET) (возврат из вызванной ранее подпрограммы).
Могут использоваться также и команды CALL (Вызов) и INT (Прерывание); хотя их использование в качестве команды завершения последовательности команд встречается достаточно редко.
Существует ряд особенностей, на которые следует обращать внимание при решении вопроса подлинности предъявленного участка программы после его деассемблирования. В первую очередь следует обратить внимание на используемые регистры. Если операции реализуются на регистрах, используемых как правило для выполнения арифметических операций (AX или AL, AH;BX или BL, BH; CX или CL, CH; DX или DL, DH), но никакие действия в отношении результата не предпринимаются, то это вызывает подозрение. Здесь следует быть более внимательным. Один из результатов выполнения арифметических операций состоит в установке флагов - следовательно, естественно ожидать наличие команд условных переходов по состоянию флага, таких как JNC (команда перехода по условию отсутствия установленных битов флага).
Рассмотрим аспект некорректности использования регистров в реконструируемой программе. Программы не используют регистры некоторым хаотичным образом - им присуща определенная дисциплина. Поэтому весьма непривычно, скажем, видеть загрузку или непосредственную ссылку на сегментные регистры - особенно сегментный регистр программы (CS) и сегментный регистр стека памяти (SS). Загрузка сегмента регистра данных (DS) более вероятна, но также встречается редко. С другой стороны, дополнительный сегментный регистр (ES) практически постоянно используется программами, поэтому его загрузка - дело обычное. Если загрузка регистра CS или SS все-таки обнаружена, то это должно быть сделано в программной секции, формирующей операционную структуру выполняемой программы; в этом случае вероятнее всего, что в одном месте будет произведена загрузка нескольких сегментных регистров, в частности, CS, SS и DS.
Попытка реконструировать программу по листингу, выданному деассемблером или даже просто попытка убедиться в подлинности предъявленного набора команд, представляет собой захватывающее умственное упражнение. Для этого,кстати, не требуется специальная подготовка. Как правило, достаточно бывает просто здравого смысла. Усвоив все наши рекомендации и приобретя некоторые практические навыки, Вы, при необходимости, сможете все это проделать. В следующем параграфе мы выполним декодирование (реконструкцию) программы Бейсик-ПЗУ; читатель, таким образом, получит представление о том, как это делается и убедится в том, что это не очень сложно.


Анализ содержимого ПЗУ - метод деассемблирования

Анализ содержимого ПЗУ - реконструкция интерпретатора

Анализ содержимого ПЗУ средствами программы DEBUG

Две версии BIOSа

Дополнительные процедуры системы BIOS

Механизм выборки информации из ПЗУ

Описание специальных прерываний

Организация ПЗУ и его использование

Процедура обслуживания клавиатуры в системе BIOS

Система BIOS в ПЗУ

Служебные процедуры обслуживания дискет системы BIOS в ПЗУ

Средства управления видеотерминалом уровня BIOS-ПЗУ




Немного рекламы:


















































































Rambler's Top100