Распаковка, редактирование и упаковка прошивок видеорегистраторов и IP камер из Китая

в 18:39, , рубрики: diy или сделай сам, dvr, firmware, метки: , ,

Предыстория

Не так давно приобрёл на Aliexpress IP камеру (чип Hi3516 платформа 53H20L) и 16-канальный гибридный видеорегистратор (чип Hi3521 платформа MBD6508E). Оба выполнены на чипсете от HiSilicon, так что проблем с совместимостью между собой не испытывают.
Разумеется, не обошлось и без глюков. Первый, и самый главный — у камеры криво работал WiFi — нельзя было подключиться к сети, если ключ был задан в HEX виде, а таже периодически возникала проблема со шлюзом по умолчанию.
Распаковка, редактирование и упаковка прошивок видеорегистраторов и IP камер из Китая
Прошивка оказалась старая, ещё июньская. Раздобыл несколько свежих прошивок и попробовал. Некоторые оказались глючными, но одна заработала нормально.
Возникла другая проблема — изменился пароль по умолчанию для telnet подключения. Этого я не стерпел и стал искать способы вернуть его обратно.
Сразу предупрежу, что данный способ опробован на видеорегистраторах и камерах на чипах HiSilicon, но должен сработать и с другой платформой, так как китайцы широко используют загрузчик U-boot.

Распаковка

Инструкция по распаковке довольно подробно расписана в этой статье, но вот процесс упаковки нигде не описан, что и побудило меня написать этот пост.
Расписываю по шагам, чтобы ничего не упустить:
Ставим Linux, я выбрал ubuntu.
Проверяем тип файла прошивки:

root@xc:~/firmware# file General_HZXM_IPC_HI3516C_53H20L_V4.02.R11.20131108_ALL.bin 
General_HZXM_IPC_HI3516C_53H20L_V4.02.R11.20131108_ALL.bin: Zip archive data, at least v2.0 to extract

Распаковываем:

root@xc:~/firmware# unzip General_HZXM_IPC_HI3516C_53H20L_V4.02.R11.20131108_ALL.bin 
Archive:  General_HZXM_IPC_HI3516C_53H20L_V4.02.R11.20131108_ALL.bin
  inflating: Install                 
  inflating: u-boot-all.bin.img      
  inflating: web-x.cramfs.img        
  inflating: custom-x.cramfs.img     
  inflating: user-x.cramfs.img       
  inflating: romfs-x.cramfs.img      
  inflating: logo-x.cramfs.img       
  inflating: InstallDesc

Смотрим содержимое Install:

{
   "Commands" : [
      "burn custom-x.cramfs.img custom",
      "burn romfs-x.cramfs.img romfs",
      "burn user-x.cramfs.img user",
      "burn logo-x.cramfs.img logo",
      "burn web-x.cramfs.img web"
   ],
   "Devices" : [
      [ "53H20L", "1.00" ]
   ]
}

InstallDesc:

   "UpgradeCommand" : [
      {
         "Command" : "Burn",
         "FileName" : "u-boot-all.bin.img"
      },
      {
         "Command" : "Burn",
         "FileName" : "custom-x.cramfs.img"
      },
      {
         "Command" : "Burn",
         "FileName" : "romfs-x.cramfs.img"
      },
      {
         "Command" : "Burn",
         "FileName" : "user-x.cramfs.img"
      },
      {
         "Command" : "Burn",
         "FileName" : "web-x.cramfs.img"
      },
      {
         "Command" : "Burn",
         "FileName" : "logo-x.cramfs.img"
      }
   ],
   "Hardware" : "53H20L",
   "Vendor" : "General"
}

Слово u-boot-all наводит на мысль, что файлы img являются образами загрузчика U-boot, поэтому ставим соответствующий пакет:

root@xc:~/firmware# apt-get install u-boot-tools

Смотрим, что за файлы у нас были в архиве:

root@xc:~/firmware# file u-boot-all.bin.img 
u-boot-all.bin.img: u-boot legacy uImage, linux, Linux/ARM, Firmware Image (gzip), 524288 bytes, Fri Nov  8 05:15:49 2013, Load Address: 0x00000000, Entry Point: 0x00080000, Header CRC: 0x8A551AA8, Data CRC: 0x8290AD90

root@xc:~/firmware# file romfs-x.cramfs.img 
romfs-x.cramfs.img: u-boot legacy uImage, linux, Linux/ARM, OS Kernel Image (gzip), 4100096 bytes, Fri Nov  8 05:16:04 2013, Load Address: 0x00080000, Entry Point: 0x00580000, Header CRC: 0xD16AC90F, Data CRC: 0x54CDD868

root@xc:~/firmware# file user-x.cramfs.img 
user-x.cramfs.img: u-boot legacy uImage, linux, Linux/ARM, OS Kernel Image (gzip), 7602112 bytes, Fri Nov  8 05:16:02 2013, Load Address: 0x00580000, Entry Point: 0x00CC0000, Header CRC: 0x106C19AD, Data CRC: 0x6D54ADA7

root@xc:~/firmware# file web-x.cramfs.img 
web-x.cramfs.img: u-boot legacy uImage, linux, Linux/ARM, Standalone Program (gzip), 1572800 bytes, Fri Nov  8 05:15:51 2013, Load Address: 0x00CC0000, Entry Point: 0x00E40000, Header CRC: 0x87611FE5, Data CRC: 0x6BD90EBD

root@xc:~/firmware# file custom-x.cramfs.img 
custom-x.cramfs.img: u-boot legacy uImage, linux, Linux/ARM, Standalone Program (gzip), 262080 bytes, Fri Nov  8 05:15:49 2013, Load Address: 0x00E40000, Entry Point: 0x00E80000, Header CRC: 0xF7C82692, Data CRC: 0x5A27F74C

root@xc:~/firmware# file logo-x.cramfs.img 
logo-x.cramfs.img: u-boot legacy uImage, linux, Linux/ARM, Standalone Program (gzip), 262080 bytes, Fri Nov  8 05:15:47 2013, Load Address: 0x00E80000, Entry Point: 0x00EC0000, Header CRC: 0x4FE4A821, Data CRC: 0xF6671BD1

Прошу обратить внимание на два параметра Load Address и Entry Point. Я при первой сборке забыл их указать, они по умолчанию стали нулями, а это адрес загрузчика, который оказался затёрт после прошивки! Из-за этого я потратил лишний час на восстановление — пришлось снимать с улицы камеру, разбирать, и восстанавливать прошивку на программаторе. (Хотя камеру разбирал всё же не зря — добавил в кожух пакетик силикагеля, чтобы убрать возможную влагу из воздуха.)

Теперь небольшое пояснение: образ .img из данной прошивки является несколько изменённым образом файловой системы cramfs. Вот тут можно почитать поподробнее. Чтобы привести образ к нормальному виду, нужно отрезать 64 байта заголовка.

root@xc:~/firmware# dd bs=1 skip=64 if=logo-x.cramfs.img of=logo-x.cramfs
262080+0 записей получено
262080+0 записей отправлено
скопировано 262080 байт (262 kB), 0,891322 c, 294 kB/c

Для остальных файлов команды аналогичные.
Смотрим, что получилось:

root@xc:~/firmware# file logo-x.cramfs 
logo-x.cramfs: Linux Compressed ROM File System data, little endian size 28672 version #2 sorted_dirs CRC 0xe29e6340, edition 0, 199 blocks, 2 files

Уже похоже на cramfs. Для работы с образами cramfs установим или обновим соответствующий пакет:

root@xc:~/firmware# apt-get install cramfsprogs

Распаковываем образы:

root@xc:~/firmware# cramfsck -x logo logo-x.cramfs
root@xc:~/firmware# cramfsck -x user user.cramfs
root@xc:~/firmware# cramfsck -x romfs romfs-x.cramfs
root@xc:~/firmware# cramfsck -x web web-x.cramfs
root@xc:~/firmware# cramfsck -x custom custom-x.cramfs

Каталоги я не создаю, они создадутся автоматически.
Загрузчик так не распаковать, это не образ cramfs, но его и не надо трогать.

Что внутри

Быстренько пробегусь по содержимому каждого файла внутри архива прошивки:

  • InstallDesc — описывает действия, которые нужно произвести с этими файлами при обновлении прошивки, install-скрипт.
  • logo-x.cramfs.img — картинка в формате 800x600 с логотипом изготовителя, которая появляется при загрузке аппарата.
  • romfs-x.cramfs.img — собственно сама операционная система linux под архитектуру ARM
  • u-boot-all.bin.img — загрузчик U-boot
  • custom-x.cramfs.img — содержит наименование платформы и дополнительные настройки
  • user-x.cramfs.img — прикладной софт, в том числе Sofia — сама программа видеорегистратора
  • web-x.cramfs.img — картинки веб-интерфейса, web.cab — плагин для Internet Explorer с локализацией, логотипы производителя.

Нас интересует romfs-x.cramfs.img, так как именно там присутствует файл passwd, в котором хранится пароль. Вот его содержимое, желающие могут попробовать сбрутить:

root:$1$RYIwEiRA$d5iRRVQ5ZeRTrJwGjRy.B0:0:0:root:/:/bin/sh

Я же просто сгенерил новый хеш на сайте и поменял его в файле.

Собираем обратно

После сделанных изменений нужно всё запаковать обратно:

root@xc:~/firmware# mkcramfs romfs romfs-x.cramfs
Directory data: 3624 bytes
Everything: 4004 kilobytes
Super block: 76 bytes
CRC: 28c62b9b

Помните, я заострял внимание на значениях Load Address и Entry Point? Самое время о них вспомнить и добавить в команду.
Создаём образ U-boot:

root@xc:~/firmware# mkimage -A arm -O linux -T ramdisk -n "linux" -e 0x00580000 -a 0x00080000 -d romfs-x.cramfs romfs-x.cramfs.img
Image Name:   linux
Created:      Fri Feb 21 14:27:38 2014
Image Type:   ARM Linux RAMDisk Image (gzip compressed)
Data Size:    4100096 Bytes = 4004.00 kB = 3.91 MB
Load Address: 00080000
Entry Point:  00580000

Кстати, чтобы обновить один модуль не обязательно прошивать всю прошивку, достаточно положить только нужный, и отредактировать файлы Install и InstallDesc, оставив только нужные строчки.
Складываем полученные файлы в отдельный каталог, пусть это будет new. Даём команду:

root@xc:~/new# zip -D -X firmware.bin *
  adding: Install (deflated 22%)
  adding: InstallDesc (deflated 30%)
  adding: romfs-x.cramfs.img (deflated 0%)

Всё, прошивка готова. Осталось только прошить её через web-интерфейс через пункт update

Предостережение

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

Ссылки

Burn-in рутовый шелл в IP-камерах Vesta и не только
GNU/Linux и устройство на Rockchip 2918
Hacking RAM disks

Автор: Newsonya

Источник

Поделиться

* - обязательные к заполнению поля