Структура прошивок

Kaliningrad

Ушол, щасвирнус...
Команда форума
В своё время структуру очень хорошо описал Mi81.
Поэтому приведу прямое цитирование...

Учитывая многочисленные просьбы здесь и в личке:
1. Прошивка (bin) состоит из заголовка и следующих за ним разделов (обычно их пять, но теоретически может быть и больше).
2. Разделы прошивки выровнены на 0х00000800 и каждый раздел имеет свой заголовок.
3. В заголовке прошивки нас, грубо говоря, интересуют два массива DWORD каждый длиной 0х80 (128) байт, которые выглядят примерно так (в последней прошивке для QL3 Old):
Структура прошивки Ambarella (Mi81)-1.jpg
Массивы на рисунке разделены красной чертой.
Первый массив это смещения начала каждого раздела в файле прошивки, т.е смещение первого байта раздела относительно начала файла. Обратите внимание, что первый байт прошивки имеет нулевое смещение 0х00000000.
Второй массив - смещение конца, т.е. байта следующего за последним байтом соответствующего раздела. Естественно тоже относительно начала файла прошивки.
Пройдемся по этим массивам:
1-й раздел: начало - 0х00001000, конец - 0х00001900 (бирюзовый цвет);
2-й раздел: в данной прошивке отсутствует, о чем свидетельствует его нулевой смещение 0х00000000 (зеленый цвет);
3-й раздел: начало - 0х00002000, конец - 0х00035B14 (синий цвет);
4-й и 5-й разделы: отсутствуют;
6-й раздел: начало - 0х00036000, конец - 0х005СE104 (самый интересный с точки зрения редактирования раздел);
7-й раздел снова отсутствует.
Ну и так далее, разберетесь дальше сами.
Всего вы найдете пять действительных разделов, т.е. разделов реально включенных в данную прошивку. Каждый раздел имеет свое имя и назначение, но мы в детали вдаваться не будем, т.к. полученной информации достаточно для первых шагов.
Пока обратите внимание на следующие вещи:
-каждые четыре байта смещения в прошивке записаны задом наперед, так принято и об этом надо всегда помнить;
-конец раздела во втором массиве обозначен смещением байта следующего за последним байтом этого раздела;
-в прошивке теоретически может быть до девяти разделов, но часть из них может отсутствовать, в этом случае смещения забиты нулями ну а сам размер массива сделан с запасом на будущее усложнение прошивок.4. Теперь перейдем к самому интересному разделу, который в этой прошивке начинается со смещения 0х00036000 и чаще других подвергается правке.
Выполним в меню -> Position -> Go to offset... -> вводим 36000 и попадаем на первый байт раздела:
Структура прошивки Ambarella (Mi81)-2.jpg
Как уже отмечалось, каждый раздел состоит и заголовка длиной 0х100 (256) байт за которым непосредственно следует тело раздела, т.е. в нашем случае первый байт тела раздела будет лежать по смещению 0х00036100, что и показано на рисунке черной стрелкой.
5. Рассмотрим наиболее интересные значения заголовка прошивки, они выделены на рисунке различными цветами:
синий - контрольная сумма тела раздела (обратите внимание - только тела, без заголовка) в формате CRC32;
зеленый - длина раздела в байтах, т.е. даже если бы мы не знали из заголовка смещение конца раздела, мы смогли бы его вычислить;
желтый - адрес первого байта тела раздела в памяти прибора.
В заголовке есть и другие контрольные данные, но в данном контексте нас интересует только CRC32, поэтому оних я писать не буду, другие упомянутые привел лишь для сведения.
6. Теперь о контрольной сумме. Во-первых, она как ивсе другие значения записана задом-наперед, т.е. реальное значение в данном примере 0х2295С1С1 и когда вы вычислите свою сумму, вам придется ее побайтово перевернуть.
Во-вторых, напомню - считается только контрольная сумма тела раздела.
Делается это так:
-устанавливаем курсор на начало тела, т.е. по смещению 0х00036100;
-идем в меню: Edit -> Define block...;
-в открывшемся окне устанавливаем значения: для поля Begining в выпадающем комбобоксе выбираем Current position, т.е. байт где установлен курсор или вводим его смещение вручную, а в поле End - вводим вручную значение 5СE103 (т.е. смещение последнего байта раздела), нажимаем OK. В результате будет выделено тело раздела.
Теперь выполняем подсчет контрольной суммы:
-меню -> Tools -> Compute Hash...
-В открывшемся окошке выбираем в комбобоксе вид контрольной суммы, который нас интересует - СRC32 (32bit) и нажимаем OK.
-Записываем полученное значение в обратном порядке на бумажку.
Т.к. мы еще ничего не меняли в этом разделе прошивки, полученная контрольная сумма совпадет с той, что уже записана по смещению 0х00360000.
Если вы измените хоть один байт в теле раздела, его контрольная сумма изменится и вам нужно будет прописать ее в заголовке раздела на свое место не забыв перевернуть ее побайтово задом-наперед (в данном случае по смещению 0х0003600).
И еще, вы уже, наверное, обратили внимание, что при выделении тела раздела я указал конец блока 5CE103, а не 5СE104, как прописано для этого раздела в заголовке прошивки. Это потому, что как я писал выше, в заголовке конец раздела обозначен смещением первого байта, следующего за последним байтом раздела. Нас же в данном случае именно последний байт раздела и интересует.

Удачи и будьте внимательны, трижды внимательны, семирижды внимательны при редактировании прошивок.
 
Последнее редактирование:

z.768

Команда форума
а2 - а7 могу и подробней описать хеадер.
Там тоже есть нюансы, вообще структура очень схожая.
Длина хеадера как правило 2048 байт.
В хекс 0х800.
Скажу точно никогда не встречал что-то внезапное, всегда 2048.
а9-а12, это иная страница, пока пропустим мимо.
А вот данные в хеадере расположены по разному.
Начну с чипа а2 и потиху разложу прошивку на составляющие на примере Axiom 1100.
Порядок байт little-endian - т.е. от младшего к старшему...
Если в хекс редакторе вы увидели 44332211, то реально это 11223344 - в хекс значении.

На примере Axiom 1100 (A2s70+OV2710)
А2.png
 
Последнее редактирование модератором:

z.768

Команда форума
Продолжу на разборе хеадера.
Система простейшая...
Идет оффсет от начала прошивки 4 байта, следом длина раздела, тоже 4 байта.

Далее пример разбора хеадера.

00080000 = оффсет первого раздела
28100000 = длина первого раздела (вместе с хеадером)
00180000 = оффсет второго раздела
10590200 = длина второго раздела (вместе с хеадером)
00000000 = раздел отсутствует
00000000 = длина отсутствующего раздела
00600200 ... и так далее
F4033F00
00000000
00000000
00083F00
00497D00
00507D00
04D79600
...
...

Bst
Bld
Hal - отсутствует
Pri
X-5 - не знаю но отсутствует
Rom
Dsp

Напомню, в каждом разделе и в хеадере прошивки присутствуют байты выравнивания.
Т.е. длина хеадера и всех разделов должна быть кратна 2048.
 

Вложения

  • 259 байт Просмотров: 9
Последнее редактирование:

z.768

Команда форума
Сейчас начнем раскладку разделов...
Каждый раздел всегда имеет заголовок, ну или хеадер.
Длина 256 байт.
:)
Или цена $100, извиняюсь за юмор.
Ну это в хекс значении, не в купюрах.

// заголовок секций
TSecHeader = record // равно 0x100
Crc32: DWORD; // контрольная сумма 4 байта
Version: DWORD; // версия = 2 символа, по 2 байта на символ
DateSec: DWORD; // дата = день = 1 байт, месяц = 1 байт, год = 2 байта
// год - 2 старших байта
LengthSec: DWORD; // длина секции 4 байта
MemAdress: DWORD; // Memory адрес 4 байта
FlagSection: DWORD; // флаг 4 байта
MagicConst: DWORD; // константа секции 4 байта CNS_MAGIC_CONSTANT
// FIX = неправильный Offset
UnknownFlag: DWORD; // ..................????? = $01
ZeroBytes: array [1..56] of DWORD; // 224 нулевых байт
//ZeroBytes: array [1..57] of DWORD; // 228 нулевых байт
end;

Решил не править ничего, как есть из исходников программы АЕ.
Умный разберется.
Каждый раздел должен быть кратен 2048.
Иначе добавляются байты выравнивания, не важно $FF либо $00, как правило $00.
 
Последнее редактирование:

z.768

Команда форума
Начнем разбор разделов, в нашей ситуации их пять.
Интересуют только 2 раздела, pri и rom.
Раздел pri обойду стороной, кто хочет тот и правит все для себя.
Как правило там длина не изменяется, остается только в хеадере прописать контрольную сумму crc32
после правки.

Rom очень понятный раздел.
Стандартный заголовок длиной $100.

Далее информационный заголовок длиной $800.
В первых 4-ех байтах прописано количество файлов в разделе.
Следующие 4 байта - константа.
Все остальное как правило $FF.

Следом идут заголовки каждого файла.
Длина каждого заголовка $80.
Включаем в хекс редакторе режим cp-utf8 и видим имена каждого файла.
 
Последнее редактирование:

z.768

Команда форума
Два скрина для наглядности.
В последних 12-ти байтах находится
1.Смещение
2.Длина
3.Константа
rom.png files.png
Вроде все просто.
 
Последнее редактирование модератором:

z.768

Команда форума
Strings.bin
Довольно интересный файлик, точней его построение.

// заголовок Strings.bin
TStringHeader = record // равно 0x20 байт
StringConst: DWORD; // константа strings.bin
LengthHdr: Word; // длина заголовка Strings.bin
Languages: Word; // количество языковых секций
Strings: Word; // количество строк в каждой языковой секции
ZeroArray: array [0..10] of Word; // байты выравнивания = $00
end;

Для общей информации DWORD = 4 байта
Word = 2 байта.
Количество строк для каждой языковой секции всегда одинаково !

Если разложить в текстовом редакторе получится так
Код:
56340001 - константа
2000 - длина заголовка
0C00 - количество яз. секций
FD02 - кол. строк
00000000000000000000000000000000000000000000 - байты выравнивания
 
Последнее редактирование:

z.768

Команда форума
Далее тоже все красиво получается.

str.png

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

z.768

Команда форума
Языковые секции и их содержимое.

length.png
Разберемся сейчас и с языковыми секциями.
В начале каждой секции идет массив длин строк.
По 4-ре байта на строку.
Привожу на примере первых трех строк из первой секции...
Код:
00000000 - начало секции
0A000000 - длина 1-ой строки в байтах
1C000000 - длина второй строки в байтах
2C000000 - длина третьей строки в байтах
Длина первой строки вычисляется просто.
0A000000 - 00000000 = 0A
Длина второй строки
1C000000 - 0A000000 = 12
ну т.д

sec.png

Для примера раскладываю в блокноте.
Код:
6E00 7500 6C00 6C00 0000
4C00 4100 4E00 4700 5500 4100 4700 4500 0000
4500 4E00 4700 4C00 4900 5300 4800 0000
Проверяем в юникоде символы - все верно.
Считаем байты - тоже все верно.
 
Последнее редактирование:

JeWell

Знающий
Возобновим тему. ;-)
Вопрос про раздел header: первые FF байт от начала описаны, с ними всё понятно. А последующие за ними? Есть какое-то описание, что за данные находятся со смещения 0х100 по 0x7FF?
 

z.768

Команда форума
Хеадер у а2-а7 фиксированный.
У чипов выше, плавающий.
Ну это я так называю.
У каждой секции, либо раздела присутствует свой заголовок размером в 0х100.
crc32, константа раздела, дата и т.п.
Все это можно понять из моей проги.
Есть еще байты выравнивания, иногда ксор на прошку, gzip упаковка и всяки бяки.
 

z.768

Команда форума
Да и учитывай фактор LE ...
00000001 в нормальном хекс = 01000000 = дек 16777216
 

z.768

Команда форума
Аватар поменял ?
Извини... не хочу обидеть...
Сразу вспомнил фразу из известного фильма
... дурик, ты зачем усы сбрил ?
Сорри перед сообществом и лично, за шутку и оффтоп.
 

JeWell

Знающий
Да, картинку поменял. И та "не оно" и эта... но эта хотя бы новая. Вообще движок форума после обновления новогоднего сильно хуже стал. И теперь тут многое очень неприветливо. Поэтому - не всё ли равно, какая картинка. И эту потом поменяю. А можно вообще убрать. Пофиг. Это ж "одёжка".

Про header: речь именно про прошивку для устройства на A7LA50.
Сверху - этот "нестандартный", снизу - "стандартный". Красным обвёл те данные дополнительные. Ну и всякая там вроде как "не важная" ерундень в виде текстовой строчки - она ж тоже для чего-то нужна и нигде не описана.
compare headers.png
 

z.768

Команда форума
Дим, ты чем открываешь прошку ?
Есть хексворкшоп. Ну хекс редактор.
Я понял что не в проигрывателе виндовс медиа.
 

JeWell

Знающий
Это просто для создания этих картинок - в просмотрщике (по F3) total commander-а.
 

z.768

Команда форума
Прежде чем ковырять прошку нужно понять заголовок проши.
Далее идут разделы, ну или секции.
Для ром-раздела идут файлики - это отдельная история.
Все остальное нас не интересует.
Все что правим находится в при-секции, она самая сложная...
...ром попроще, но есть всяки фишки с конкретными файлами !
 

JeWell

Знающий
Позвольте немного возродить тему. :)
Есть задача - восстановить прошивку, прочитанную из микросхемы флэш-памяти. Т.е. имеем дамп. Глазками можно в нём найти начала и концы разделов. У разделов нет заголовков, но зная структуру заголовков - легко их приделать вручную.
А вот далее, чтобы создать работающую прошивку, которую бы можно было прошить через SD-карту, надо эти все файлы разделов скомпилировать в один файл (firmware.bin). А для этого надо знать, по какому смещению какой раздел в этом файле должен жить.
Иными словами, не имея файла hdr, можно как-то правильно восстановить структуру прошивки? Как знать, по каким смещениям что должно лежать в ней?
Понятно, что блоки в коде
01 bst
02 ptb
03 bld
04 hal
05 pba
06 pri
07 sec
08 bak
09 rmd
10 rom
11 dsp
12 lnx
13 swp
14 add
15 adc
16 raw
17 stg2
18 stg
19 prf
20 cal
(подсмотрел её в считанном дампе).
Соответственно, если длины блоков bld, bst, hal почти всегда одинаковые, то у блока pri всегда своя длина. Начинаться он может по смещению 0х034800, а заканчиваться соответственно длине самого файла с этим блоком. Но вот вопрос: а расстояния между блоками по каким законам создаются?

Так же, если с двумя табличками (в которых лежат смещения начал и длин блоков) длиной 0х80 всё понятно, то что лежит далее, за этими табличками, начиная со смещения 0х100? Вот тут вот, на этом примере:hdr-q.PNG

Ориентироваться на расположение блоков (смещения их относительно начала) прошивки внутри дампа для проведения аналогии по размещению этих же блоков внутри файла firmware.bin нельзя, т.к. в дампе расстояние между блоками прошивки довольно большое, кроме того, между BST и BLD живут какие-то данные, похоже что с разметкой блоков внутри дампа.
 
Последнее редактирование:

JeWell

Знающий
Попробовал собрать прошивку вручную. Расставил все длины, смещения, пересчитал црц. Недостающие данные в область блока HDR взял из ближайшей похожей прошивки. В общем, программа AE не ругается, всё распаковывается-запаковывается, а аппарат процесс прошивки этим файлом начинает, но потом говорит об ошибке. И после этого родная прошивка не заменяется.
 

On-Line статистика

Пользователи онлайн
3
Гостей онлайн
9
Всего посетителей
12