четверг, 7 февраля 2013 г.

Прошивка DVR Asenware DN8004 (HI3515 based) часть 2

Продолжая прошлую тему, с изучением работы китайского DVR.
После того, как мне удалось восстановить работу устройства и зайти в терминальную сессию, я, в первую очередь исправил обходной скрипт в прошивке, а вернее, заменил его на другой. Работая с подобными девайсами надо всегда помнить о том, что количество циклов перезаписи ограничено, и нельзя оставлять любой вывод или запись во флеш, в процессе загрузки.
Поскольку мне не хотелось вновь изменять прошивку и заливать ее, я решил найти другой путь. ФС Cramfs не дает нам возможность изменить файл, или примонтировать ее r\w, поэтому, я внес изменения в /etc/init.d/rcS, убрав строку ./load и вписав /etc/load, в который я скопировал все содержимое скрипта ./load, кроме переноса файла shadow.


Далее надо было выяснить, с чем предстояло работать в плане видео-вывода.
Полистав логи загрузки, стало ясно, что устройство работает на чипе Hi3515. Его разработчиком является небезызвестная компания Huawei, но чипы также делают фирмы HiVision и HiSilicon.
Дальнейшие поиски дали представление о том, как работает сам чип:
http://www.videosec.com/DVR-04H-08E/Hi3515.pdf


Однако существовала одна большая проблема — нигде в сети мне не удалось найти SDK Hi3515. Я обошел множество ресурсов, как англоязычных, так и китайских. Были лишь упоминания о продаже SDK, либо о более ранних моделях, например, на ресурсе http://www.openipcam.com/files/ARM9/ .Кстати, очень полезный ресурс с большим количеством материала по вопросу Emb Linux и прочих встраиваемых системах. Поскольку без SDK было невозможно выводить видео-потоки, я попробовал получить информацию в процессе запуска приложения оболочки с ключами вывода в файл. К сожалению, информации было мало (вероятно программа была собрана как надо, в release-версии):

Вывод exec_cmd:

Вывод ./xsj_dvr3515_4ch_dn8004 с ключом --help:

При попытке убить процесс  xsj_dvr3515_4ch_dn8004 при запущенном exec_cmd вызывает моментальную перезагрузку устройства.
Если же убить сначала процесс exec_cmd, а после xsj_dvr3515_4ch_dn8004, то система продолжает работать. При этом, запуск бинарника exec_cmd проходит нормально, а вот при запуске xsj_dvr3515_4ch_dn8004 система опять падает.
Поскольку объем доступного пространства для / только 2Мб, из которых свободно только 400Кб, копирование strace с используемыми им библиотеками было невозможно. Как вариант обхода, я использовал симлинки на флешку. Попытки запуска приложений через strace при старте системы не прошли, поскольку смонтировать флешку через fstab или скрипт инициализации по неясной причине было невозможно.
Вывод strace при запуске вручную, с системой, запущенной без автозапуска бинарников (закомментированы в скрипте инициализации):

exec_cmd:

xsj_dvr3515_4ch_dn8004:

Как видно по логу, после запуска xsj_dvr3515_4ch_dn8004 система также падала в сегфолт. Попытки запустить бинарник и после, сразу strace по PID, вида:
strace -xf -eopen -o /mnt/sda1/test.log -p `ps -A -o pid,cmd|grep xsj_dvr3515_4ch_dn8004 | grep -v grep |head -n 1 | awk '{print $1}'` 
также не удалась.

Иными словами, это был тупик. Без SDK более ничего сделать было нельзя.

Поскольку мне все же требовалось любое решение трансляции в linux, то я перешел на другое устройство — DRV DH3008 (аналог Uvision DH-1808).

Это 8-и канальный рекордер, работающий на том же hi3515.
Информации в сети по нему, я, как и в прошлом варианте, не нашел. Более того, ни сайта, ни прошивки на него не было.
Традиционное сканирование портов показало интересную картину:

Порты 8670 и 101\102 — порты для обычной и мобильной версии ПО;
23 — традиционный telnet;
80 — http, с аналогичным прошлому Active-X компоненту;
6623 — оригинальная версия telnet, которая выводила:

->help

help

Debug interface:

==================================================================

01. dvrsysstatus get dvr system status

02. dvrencstatus get dvr encode status

03. dvrrecstatus get dvr record status

04. dvrplaystatus get dvr local player status

05. dvrnetstatus get dvr net send status

06. help get help

07. bye quit telnet

==================================================================
На команды, правда, никакой реакции не было, кроме:
->dvrsysstatus

dvrsysstatus


value=0
И, наконец, очень интересный мне порт 554, который используется обычно RTSP-сервером (http://ru.wikipedia.org/wiki/RTSP).
Настал момент подумать, как можно зайти на устройство, чтобы посмотреть, как что работает.
Прошивки не было, поэтому вариант, аналогичный прошлому DVR-у не прокатывал. А поскольку 3008 уже работал и был занят, разобрать его, чтобы добраться до UART тоже было нельзя.
Оставалось только гадать.
Я просмотрел множество тем форума, где люди спрашивали о возможных паролях на китайские регистраторы, и уже почти отчаявшись найти что-то полезное, я увидел совет зайти root-ом без пароля. И это сработало :)
BusyBox v1.1.2 (2010.03.16-02:37+0000) Built-in shell (ash)

Enter 'help' for a list of built-in commands.


Welcome to HiLinux.

None of nfsroot found in cmdline.

~ $
Оказавшись в системе я принялся за изучение того, что имело в наличии.
Структура была очень схожа с 8004, но эта модель была явно лучше оснащена. В busybox присутствовало больше команд.
/proc $ cat cpuinfo:

/proc $ cat meminfo:

/proc $ df -h:
Filesystem Size Used Available Use% Mounted on

/dev/ram0 12.5M 10.5M 1.4M 88% /

tmpfs 20.3M 4.0k 20.3M 0% /dev

tmpfs 9.0M 0 9.0M 0% /tmp2

/dev/sda1 37.2G 36.9G 372.4M 99% /root/rec/a1

/dev/sda2 37.2G 36.9G 372.5M 99% /root/rec/a2

/dev/sda3 37.2G 36.9G 372.5M 99% /root/rec/a3
/dev/sda4 37.2G 36.9G 372.5M 99% /root/rec/a4 
/proc $ cat hiversion
LINUX_2_6_24-M01C06FB02F @Hi3515v100R001_C_0_0_0 2010-03-16 10:41:14
/proc $ cat mtd
dev: size erasesize name
mtd0: 00100000 00010000 "boot"
mtd1: 00200000 00010000 "uImage"
mtd2: 00500000 00010000 "rootfs"

/proc $ cat version
Linux version 2.6.24-rt1-hi3515v100 (root@bogon) (gcc version 3.4.3 (release) (CodeSourcery ARM Q3cvs 2004)) #264 Wed Sep 8 22:03:22 CDT 2010

Пользователь в системе был только root. Файл shadow отсутствовал вообще.
Через ftpget мне удалось залить в систему нормальный netstat с ARM-виртуалки и библотеки к нему, чтобы понять, кто именно занимает порт RTSP. Вывод показал, что это был файл: /root/app.out
Сверившись со скриптами инициализации, стало ясно, что основные файлы, за счет которых работает оболочка девайса — это бинарники app.out и mydaemon.out.
Инициатором запуска являлся скрипт /root/run_app.sh


К сожалению, архивы app.tgz и data.tgz по пути /lib/modules/2.6.24-rt1-hi3515v100/kernel были битыми (что довольно странно). Были также 2 симлинка на SDK, которые забыли удалить разработчики:
lrwxrwxrwx 1 root root 72 Dec 2 2010 source -> /home/pub/osdrv/Hi3515V100_OSDRV_SDK_20100316/sdk/source/os/linux-2.6.24

lrwxrwxrwx 1 root root 72 Dec 2 2010 build -> /home/pub/osdrv/Hi3515V100_OSDRV_SDK_20100316/sdk/source/os/linux-2.6.24
Веб-сервер со страничкой логина и ActiveX-компонентом был запущен отдельно:
$ ps |grep webs

646 root 300 S webs -p 80
Примечательно то, что после перезагрузки девайса, все библиотеки и файлы, которые я скопировал в его ФС были стерты. Это наводит на мысли о том, что в какой-то области памяти находиться дамп прошивки, который самозаливается при перезагрузке, но такой подход не очень вяжется с техническими особенностями флеш-памяти.

Отталкиваясь от исходных данных и открытому 554 порту, я попробовал отправить запрос с VLC-плеера, дабы понять, действительно ли на нем висит RTSP-сервер или это просто случайный порт, выбранный разработчиками для своих целей.
Запрос вида rtsp://10.10.0.102/ через понять, что я был прав. Wireshark показал ответ:



Это был действующий RTSP-сервер, и это внушало надежду. Но была одна большая проблема — я не знал полный путь к потокам, без которого все мероприятие теряло смысл.
Несколько часов было потрачено на поиски любых пресетов для различных устройств, вроде DVR и камер, с поддержкой RTSP. Результатов не было, угадать было невозможно.
Лог dmesg также не дал информации. Остальные логи система не писала по причине ограничения циклов перезаписи.
Оставался только глубокий анализ бинарного файла, который открывал 554 порт.

Для анализа файлов можно использовать разные инструменты. Наиболее эффективны, на мой взгляд - binwalk, foremost (в некоторых случаях), традиционный strings из комплетка binutils, hexdump (или bless для тех, кто любит GUI), а также различные отладчики и трассировщики, вроде IDA и strace, ltrace. Неплохая статья на эту тему http://www.devttys0.com/2011/07/reverse-engineering-vxworks-firmware-wrt54gv8/
В первую очередь стоило натравить binwalk. Ответ не заставил себя ждать:


Первый блок показал сигнатуру ELF 32.
Четвертый JFFS2, что вероятно было просто случайным совпадением сигнатур, поскольку ФС девайса была в ext2 (что, кстати, довольно интересно, поскольку традиционными ФС для rootfs в Emb Linux обычно являются jffs2,yaffs,cramfs)
Попытка использовать найденный magik-файл для анализа прошивок показал немного другую картину:


Было ясно, что файл упакован.
Но, попытка распаковать его не прошла:
root@tester-HP:/home/tester/temp# dd if=app.out skip=1 bs=876 of=app.7z
4271+0 записей считано
4271+0 записей написано
скопировано 3741396 байт (3.7 MB), 0.0222831 c, 168 MB/c
root@tester-HP:/home/tester/temp# 7z e app.7z

7-Zip [64] 9.20  Copyright (c) 1999-2010 Igor Pavlov  2010-11-18
p7zip Version 9.20 (locale=ru_RU.UTF-8,Utf16=on,HugeFiles=on,8 CPUs)

Processing archive: app.7z

Error: Can not open file as archive
Зато интересную картинку показал вывод file при сканировании без 1-ого блока:
root@tester-HP:/home/tester/temp# file app.7z
app.7z: PGP encrypted data
Возможно, это просто ошибочные данные, но традиционный способ распаковки не помог. Сигнатур упаковщиков также не было найдено.
Остался только анализ strings, который кое-что дал:


Это дало точку отсчета для того, чтобы знать где искать и не просматривать файл в 3.6Mb руками.

Стали известны строки:

Версия RTSP-сервера стала известна. А вот понимание xml пришло не сразу.
Пока я размышлял на тему того, как узнать чему сопоставлены переменные, пролистывая листинг файлов в корне, в голову пришла мысль о том, что если разработчики оставили симлинки на удаленные остатки SDK, то возможно, они еще что-то могли забыть.
Интереса ради, и убил процесс app.out и запустил его руками. Результат превзошел ожидания, и моему взору предстал дебаг-вывод:


Особенно порадовала строка:
when release, you should not see this print!!!!!!!!!!!!!!!!!!!
Забывчивость разработчиков очень помогла. Лог RTSP решил вопрос с путем до потоков:
info=01,info2=H264 Stream Meida 01
MPEG4VideoFileServerMediaSubsession::MPEG4VideoFileServerMediaSubsession:01
Play this stream using the URL "rtsp://10.10.0.104/01"
Подключение прошло успешно, я увидел картинку с камеры. Данные по потоку:
Поток 0
    Тип: Видео
    Кодек: H264 - MPEG-4 AVC(part 10)(h264)
    Разрешение: 352x288
    Декодированный формат: Planar 4:2:0 YUV
Данные в трафике:

Также интересен момент проверки лицензии:
check license ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
authentication result:0
authentication success:0
На этом мои поиски подошли к концу. Решение задачи было найдено, хоть и с другой моделью. Возможно, когда откроют SDK Hi3515, то и для первого DVR найдется применение, а пока мне осталась только настройка сервера, который бы принимал RTSP и отдавал HTTP, на благо таких немало. Например Avreg или Zoneminder. Читать дальше...

2 комментария:

  1. Ковыряю тут китайский DVR, описание совпадает с DH3008 (тот же app.out, включая хохму с you should not see this print!), но за одним большим исключением: порт 554 не открыт, RTSP, соответственно, нет, хотя в app.out есть строчки с rtsp xml.
    Плюс к этому, вход по telnet запаролен, подобрать не получилось.

    Слить прошивку с этих DVR можно через netcat, следующим образом:
    cat /dev/mtd0 | nc 192.168.1.1 7778

    На хосте с адресом 192.168.1.1 предварительно:
    nc -l -p 7778 > mtd0.bin

    Аналогично можно слить и другие разделы флешки (в моем случае образ ФС находится в /dev/mtd4)
    С /dev/mtd0 - очень аккуратно, там лежит u-boot.
    Все остальное можно поднять, а вот если убить его.....

    Можно вообще слить всю ФС в уже распакованном виде:

    tar -xf - /boot /bin ..... /var | nc 192.168.1.1 7778

    На хосте получаем архив. При сливании нельзя указывать каталоги /proc и /sys - будет SIGSEGV.
    После этого, если на хосте поднять NFS_сервер и в параметрах ядра u-boot можно указать nfsroot=...., то получим монтирование ФС по сети.

    Заливать образ ФС можно аналогично.
    На девайсе:
    nc -l -p 7777 > /dev/mtd4

    На хосте:
    nc dev-ip 7777 root_fs.gz.u-boot

    Что касается выключенного RTSP в моей прошивке. Очень хотелось бы поиметь образы флешки от DH3008.

    Спасибо.

    ОтветитьУдалить
  2. Добрый день! разбираюсь с регистратором на базе hi3515. http://sysadmins.ru/topic386054.html
    Скажите, можно ли на такой регистратор установить своё по? нужен vpn клиент. Я пробовал под arm собирать ( кросс-компиляция), но пока без успеха.

    ОтветитьУдалить