Описываю мои телодвижения как и обещал: Запускаю mmtool(v2.22.1). Выковыриваю

Описываю мои телодвижения как и обещал:

Запускаю mmtool(v2.22.1). Выковыриваю оттуда все модули в отдельные файлы. (Меню Extract - In uncompressed form, Module ID Offset и Segment не трогаю). Напоминаю, что программа глючная слегка и при перемещениям по меню(у меня больше чем 3 смены ) завершается аварийно, поэтому я делал так: Запустил mmtool. Выбрал 'Power MMtool'.
Выбрал Load ROM. Потом мышкой выбрал Extract. Далее мышкой выбираю нужный можудь и в меню Extract подменю Extract. Описываю я это потому что сам пока не понял , что программа подвисает из-за перемещений по меню , начинал сильно сомневаться в возможности программы.

В каждом файле поиском пытаюсь найти CD 13(int 13h). В найденных файлах уже смотрю по контексту - считывание это MBR(или другого загрузчика) в память либо работа с HDD либо какая-то логика работы с другим носителем . Итак мой выбор пал на модуль runtime.
Почему?
Просмотрев все встречающиеся места в этом и другом модулях я смотрел контексту на наличие 7С00 (смещение при считывании загрузчика в память по адресу 0000:7C00)
Итак runtime. CD 13 там встречается 3 раза.
Искал я эти баты с помощью hiew.exe
и нашёл следующее нужное мне место:
00003146: push es
00003147: push bx
00003148: push 000
0000314A: pop es
0000314B: mov cx,00004
0000314E: mov bx,07C00
00003152: push cx
00003152: mov cx,00001
00003155: mov dh,000
00003157: mov ax,00201
0000315A: int 13
0000315C: pop cx

Я думаю, что те кто знают ассемблер, либо те кто экспериментировали с int 13h (пусть даже на паскале используя asm вставки ) поймут что идёт считывание (ah=02) одного сектора( al=01) с номером Cyl=0 Sect=1 (cx=1) head=0 (dh=0) в память по адресу 0000:7C00 (es=0, bx=7C00)
что касается регистра dl - это данные касательно носителя с которого считывается сектор (для первого HDD он 80h). Если кому интересно значение этого регистра имеенно в контексте моего биоса могут глянуть выше по коду и убедиться, что он наверняка заполянется из значения CMOS касательно порядка загрузки компьютера с носителя.

Если кого-то интересует почему я выбрал именно этот (второй кусок кода с найденным CD 13 и какое значение получает dl перед int 13h спрашивайте - опишу более детально). Мне показалось что это тривиальные рассуждения поэтому я их и опустил.

Итак место где считывается загрузочный сектор в память найдено.
Начинаем править этот модуль (runtime).

Просматривая с hiew я пытался обнаружить необходимые для меня участки кода из FF. Таких оказалось одна штука (смещение 00000644). Длиной 32 байта.:) Маловато подумал я и решил более аккуратно посмотреть на куски подряд идущих 00, не забывая в принципе что это запросто могли бы быть данные которые используются для инициализации(обнуляения) какой-нить структуры данных используемой для работы BIOS. Тут я немного схалявил - понядеявшись на русский авось и не стал сильно копаться нули это для инициализации или просто пустое место. Бегло прошвырнувшись в IDAPro я стал почти уверен что те участки нулей которые я буду использовать - пустые места.

Итак имеем следующие куски свободные для записи нашего кода.


00000616: длина 90 байт
00005590: длина 110 байт
000057С9: длина 108 байт
0000598E: длина 44 байта
000091A7: длина 44 байта

По ходу дела ещё встречались участки 000046B0 (меньше 32 байт я не включил - ибо того что было мне в принципе хватило)
Плюс ещё есть достаточно большие участки из 0 (но я не стал возиться с ними по причине близкого соседства с данными строкового типа - возможно их и можно было бы использовать но для этого нужно быть уверенным и потратить время на солидный кусок трассировки BIOS - даже с IDAPro это занятие не сильно интеллектуальное - и рутинность трассировки BIOS начинает временами сильно утомлять)
И В конце runtime есть ещё солидный кусок из 20h(это пробел) который можно было бы использовать внеся небольшое изменение к BIOS.

Итак участки найдены - ищу первую команду с которой неплохо бы стартануть свой код.
Я для этого дела выбрал
00003148: push 000
0000314A: pop es
и изменил это (прямо в hiew ) на
00003148: call 0000055B0 (E86524 если кому не ясно как высчитывается смещение для прыжка смотрите ссылки которые я давал в посте выше)
(соответственно перед выходом из моей процедуры я не забыл про код который я убрал тоесть перед самым последним ret будет конструкция
push 0
pop es)
У внимательных людей может возникнуть вопрос почмеу я сделал call не на начало свободного блока 00005590. (по моим расчётам мне необходимо было 239 байт. Поэтому я позволил себе быть слегка расточительным и мало лли что - но я предпочитаю потерять 4 пустых байта и быть немного уверенным что это не начало какой-то новой порождённой мной инструкции либо если есть необходимость выровнятькод по адресу кратному 4)
Итак первая команда по адресу 55B0

000055B0: cli (жёстко конечно выключать прерывания которые уже могли бы выполняться даже в BIOS но я предпочитаю быть уверенным что чтонибудь мне не поменяет регистры особенно ss sp )
000055B1: pusha (сохраняем все регистры)
000055B2: pushf (сохраняем регистр флагов)
Далее у меня весьма расточительная трата свободного места (мне нужны показания часов из BIOS)
Весь код и в особенности основную процедуру (работа c HDD) я приводить не буду заменяя её nop:) но пару кусочков кода могу привести :)
000055B3:
mov ax,09
out 070,al
in al,071 (это мы берём две последние цифры от года)
push al
nop (убрал я этот кусок кода дабы не актвизировать творчество отечественных умельцев в ненужном направлении:) )
nop
pop al
000055D6: call 000057E0 (E80702)
nop (6штук):)
000055DF: call 000057E0 (E8FE01)
000055E2: popf
000055E3: popa
000055E4: push 000
000055E6: pop es
000055E8: retn

из процедуры 000057E0 (идут вызовы и возвраты в оставшиеся 3 свободных участка блока). Описывать я их здесь не стану, но в каком нибудь закрытом форуме думаю смог бы:)

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

Напоминаю - длина модуля runtime не поменялась.
Теперь вставка этого модуля в основной файл ROM BIOS.
По прежнему осторожно используем mmtool. Тут я потратл слегка времени пытаясь указать segment и offset с того места которое было расшифровано самим mmtool. Но тут меня постигали обломы ибо почему-то после Replace, у меня в mmtool менялись точки распаковки модуля в память. Солидно поднадобламавшись:) из-за глючности mmtool (хотя не спорю работу она свою делает) я один раз не указал ни сегмент ни смещение, и в общем всё прошло успешно модуль заменился и вся инфа о точках входа и прочее осталась прежней.

Далее я выбрал save ROM as. сохранил его. потом опять открыл с помощью mmtool пересмотрел есть ли изменения в точках входа в памяти, распаковал каждый модуль сравнил его с раннее распакованным вариантом. В общем не растекаясь мыслию скажу что изменения были только в модуле runtime.
Ну и конечно если теперь сравнить этот новый ROM BIOS и старый то изменений будет ну очень много с определённого адреса, что и понятно ибо модуль паковался.

Далее взял родной прошивальщик и прошил новым ROM.
Тестю уже 9 дней. Полёт нормальный.
Глюков пока не замечал.

С уважением Виктор.

P.S. Незнаю нужны ли кому-либо эти файлы (runtime к примеру), я давал ссылку в самом начале поста где этот ROM можно скачать. Ну я думаю mmtool и hiew найдться если поискать. На случай если уже не всилах найти необходимый инструмент (hiew mmtool ) отписывайте к админам форума. Если они разрешат я солью то с помощью чего экспериментировал.

Добавить код или работа с модулями AMI Bios
  • Для начала проверьте не установлен ли атрибут ReadOnly
  • Подскажите пожалуста в чем беда, у меня AMI
  • А реальные биосы с оными назвать
  • >Если б я шарил в асме, то попытался
  • Ok. Посмотрю что там внутри. Если разберусь
  • В общем AmiDeco (Decompressor) лежит здесь: http://biosgfx.narod.ru/v3/index.html А вот Сompressor