Изобретаем жесткий диск. В поисках сегмента данных. Часть 12.

В этом посте продолжение разбора микропрограммы жесткого диска WD21000. Этот жесткий диск выбран для демонстрации повторения платы электроники на современной элементной базе. Чтобы это сделать нужно подробнейшим образом разобрать его программу управления в дизассемблере IDA.

Так что продолжаем разбор программ.

В прошлый раз мы смотрели команду 0xEC. Вот она:

073_pic01

И сейчас интересно вот что посмотреть… У жесткого диска есть микросхема ОЗУ непосредственно подключенная к процессору. В этой микросхеме расположен сегмент данных, а также явно какой-то оверлей. Вот обращения к нему просматриваются в коде:

073_pic02

Хорошо бы понять, что именно это за оверлей и считать его из оперативной памяти.

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

Автор предположил, что выдача данных наружу командой чтения будет производиться при помощи той же самой функции, что и в комане 0xЕС. То есть, команда 0xЕС один сектор отдает и, соответственно, эта предполагаемая технологическая команда, скорее всего, отдает данные в через ту же функцию. Нужно эту гипотезу проверить.

Если присмотреться, то вот эта функция из команды 0xEC, возвращает АТА сектора хосту принимает два параметра ВХ и АХ.

073_pic03

В АХ здесь передаются просто нули, а в ВХ передается размер — 0x200 шестнадцатиричных байт или 512 байт. То есть, фактически, эта функция возвращает один сектор.

073_pic04

Давайте посмотрим список всех ссылок на на вызов этой функции, который открывается при нажатии клавиши «x».

073_pic05

Нам нужно сделать обзор всех этих мест.

Начнем с первой. Смотрим ее.

073_pic06

Здесь видно тоже, что возвращается один сектор. Листаем вверх, чтобы посмотреть что это может быть за команда. Это команда 0xАD.

073_pic07

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

073_pic08

Что за команда 0xАD мы пока не будем изучать, видно, что она формирует один сектор и его возвращает. Идем по второй ссылке. Открывается тоже какая-то команда — 0xЕ9.

073_pic09

Это, по всей видимости, стандартная команда и она не технологическая, скорее всего в ней ничего интересного.

Посмотрим третью ссылку.

Это у нас стандартная команда Е4 — читать/писать сектор.

073_pic10

Четвертая ссылка — команда ЕС.

По пятой ссылке находится уже более интересная команда.

073_pic11

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

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

Смотрим шестую ссылку.

073_pic12

А вот здесь интересно.

Здесь несмотря на то, что в АХ передается ноль, в этом месте используются сразу 4 байта из АТА команды, передаваемой из компьютера. Это 4й и 5й регистр, то есть младший цилиндр и старший цилиндр, 2й и 3й — количество секторов и номер сектора. При этом видно, что они идут парами и образуют два шестнадцатиразрядных параметра в функцию sx_ret_ATA_sectors.

073_pic13

Причем здесь интересно, что количество (регистр ЕВХ) по функции and объединяется с FFFE потому, что это 16-битная операция. Получается, что функция sx_ret_ATA_sectors может отдавать только слова. То есть байты она не может отдавать потому, что младший бит количества будет всегда ноль.

Теперь интересно, а что это за команда такая. Видно, что есть два варианта ее вызова в зависимости от 7го бита регистра СХ.

073_pic14

Если он сброшен, то идем по ветке loc_8808.

073_pic15

По ней выполняется какой-то цикл копирования.

073_pic16

Смотрим дальше. У нас есть точка входа в команду loc_87F6 .

073_pic17

Смотрим куда она нас ведет. Фактически это команда Е1.

073_pic18

При этом, если сброшен бит 6, то мы попадаем сразу не в ту точку входа, по которой мы только что пошли, а в еще одну — loc_87EA.

073_pic19

В этот кусочек всего две точки входа. Если в первой точке входа значение первого регистра 0 (это регистр feature, в спецификации называется set features) и в ЕАХ мы загрузили значение этого же регистра и убрали у него два старших бита.

073_pic20

В команде loc_87F6 очищается ЕСХ, ему передается 0, это означает, что вот эта ветка

073_pic14

пойдет через вот эту функцию

073_pic15

В команде loc_87EA мы помним, что в АХ лежит АТА регистр+1. Здесь мы его сравниваем с единичкой

073_pic21

если значение больше 1 мы перепрыгиваем сюда

073_pic22

То есть сразу на выход идем — lc_factory_exit. Это означает, что у нас в этом регистре может быть только 0 или 1. Соответственно, если равно единице, то мы идем вот сюда

073_pic23

по второй ветке.

073_pic24

Но там много всего происходит, пока не будем смотреть.

Если же равно 0, то идем по первой ветке, которая продолжается где loc_87F6. В ЕВХ полностью загружаются 2й, 3й, 4й, 5й регистры. Так как

ЕСХ здесь очищен и обнулен, соответственно, то мы всегда будем выполнять функцию sub_512А.

073_pic14

А здесь видно, что у нас ЕАХ и ЕВХ как параметры этой функции используются. То есть достаточно плотно это все происходит. Скорее всего эта функция sub_512А что-то копирует. Собственно у нас есть одна очень подходящая функция на то, что нам нужно.

Давайте посмотрим другие вызовы. Смотрим седьмую ссылку.

073_pic25

Здесь не очень похоже что идет работа с АТА регистром.

Вот первый регистр, который здесь встречается ide_p6p1 в 88СЕ, он здесь всего один и используется как флаги.

073_pic26

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

073_pic27

Последняя восьмая ссылка. И у нас здесь какая-то странная таблица, просто все функции перечислены.

Получается, что у нас всего один кандидат. Это шестая ссылка — команда Е1. У нее в +1 регистре должен быть 0. А, соответственно, 2й, 3й, 4й, регистры содержат какие-то параметры.

Переходим теперь в PC-3000 и будем щупать, что же это за параметры такие. Открываем в PC-3000 АТА Commander.

073_pic28

Подаем питание на жесткий диск.

073_pic29

После того, как он запустился подаем команду 0xЕС.

073_pic30

Вот наш паспорт.

073_pic31

Подаем техноключ.

073_pic32

Еще раз смотрим паспорт. При этом у нас появились значения, которые при техноключе отдаются.

073_pic34

И вот наша команда 0xE1.

073_pic35

Как мы помним, регистр +1 у нас 00, +2, +3 содержат какое-то число, допустим зададим первое и второе число 10. Эта команда с забором данных. Подаем ее.

073_pic36

У нас что-то прочиталось.

073_pic37

Причем, прочиталась 10 шестнадцатиричная байт. То есть первая цифра у нас – счетчик байтов. Соответственно, давайте сделаем так, чтобы оно один сектор возвращало.

073_pic38

Еще раз подаем и видим, что команда вернула сектор.

073_pic39

То что это счетчик мы угадали правильно. Что такое вторая цифра? Установим на ней не 10, а 00.

073_pic40

Подаем команду, ответ:

073_pic41

Видно, что выдаваемый сектор сдвинулся — появилась еще одна строчка. Значит вторая цифра задает смещение в байтах. Самое интересное у нас находится с 8000. Посмотрим что там.

073_pic42

Там лежит какая-то таблица.

073_pic43

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

В этих данных можно увидеть версию микропрограммы.

073_pic44

Серийный номер.

073_pic45

Он находится в служебной зоне, но никак не в ПЗУ. Еще есть участки с множеством нулей. То есть это явно сегмент данных потому, что ПЗУ, как мы знаем, иначе выглядит. Сейчас мы все это сохраним в файл вот этой кнопкой.

073_pic46

Далее подключим к дизассемблеру и посмотрим что это за данные. У меня уже есть во вкладке Programm Segmentation заготовка под сегмент данных.

073_pic47

Сюда загружаем наш файлик File → Load file → Additional binary file.

Вот он наш считанный сегмент.

073_pic49

Указываем нужные настройки.

073_pic50

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

073_pic51

Вот они команды 0xЕx.

073_pic52

Далее:

073_pic53

Здесь есть функция формирования ID сектора.

073_pic54

Просмотрим ее и найдем участок, где выдается серийный номер.

073_pic55

Это 20 байт или 10 слов. Переходим в процедуру sub_40D9, которая копирует серийный номер с попарной перестановкой байт, как это требует АТА спецификация.

073_pic56

Теперь перейдем по адресу #unk_922А и попадем в сегмент кода.

073_pic57

В нем ничего нету, а вот что будет у нас в сегменте данных?

Давайте изменим адрес, добавив к нему единицу в начале и запишем его как комментарий по нажатию «;».

073_pic58

Теперь наш комментарий указывает на сегмент данных.

073_pic59

Нажимаем Enter на комментарии в открывшемся адресе прямо видно серийный номер.

073_pic60

То есть получается, по этой ссылке #unk_922A у нас берется адрес в ОЗУ, где он считан уже из служебной зоны и функция sub_40D9 ее выдает. Если служебка не читается, то серийный номер жесткий диск не отдает. Это все доказывает, что мы считали именно наш сегмент данных. А теперь интересно, а что там с оверлеями?

Вернемся к команде lc_cmd_EC нажав ESC.

Там дальше явно идет вызов в оверлей.

073_pic61

Раньше там было пустое место, а сейчас что там? Заходим нажав Enter и там код появился. Нажимаем букву «С» и есть переход на возврат.

073_pic62

Видно, что здесь код осмысленный. Функция unk_190CC вызывается и тут же возвращается. То есть у нас оверлей фактически подключился.

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

А теперь, все то же самое, только кино:

А на сегодня все. До новых встреч!

Поделиться ссылкой на пост в соц. сетях

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *