По многочисленным просьбам читателей пишу серию статей о формате прошивок принтеров.
Начнем, пожалуй, с самого простого, практически с начала одноаппаратных прошивок. SCX-3200. Начиная с 8 версии, производитель начал применять шифрование, здесь же простое сжатие gzip.
Итак, нам понадобится:
1. HEX-редактор, любой, удобный вам. Мне нравится Hex Editor NEO.
2. Среда программирования, с языком которой вы знакомы. Для примера будем использовать PHP DevelStudio (http://develstudio.ru/), т.к. здесь проще всего организовать упаковку/распаковку gzip.
3. IDA Pro Advanced 5.5 with Hex-Rays для дизассемблирования.
Загрузим файл в хекс-редактор:

и перейдем по адресу (CTRL+G) 0x40078 (здесь и далее все адреса в шестнадцатеричном представлении)

Видим сигнатуру $ZIP . Здесь и находится ядро прошивки в упакованном виде.
Следующие 4 байта 0x40080000 – адрес распаковки ядра, далее 0x001afff4 – размер упакованной части.

Лирическое отступление: 2 основные части прошивки – загрузчик и ядро. Загрузчик проверяет контрольную сумму прошивки, распаковывает и запускает ядро. Здесь же находится принудительный режим и дебаг. Ядро – основная рабочая программа принтера, реализующая функции печати, взаимодействие с компьютером, сетевые протоколы и все остальные рабочие процессы аппарата.
Теперь наступило время запустить Devel Studio.
Добавим на форму кнопку и создадим для нее событие «Клик»

Двойным щелчком на надписи «Клик» откроем редактор кода.

С этого момента начинается программирование.
Пишем следующий код:
$fn = 'D:\test\Z501BFEZ900168X_FIX_NU_3200_v07.hd';// имя файла и путь к нему
$file = file_get_contents($fn); // считывание содержимого файла в переменную
$zip = substr($file, 0x40078+0xC, 0x1afff4); // считывание упакованного ядра без заголовка $ZIP(0xC - 12 байт)
$unzip = gzuncompress($zip); // распаковка архива
file_put_contents('D:\kernel.hd',$unzip); // сохранение распакованного ядра в файл
echo "OK!";
Компилируем и запускаем (F9), нажимаем нашу единственную кнопку. Если пути к файлам прописаны правильно, и ошибок не возникает – видим сообщение «ОК». Появившийся файл ‘D:\kernel.hd‘ и есть наше распакованное ядро.
В нем поиском можно найти серийный номер.

Улыбаемся, и представляем, как эти знания еще пару лет назад могли вас значительно обогатить.
Теперь загрузим ядро в ИДУ и немножко дизассемблируем.
Выбираем процессор ARMB (big endian):

Выставляем адреса, как на картинке:

Далее в меню Options -> General -> Analysis ->Kernel options 1 ставим галку Make final analysis pass -> OK -> Reanalyze program
Несколько минут курим. Пока идет процесс анализа кода, скажу вам, что верить Иде на 100% нельзя, иногда она ошибочно принимает данные за код и наоборот. И довольно часто домысливает лишние конструкции, что усложняет понимание кода. Лучше запускать исследуемые функции в эмуляторе и смотреть, что происходит с регистрами и памятью. Но, все-таки, общую картину понять можно значительно быстрее с помощью Иды.
Итак, анализ закончен, серийник находится по адресу 0x400C76B0 (для перехода нажать клавишу G)

Серийный номер считывается из прошивки во время выполнения 0x400C768C и передается через R0 в функцию sub_400DBF70, которая проверяет его, и в случае соответствия пишет в R0 = 0.
ROM:400C769C CMP R0, #0
Здесь сравнение R0 с нулем, собственно, то место, где изменением пары байт можно сделать многоаппаратную прошивку.
На этом пока все, ждите продолжения. Если вы не понимаете всего вышесказанного, то лезть в эту тему смысла нет – дальше ещё сложнее.