Запускаю 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 ) отписывайте к админам форума. Если они разрешат я солью то с помощью чего экспериментировал.
Описываю мои телодвижения как и обещал:
Запускаю 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 ) отписывайте к админам форума. Если они разрешат я солью то с помощью чего экспериментировал.