В данной статье речь пойдет о Wi-Fi мини видеокамере из семейства А9 от китайских производителей. Цель исследования этих камер – расширить возможность их применения, которая ограничена использованием только стандартных приложений для мобильных устройств на базе Android или iOS.

О камерах семейства А9

Стоимость данных видеокамер варьируется от 2$ до 4$ (в зависимости от производителя, типа процессора, наличия ИК подсветки и др.). На известной экспресс торговой площадке её можно найти по запросу «мини-камера A9». Ссылка на англоязычный форум по теме разбора камер А9.

Внешний вид моих подопытных камер представлен на фотографии ниже (и, да, внутри они немного разные).

Внешний вид камер А9 от разных производителей (показаны без элементов крепления)
Внешний вид камер А9 от разных производителей (показаны без элементов крепления)

Типовая видеокамера А9 имеет встроенный аккумулятор, а внешнее питание подается через разъем microUSB. Она может обеспечивать два режима работы с сетью: как точка доступа (AP), и как клиент сети (STA). Режим работы настраивается через стандартное приложение на смартфоне. По умолчанию всегда включен режим АР. IP адрес для камеры в режиме АР может отличаться в зависимости от производителя, у моих подопытных – 192.168.1.1. При проведении исследований этих камер использовалось приложение FtyCamPro рекомендованное производителем, хотя в «интернетах» пишут, что работают эти камеры и с более известным приложением Little Stars. Пользовательский обзор в достаточном объеме представлен на YouTube по запросу «Подключение китайской камеры А9».

Рассматриваемые здесь дешевые видеокамеры построены на основе процессора TXW806-840. Ссылка на сайт производителя чипа TWX806 (только китайский язык) https://www.taixin-semi.com/. В продаже имеются также и аналоги с процессором BK7231, которые несколько дороже. Электронная часть камеры выглядит вот так:

Плата одной из моих видеокамер с обеих сторон
Плата одной из моих видеокамер с обеих сторон

Структурная схема процессора, взятая из официального даташита показана ниже.

Структурная схема SoC TXW806
Структурная схема SoC TXW806

Согласно данным от производителя TXW806 - это высокоинтегрированный небольшой многорежимный чип для IoT с частотой 2,4 ГГц. Чип включает в себя 32-битный микроконтроллер, встроенный MJPEG (поддерживает VGA/720P), имеет DVP интерфейс, высокоскоростной хост USB2.0, хост SDMMC, ведомое устройство SDIO2.0, интерфейс RMII MAC, ведущее устройство SPI, UART, IIC, IIS, IR Send/Receive, PWM, GPIO и ADC/DAC, поддерживают запуск программ на SPI Flash. Базовый модуль Wi-Fi TXW806 реализует технологию мультиплексирования с ортогональным частотным разделением каналов (OFDM), обратно совместима с технологией расширения спектра прямой последовательностью (DSSS), дополнительной кодовой манипуляцией (CCK) и поддерживает протокол IEEE 802.11 b/g/n. Wi-Fi поддерживает стандартную полосу пропускания 20 МГц и узкую полосу пропускания 5 МГц/10 МГц, обеспечивая скорость физического уровня 72,2 Мбит/с. Имеет усилитель мощности, малошумящий усилитель LNA, радиочастотный балун, антенный переключатель, модуль управления питанием и т. д. Поддерживает RTOS и сторонние операционные системы, а также предоставляет открытую и простую в использовании среду разработки и отладки.

Используется этот чип в основном для беспроводных аудио и видео устройств, аэрофотосъемки, видео глазков для домофонов и т.п. Богатый функционал, за такую стоимость, не правда ли? От себя могу похвалить этот чип за его стрессоустойчивость, которую он проявил во время пыток его паяльником и тестером.

Безоперационное определение сознания камеры

До препарирования камеры было проведено сканирование доступных портов утилитой nmap в Ubuntu, при этом камера была подключена к роутеру в режиме STA. По результатам сканирования, были определены открытые порты камеры:

PORT

STATE

SERVICE

68/udp

open|filtered

dhcpc

7070/tcp

open

rtsp/realserver

32108/udp

open|filtered

unknown

7070/tcp open rtsp
| fingerprint-strings:
| RTSPRequest:
| RTSP/1.0 200 OK
|_ Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE

Из доступных для чтения видеопотока оказался порт 7070 по которому предоставляется потоковое видео и аудио по RTSP. Первые попытки получить видео посредством ПО работающего с протоколом RTSP не принесли успеха. Для этого использовались VLC player и openRTSP под Ubuntu (http://www.live555.com/openRTSP/).
На запрос: /home/live/testProgs# ./openRTSP ‑T 7070 rtsp://192.168.1.1:7070
Камера отвечала:

Hidden text

Created new TCP socket 3 for connection
Connecting to 192.168.1.1, port 7070 on socket 3...
...remote connection opened
Sending request: OPTIONS rtsp://192.168.1.1:7070 RTSP/1.0
CSeq: 2
User-Agent: ./openRTSP (LIVE555 Streaming Media v2023.11.30)
Received 76 new bytes of response data.
Received a complete OPTIONS response:
RTSP/1.0 200 OK
CSeq: 2
Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE
Sending request: DESCRIBE rtsp://192.168.1.1:7070 RTSP/1.0
CSeq: 3
User-Agent: ./openRTSP (LIVE555 Streaming Media v2023.11.30)
Accept: application/sdp
Received 35 new bytes of response data.
Received a complete DESCRIBE response:
RTSP/1.0 404 Not Found
CSeq: 3

Итогом такого общения был ответ от камеры:
Failed to get a SDP description for the URL "rtsp://192.168.1.1:7070": 404 Not Found
При использовании VLC результат был примерно такой же.

Еще отмечу, что камера в режиме STA интенсивно соединялась со сторонними серверами по UDP, IP которых: 170.106.50.82, 146.56.226.66 и 35.156.204.247. Это общение пришлось закрыть фаерволом, на всякий случай. Кстати, фаервол был включен на эти IP уже после тестирования с помощью утилиты openRTSP, на случай если при отсутствии соединения с этими серверами камера будет уходить в глухую оборону и в полное молчание.
P.S. Печально конечно, но IP адреса сторонних серверов потом меняются.

Вскрытие

Следующим шагом исследования было вскрытие корпуса и привлечение паяльника. На фотографиях ниже представлены PCB двух моих камер. Слева уже распаянная для работы, справа – новая, не тронутая. Обратите внимание на контактные площадки.

Контрольные (тестовые) контактные площадки на плате подопытных камер
Контрольные (тестовые) контактные площадки на плате подопытных камер

Да, и давайте камеру слева назовем FTYB, а камеру справа – BATC. Не спрашивайте почему. Дальше, надеюсь, будет понятно.

Контакты на плате слева имеют следующие обозначения: RX_PA9, TX_PA10, PA8, GND и CEN (chip enable). На плате справа аналогичные контакты обозначены несколько иначе: HCK, без обозначения, HDA, GND и nRST. В даташите на процессор TXW806 есть следующая информация:

Обозначение вывода

Тип

Назначение

PA8

I/O

LEDTMR2_PWM_OUT, ADKEY1_N0, ADKEY0_P1, ADKEY1_P0, TK8, LED_SEG4, QSPI_CLK

PA9

I/O

ADKEY0_P1, ADKEY1_P0, TK9, LED_SEG9, QSPI_IO2

PA10

I/O

ADKEY0_P1, ADKEY1_P0, TK10, LED_SEG8, QSPI_IO1

CHIP_EN

I

Chip enable:0:Chip off,   1:Chip enable

И таблица о порядке подключения чипа к программатору:

Кроме того, производитель сообщает, что имеется два интерфейса отладки: PA9 (DebugIO) и PA10 (DebugCLK) с внутренним сопротивлением подтягивающего резистора 10 кОм. Когда функция отладки не используется, интерфейс отладки можно использовать как обычный GPIO, и его необходимо настроить с помощью программного обеспечения. Во время компоновки печатной платы должны быть зарезервированы контрольные точки на плате, чтобы облегчить отладку. В то же время PA8, CHIP_EN также необходимо зарезервировать для вспомогательного тестирования.

С помощью переходника USB-TTL (в моем случае на микросхеме CP2102) камера была подключена к последовательному порту компьютера. Кстати! Контакт TX на плате это PA8, а на другой камере TX это HDA! Общение с платой осуществлялось посредством Putty с настройкой COM порта на скорость 1 000 000 (106) бод, все остальные параметры по умолчанию. Было задействовано три точки: GND, PA8 и PA9. Скорость взаимодействия определена опытным путем. На стандартной максимальной скорости 512 000 бод и менее в терминал сыпались нечитаемые знаки. Думаю, что весь лог загрузки приводить не целесообразно, здесь акцентирую внимание лишь на некоторых моментах. В логах загрузки и работы камеры содержатся наименование сборки и дата сборки ПО, наименование клиента (станции), пароль, наименование прошивки, калибровочные параметры для видео сенсора, настройки для АЦП, для TF (SD) карты памяти (пытается ее найти, создать там рабочие папки для записи видео и фото), настройки сети Wi-Fi (MAC, FLAGS, UP LINK_UP ETHARP IGMP, ip address 192.168.1.1, gateway, net mask), информация о состоянии системы (температура чипа, рабочая частота, свободная память, работающие процессы и уровни загрузки ими ЦП), например:

• начало загрузки, с наименованием сборки ПО выглядит так:

Hidden text

** hgSDK-v2.2.0.7-22619, app-0, build time: Apr 13 2023 10:15:54 **
 ------- system restart fault -----------
 ------- lvd fault -----------
 ---------------------------------------
[1]time=0, tick=1

get flash addr:fd000 size:4096,
[9]col_flag:1
[9]get_parse_cloud_id:126
[10]selfId:FTYB931188RLTOV:15
[10]col_flag:1
[10]col_flag:2
[10]get_parse_cloud_id: 126
[11]parId: WRAWEJ: 6
[IpcCfgInit][ 448] 1:616 --> get from  ezConfig FTYB931188RLTOV:ZZZZZ:
[IpcCfgInit][ 462] 0 --> get from  ezConfig FTYB931188RLTOV:ZZZZZ:
<-- FTYB931188RLTOV – имя камеры и имя точки доступа

• сообщение о разрешении матрицы сенсора:

Hidden text

[148] SENSR ident ok: 640*480
[148] csi set size ====>640*480

•  информация о том, что открытым является порт 7070:

Hidden text

t_s> spook init
listening on tcp port 7070
port:7070       fd:3
jpeg set_output
live start_block
live set_path /webcam
      <‑- /webcam – имя папки для работы по протоколу rtsp!
live set_track jpeg_dvp
jpeg get_framerate
jpeg set_running: 1
live end_block
len:1200

Соответственно, полный путь к устройству для приема потокового видео будет rtsp://192.168.1.1:7070/webcam
• данные о соединении с сетью:

Hidden text

[sys_wifi_init][ 419] CONFIG_UMAC4 ---- yes
-------ssid: FTYB931188RLTOV, key: 12345678
[52] lmac_bgn_lo_freq_set: 2457
[54] vif2 state WPA_DISCONNECTED -> WPA_COMPLETED

network interface: w0 (Default)
MTU: 1600
MAC: d8 83 32 8e a8 24
FLAGS: UP LINK_UP ETHARP IGMP
ip address: 192.168.1.1
gw address: 192.168.1.1
net mask: 255.255.255.0
network interface: lo
MTU: 0
MAC:
FLAGS: UP LINK_UP
ip address: 127.0.0.1
gw address: 127.0.0.1
net mask: 255.0.0.0

• данные о состоянии системы:

Hidden text

local:d8:83:32:8e:a8:24
    chip-temperature: 28
    freq:2457, bg_rssi:-73
    gain_table:0
    cca: -63, -53, -55
    tx: txq:0, ps:0, tx_stat_q:0,
        tx dma:12, total tx:12, retry:32, tx lost:3, tx err:0
    rx: rx irq:148
    rx dma free: 17232
    rx err: dma err:7, phy err:6714, rx frm err:467,

• данные о запущенных процессах:

Hidden text

[6244]ip:101a8c0  freemem:40224
[6244]---------------------------------------------------
[6245]Task Runtime Statistic, interval: 6244ms
[6245]PID      Name                          %CPU(Time)              Stack               Prio
[6246]--------------------------------------------------------------------------------------
[6247] 1          idle_task                     94%(5930)                  1024                61
[6247] 2          timer_task                   0%(1)                          800                  5
[6248] 3          MAIN                         2%(173)                      2048                43
[6248] 4          lmac tx                        0%(3)                          640                  27
[6249] 5          lmac tx status             0%(1)                          512                  27
[6250] 6          lmac beacon task        0%(9)                          640                  26
[6250] 7          lmac rx                        0%(11)                        1024                19
[6251] 8          lmac_bgn_test            0%(1)                          512                  51
[6251] 9          lmac main                   0%(5)                          1024                43
[6252]10         hw                               0%(21)                        2048                26
[6253]12         tcpip_thread               0%(2)                          1024                49
[6253]13         hg_sdh_test                 0%(11)                        1024                43
[6254]14         hgpdm_sample_task   0%(61)                        1024                43
[6255]17         ThLstn                        0%(5)                          1024                49
[6255]20         ThSysMon                  0%(5)                          3072                49
[6256]---------------------------------------------------
[6256]WARNING: work 0x20004248 (func:0x1800438c) use 12 ticks
host->flags:14
host->flags:14

При подключении смартфона и открытии приложения FtyCamPro:
• настройка соединения со смартфоном:

Hidden text

[26499]lmac_bgn_add_sta: if:2, aid1, addr:b4:хх:хх:хх:хх:58  ß хх – это для конфиденциальности ?
[26500]inteface2: sta  b4: хх:хх:хх:хх:58 connected
[26501]user_sta_add: b4 хх хх хх хх 58
[26813]send DHCP_OFFER ...
[26813]Next IP: 192.168.1.101
[26814]Assign IP 192.168.1.100 for b4:хх:хх:хх:хх:58, flags=0 (next:192.168.1.101)
[26847]send DHCP_ACK ...
[26847]Assign IP 192.168.1.100 for b4: хх:хх:хх:хх:58, flags=0 (next:192.168.1.101)
[26849]EVENT 10007 IGNORED
[26849]IP Pool:
[26850]    ip:192.168.1.100 - b4 хх:хх:хх:хх:58

• вход пользователя и начало передачи видео:

Hidden text

[cbEvenNoteFun][ 109] p2pSession [privilege=0,status=1,peerAddr=]
[_P2pSessionEvent][  29] p2pSession.status=[1]
[_P2pSessionEvent][  70] session[0] connected from []
[IlnkConnAdd][  23] set a connection--->[0]->2
[IlnkConnAdd][  40] set a connection--->[0]
[cbEvenNoteFun][ 123] exter--------
[cbSysCtrlFun][ 915] SysCtrl->ctrlType->(3)
[_SysUsrChk][ 675] usrchk s [admin, admin], d [admin, admin]
[_SysUsrChk][ 727] usrchk [
name=admin, pass=admin] [len=8, privilege=255, ticket=ZtsS] ß обратите внимание на name, pass и ticket!
firstRTT=6, srtt=48

[_CustomCmdPrc][2531] PUSHPARAM Set---------------
[PushParamSet][ 358] failed[336]--CfgItemGet
[PushParamSet][ 364] GPushSet:
access_id=0
xsecret_key=AIzaSyB-boxOG5n6AbKMLAOwmm1PZzqPkyZjMwc <--- обратите внимание на xsecret_key!
msgType=2
environment=1
[PushParamSet][ 396] Gpush-----index=0

• запрос на синхронизацию времени:

Hidden text

[_SysTimeSet][ 820]now: 1705692126
ntpEnable: 0
ntpSvr: time.windows.com
timezone:-10800
dayLight:0
[IpcTimeSyncFromStamp][ 307]timeStamp=1705702926-->cur_time=1705702926, Fri Jan 19 22:22:06 2024
[IpcTimeSyncFromStamp][ 329] 1705702926--> datetime [2024-01-19 22:22:06]
[_SysTimeSet][ 835] now: [1705702926:1705702926]
ntpEnable:0
ntpSvr: time.windows.com
timezone:-10800
daylight: 0
[_SysTimeSet][ 844] xqTime = 1705702926

Ну, наверное, это все что мне показалось понятным и интересным. Далее камера была протестирована на предмет приема информации по линии RX камеры, и, о чудо, она откликалась на нажатие кнопок на клавиатуре ПК. Изучение даташитов сильно не помогло, разве что в описании для платы разработчика (development board) для TXW806 было вскользь отмечено об АТ командах. На простой запрос к камере «AT+» (через «ctrl+c – ctrl+v») камера выдала список из 40 возможных команд:

Hidden text

Acmd_input_user_deal: AT+, len:3
valid cmds:
 0. AT+BSS_BW
 1. AT+CCA
 2. AT+CFG_RX_AGC
 3. AT+CLR_RX_CNT
 4. AT+DBG_LEVEL
 5. AT+EDCA_AIFS
 6. AT+EDCA_CW
 7. AT+EDCA_TXOP
 8. AT+FCC
 9. AT+TX_FRM_TYPE
10. AT+TX_GAIN
11. AT+GET_RX_CNT
12. AT+LO_FREQ
13. AT+MAC_ADDR
14. AT+PRINT_PERIOD
15. AT+REG_RD
16. AT+REG_WT
17. AT+SET_XOSC
18. AT+SET_TX_DPD_GAIN
19. AT+TEST_START
20. AT+TEST_ADDR
21. AT+TEMP_EN=1
22. AT+TX_CONT
23. AT+TX_DELAY
24. AT+TX_MCS
25. AT+TX_PROBE
26. AT+SLEEP
27. AT+TX_DUTY_CYCLE
28. AT+BSS_SCAN
29. AT+TX_PHA_AMP
30. AT+TX_PWR_AUTO
31. AT+TX_PWR_SUPER
32. AT+TX_PWR_TEST
33. AT+TX_START
34. AT+TX_STEP
35. AT+TX_TRIG
36. AT+TX_TYPE
37. AT+WAVE_DUMP
38. AT+WRITE_MAC_ADDR
39. AT+WRITE_TX_DPD_GAIN
40. AT+WRITE_XOSC

Конечно, из любопытства пришлось немного с ними побаловаться, так как поиск смысла этих команд по просторам сети ничего путного не дал. В результате опытов было выявлено несколько интересных (но не сильно полезных) команд. Вот некоторые из них:
AT+PRINT_PERIOD=1000 – установка задержки по времени выдачи в терминал информации, единица измерения – мс. Если установить значение 0, печать отключается;
AT+REG_RD= 0x01 – чтение данных из регистра 0x01;
AT+REG_WT=0x20001000, 0x123 – запись 0x123 в регистр 0x20001000;
AT+BSS_BW=20 – изменение полосы пропускания Wi-Fi.
В общем, для выполнения задачи по трансляции видео выявить пользу АТ команд мне не удалось.

Результаты перехвата потока информации по беспроводной сети

Для перехвата сетевого трафика между камерой и смартфоном использовалось приложение PCAPdroid (установленное на смартфоне), для перехвата трафика между ПК и камерой – Wireshark. Для анализа шестнадцатеричного кода использовался HxD Hex Editor. (https://mh-nexus.de/en/hxd/ редактор hex, https://www.wireshark.org Wireshark).
По умолчанию номер порта на моих подопытных камерах для обмена по UDP был постоянный – 32108 (см. выше результаты nmap), номер порта на смартфоне назначался автоматически и отличался в зависимости от сессии. Из полученных данных выделялись только UDP пакеты, а из них бралась только часть пакета с данными.

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

Обозначения: # – пакет от смартфона, @ – пакет от камеры. Данные представлены в шестнадцатеричном виде.

Номера пакетов Wireshark естественно будут отличаться от ваших. В первой группе данных (выделено желтым цветом) первый байт всегда f1, это так называемый «magic number». Второй байт этой группы идентифицирует запрос, следующим образом:
42 – «приветствие», P2pRdy
e0 – «запрос проверки состояния», P2PAlive
e1 – «ответ на запрос проверки состояния», P2PAliveAck
Вторая группа данных (выделено голубым цветом) это два байта обозначающие размер основных данных:

Порядок байт в группе – big endian, то есть 0x0014 – 20 байт, 0х0123 – 291 байт
В третьем (от смартфона) и седьмом (от камеры) пакетах, обозначающих, в моем понимании, обмен «приветствиями», в основных данных содержится наименование камеры или сети FTYB931188RLTOV, где цифры указаны в hex (0x0E3574 – 931188).

Наименование второй подопытной камеры BATC-185207-YDEIB и соответствующая часть дампа пакета UDP.

Ну и наконец, проверка состояния f1e0: пакет 4 от смартфона это запрос, пакет 9 от камеры f1e1 – ответ, и наоборот пакет 6 – запрос от камеры, пакет 8 – ответ смартфона. В пакетах с запросом проверки состояния передаются только заголовки, данные отсутствуют.
Следующие после пакетов «приветствия» и опроса состояния идут пакеты авторизации.

В пакете 10 от смартфона сообщается:
f1d0 (поз. группы 1) – данные необходимо принять и на них ответить;
00b0 (поз. гр. 2) – размер основных данных 176 байт;
d100 (поз. гр. 3) – маркер;
0000 (поз. гр. 4) – номер отправляемого пакета, который необходимо будет подтвердить при ответе;
110a (поз. гр. 5) – стартовые байты;
2010 (поз. гр. 6) – байты, сообщающие что будет проводиться авторизация пользователя
Байты 6065 6c68 6f01 (выделены песочным цветом, поз. 12,13,14) это ничто иное как логин и пароль (они между собой совпадают, см. выше логи с последовательного порта). Обратите внимание, что тут применяется простой метод шифрования:
my_byte=(my_byte%2==0)?my_byte+1:my_byte-1 и наш «’elho» становится «admin»:

В пакете 11 содержится ответ камеры, что она приняла пакет с номером 0000 от смартфона, поэтому и размер основных данных 0х0006, куда входят 0000 (позиция 5 группы данных). В пакете 12 камера отправляет запрос (f1d0) смартфону с данными о том, что пользователь авторизован (2011 поз. 6) и «выдаёт» смартфону «ticket» (см. выше логи последовательного порта) – «7669 3942» (поз.11, 12, выделено розовым цветом). «Ticket» зашифрован тем же методом что и имя пользователя и выдается один раз на всю сессию, но каждый раз новый. В пакете 13 смартфон отвечает камере (f1d1), что принял пакет с номером 0000 (поз. 5) от камеры.

Пакет 14 от смартфона к камере как раз и отличает одну камеру от другой. Этот дамп для камеры FTYB. В пакете содержится xsecret_key=AIzaSyB-boxOG5n6AbKMLAOwmm1PZzqPkyZjMwc (см. выше дамп последовательного порта). Этот «секретный ключ» выделен шрифтом красного цвета. В пакете 14 он представлен в зашифрованном виде. Камера BATC не имеет xsecret_key и поэтому в дампах трафика сетевого обмена между камерой и смартфоном такой пакет отсутствует. Желтым выделено название камеры/сети – FTYB931188RLTOV, часть, содержащая цифры теперь представлена как текстовая в формате UTF-8. Также в пакете 14 указан расшифрованный ticket – «7768 3843» (выделено коричневым цветом, первая строка 9 и 10 группы), в формате UTF-8 это текст «wh8C».

В пакете 15 смартфон в запросе (f1d0) сообщает, что приложение пытается синхронизировать время для камеры на сайте time.windows.com (зашифрованные байты, выделены красным), но смартфон подключен к камере как к AP, и поэтому попасть туда никак не может! Следовательно, время на камере не синхронизируется.
В пакете 16 смартфон делает запрос на соединение уже имея при себе билет (0810, поз. 6) и его указывая (поз.9 и 10). Пакет 17 от смартфона дублирует пакет 15 только уже без ссылки на time.windows.com.
Пакетом 18 камера «отчитывается» перед смартфоном, что получила все его пакеты (номера полученных пакетов показаны красным цветом, поз. 5-8).
В общем-то дальше уже не важно что отправляет нам камера, главное перед ней отчитываться, что получены все ее пакеты и на вопрос «как дела? – f1e0», всегда отвечать «все отлично» – f1e1. Это будет понятно из кода на Python представленного далее.
В определенный момент камера перестанет присылать вопросы «как дела?». Это видно по логам с любой камеры и будет ожидать от смартфона «серьезных» предложений. Которые выглядят следующим образом:

После чего камера подтвердит их получение, пришлёт пару «ненужных» запросов, на которые также надо будет просто отчитаться о получении. А затем камера пришлет первый пакет, в котором так называемый маркер измениться. Это и будет пакет с полезными данными!

Маркер (поз. 3, показано красным) с d100 сменился на d101, что говорит о пакете с полезной для нас информацией (аудио или видео). В данном случае, в пакете 59 передан фрагмент звука 55aa 15a8 (выделено желтым, поз. 5 и 6) – AUDIO_HEADER.

И в пакете 60 смартфон отвечает, что принял пакет 0001 (показано желтым, поз. 5) от камеры. При этом маркер у него будет d201 (поз. 3). Дальше камера беспрерывно начнет присылать jpeg и звук. А смартфону важно отчитываться за полученные пакеты.

Видно, что в пакете 61 размером 1028 байт с маркером d101 есть заголовок jpeg – ffd8. Пакеты с jpeg идут с размером 1028 байт и только у пакета, завершающего полный видеокадр, размер может быть меньше (в конце пакета должно быть ffd9).
Для примера, восстановленный (путем копирования пакетов из Wireshark в редактор HxD) фрагмент видео с моей кошкой!

Подробнее о структуре jpeg файла можно почитать на https://habr.com/ru/articles/454944/ (автор @SLY_G)

Реализация на Python

Программа имитирует общение камеры BATC с приложением на смартфоне по логике обмена пакетами описанной выше. Камера включена в режиме AP. В программе не предусмотрена отправка пакета с xsecret_key. Полученные кадры потока MJPEG сохраняются в локальную папку на ПК. Звук игнорируется. Для завершения работы программы используется магическое сочетание клавиш «ctrl+Break». Вот сам текст программы:

Hidden text
import socket
from PIL import Image, ImageDraw, ImageFont
import time, io
def pack_size(mydata) :
    #преобразуем размер данных в 2 байта hex для вставки в пакет
    return (len(bytes.fromhex(mydata)).to_bytes(2, byteorder='big'))
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
BROADCAST_CAM_PORT = 32108
cam_name='42415443000000000002d3775944454942000000' # имя камеры/сети BATC185207YDEIB, 185207 в hex
MSG_HELLO=bytes.fromhex('f1420014')+bytes.fromhex(cam_name)
MSG_E0_Q=b'\xf1\xe0\x00\x00' # Ты как? Q-question
MSG_E1_ANSW=b'\xf1\xe1\x00\x00' # Норм! ANSW - answer
HDR_D0=b'\xf1\xd0' # принимай!
HDR_D1=b'\xf1\xd1' # принял!
data_login='d100'+'0000'+'110a2010a400ff'+'00'*5+'6f'+'01'*27+'60656c686f'+'01'*123+'60656c68'
MSG_LGN_ADMIN=HDR_D0+pack_size(data_login)+bytes.fromhex(data_login)
MSG_TICKET_TIME_START=HDR_D0+bytes.fromhex('0060'+'d100'+'0001'+'110a'+'401054000000')
MSG_TICKET_TIME_END=bytes.fromhex('d1d4fefe'+'01'*8+'75686c642f76686f656e76722f626e6c'+
'01'*48+'230e0e67')
MSG_TICKET_START=HDR_D0+bytes.fromhex('0010'+'d100'+'0002'+'110a'+'081004000000')
##########################
MSG_TICKET_START_2=HDR_D0+bytes.fromhex('0018d1000003'+'110a18300c000000')
MSG_TICKET_END_2=bytes.fromhex('0301010100010101')
MSG_TICKET_LONG_START=HDR_D0+bytes.fromhex('0114d1000004'+'110a103008010000')
MSG_TICKET_LONG_END=bytes.fromhex('01'*260)
MSG_TICKET_TIME_START_2=HDR_D0+bytes.fromhex('0060'+'d100'+'0005'+'110a'+'401054000000')
MSG_TICKET_TIME_END_2=bytes.fromhex('d1d4fefe'+'01'*8+'75686c642f76686f656e76722f626e6c'+
'01'*48+'240e0e67')
###########################
def take_ticket (indata):
    ticket=indata.hex(' ').split(' ')
    hex_numbers = [ticket[len(ticket)-8], ticket[len(ticket)-7], ticket[len(ticket)-6], ticket[len(ticket)-5]]
    dec_numbers = [int(hex, 16) for hex in hex_numbers]
    for i in range(0, len(dec_numbers)):
        if dec_numbers[i]%2==0: 
            dec_numbers[i]=(dec_numbers[i]+1)
        else:
            dec_numbers[i]=(dec_numbers[i]-1)
    return (bytearray(dec_numbers)) # да, можно было бы напрямую работать с hex
def my_send (mybyte):
    s.sendto(mybyte, ('192.168.1.1', BROADCAST_CAM_PORT))
    print ('I SEND: ', mybyte)
fnum=0 # счетчик для кадров MJPEG
def take_full_jpeg (jpeg_data):
    jpeg_return=bytes.fromhex(''.join(jpeg_data[4:]))
    data_send=['d201','0001']
    data_send.append(jpeg_data[3])
    my_send (HDR_D1+pack_size(''.join(data_send))+bytes.fromhex(''.join(data_send)))
    jpeg_recvdata=s.recvfrom(4096)[0]
    while jpeg_recvdata.find(b'\xff\xd9') == -1 : 
        jpeg_return=jpeg_return+jpeg_recvdata[8:]
        data_send.clear()
        data_send=['d201','0001']
        data_send.append(jpeg_recvdata[6:8].hex())
        my_send (HDR_D1+pack_size(''.join(data_send))+bytes.fromhex(''.join(data_send)))
        if (jpeg_recvdata[4:6]!= b'\xd1\x01') : 
            tmp=s.recvfrom(4096)[0]
            recive_explain(tmp)
        jpeg_recvdata=s.recvfrom(4096)[0]
    if jpeg_recvdata.find(b'\xff\xd9') != -1 :
        print ('This is the end!')
        jpeg_return=jpeg_return+jpeg_recvdata[8:]
    global fnum
    fnum=fnum+1
    t = time.localtime() 
    current_time = time.strftime("%D %H:%M:%S", t) # на каждый кадр наносим метку с датой и временем
    myfont = ImageFont.truetype("arial.ttf", 20)
    try:
        io_bytes = io.BytesIO(jpeg_return)
        im = Image.open(io_bytes)
        draw_text = ImageDraw.Draw(im)
        draw_text.text((10,10),current_time,fill=('#1C0606'), font=myfont)
        im.save('D:\\pywrk\\cam\\my_jpeg\\pic'+str(fnum)+'.jpeg')
    except:
        pass
pac_num=list() # список с номерами полученных от камеры пакетов
def answer_to_cam(datinlist):
    k='d200'
    global pac_num
    if datinlist[2] == 'd101' : 
        k='d201'
        pac_num.clear()
        if (datinlist[4]=='ffd8') : take_full_jpeg(datinlist)
    if datinlist[3] in pac_num :
        pac_num.clear()
        pac_num.append (datinlist[3])
    else : 
        pac_num.append (datinlist[3])
    data_send=[k,'0001']
    for x in range(0, len(pac_num)):data_send.append(pac_num[x])
    my_send (HDR_D1+pack_size(''.join(data_send))+bytes.fromhex(''.join(data_send)))
def recive_explain(mydata):
    partion=mydata.hex()
    data_in_list=[]
    for x in range (0, len (partion), 4) :
        if (x>len (partion)) : break
        data_in_list.append(partion[x:x+4])
    if data_in_list[0]=='f1d0' :
        answer_to_cam(data_in_list)
    if data_in_list[0]=='f1d1' :
        print ('')
    if data_in_list[0]=='f1e0' :
        my_send (MSG_E1_ANSW)
        my_send (MSG_E0_Q)
    if data_in_list[0]=='f1e1' :    
        print ('#cam answer tel - Fine!')
    if data_in_list[0]=='f142' :
        print ('#cam send to tel MSG_HELLO')
    return (data_in_list[0])
def main():
    i=0
    my_send (MSG_HELLO)
    my_send (MSG_E0_Q)
    while (recive_explain(s.recvfrom(4096)[0])) != 'f1e1' : print ('In while f1e0')
    my_send (MSG_LGN_ADMIN)
    data=s.recvfrom(4096)
    while data[0].find(b'\xf1\xd0\x00\x18') != 0 :  
        data=s.recvfrom(4096)
        recive_explain(data[0])
    my_ticket=take_ticket(data[0])
    print(f"my_ticket - {my_ticket}")
    my_send (MSG_E0_Q)
    recive_explain(s.recvfrom(4096)[0])
    my_send (MSG_TICKET_TIME_START+my_ticket+MSG_TICKET_TIME_END)
    my_send (MSG_TICKET_START+my_ticket)
    while (recive_explain(s.recvfrom(4096)[0])) != 'f1d0' : print ('In while d0')
    for i in range(0, 15):
        what_rec=recive_explain(s.recvfrom(4096)[0])
        if what_rec == 'f1e0' : break
    my_send (MSG_TICKET_START_2+my_ticket+MSG_TICKET_END_2) #то, самое "серьезное" предложение
    my_send (MSG_TICKET_LONG_START+my_ticket+MSG_TICKET_LONG_END)
    my_send (MSG_TICKET_TIME_START_2+my_ticket+MSG_TICKET_TIME_END_2)
    while True:
        tt=recive_explain(s.recvfrom(4096)[0]) #получаем постоянный поток кадров в формате jpeg
if __name__ == "__main__":
    main()

Результат работы программы, мой Кадр – кошка Фрося.

P.S. 2
Нашёл это https://github.com/DavidVentura/cam-reverse «сокровище» уже после своих мучений.

Комментарии (30)


  1. DanilinS
    25.04.2024 04:56
    +1

    А прошивку кто разбирал?  Взаимодействие с IP 170.106.50.82, 146.56.226.66 и 35.156.204.247 анализировалось?


    1. jpegqs
      25.04.2024 04:56
      +1

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


    1. sergios52 Автор
      25.04.2024 04:56
      +1

      К сожалению до дампа прошивки не добрался)))) Но, судя по сообщениям с роутера об активных соединениях (у меня OpenWRT) запросы на эти IP эпизодические и кратковременные.


  1. DrBulkin
    25.04.2024 04:56
    +3

    Вот мне бы столько свободного времени ...


    1. sergios52 Автор
      25.04.2024 04:56
      +1

      )))) на меня бывает накатит какое-то непреодолимое желание разобраться с тем что не понятно, а там и на время уже не смотришь


  1. jpegqs
    25.04.2024 04:56

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


    1. sergios52 Автор
      25.04.2024 04:56
      +1

      на сайте производителя TWX806 есть готовые коды на С с библиотеками для разных областей применения чипа (). Кроме того предусмотрена "плата разработчика".


      1. jpegqs
        25.04.2024 04:56

        Там предусмотрено чтение прошивки, или только запись? Можно ли перепрошить по этим примерам?


  1. MikeVC
    25.04.2024 04:56
    +1

    У меня была история колупал ради любопытства камеру на китайском коптере. Хотел поднять с нее поток по локалке. Перехватил команды и написал скетч на питоне который ее активирует. Команды вида:

    CTP: OPEN_RT_STREAMB {"op":"PUT","param":{"format":"0","h":"480","w":"640","fps":"30"}}

    оно должно валить поток MJPEG на порт 2224 но вот вопрос чем можно посмотреть видео в таком формате? Какой плеер это поддерживает ? Сниффером посмотрел поток на порт действительно валится, из него даже можно восстановить картинку jpeg


    1. milssky
      25.04.2024 04:56

      Попробуй VLC. Это скорее всего RTP поток


      1. MikeVC
        25.04.2024 04:56

        пробовал "rtsp://192.168.1.1:2224/mjpg" не работает

        Я так понимаю, там все очень примитивно. На принимающей стороне надо открыть порт 2224 и тупо слушать на нем поток. Но как и чем это сделать ?


        1. jpegqs
          25.04.2024 04:56

          Можно направить через stdin в ffplay -.


          1. MikeVC
            25.04.2024 04:56

            в VLC "rtp://@:2224" будет прослушивать порт или это не то ?


            1. jpegqs
              25.04.2024 04:56
              +1

              Я не знаю что там через порт у вас подаётся и в каком формате, есть ли там какие-то заголовки поверх mjpeg или нет, и какой синтаксис адресов у VLC.
              ffplay это примитивный проигрыватель из ffmpeg, он должен mjpeg распознать, если там никаких лишних данных в потоке нет.


              1. MikeVC
                25.04.2024 04:56

                Общения как в протоколе RTSP точно нет. В начале пакетов с потоком есть JFIF потом зачемто все символы по порядку и сама картинка. И так последовательность картинок jpeg


                1. jpegqs
                  25.04.2024 04:56

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


        1. orgus
          25.04.2024 04:56

          Опишите ваш поток в sdp файле и откройте через vlc или ffplay из ffmpeg. Если там действительно простой rtp поток.


    1. alex1478
      25.04.2024 04:56

      Gstreamer udpsrc


  1. Vassilij
    25.04.2024 04:56

    Интересно, один я ждал, когда он их спалит?


    1. sergios52 Автор
      25.04.2024 04:56
      +1

      )))) одну спалил. Но, исключительно в честь больших познаний!


  1. almaz1c
    25.04.2024 04:56
    +1

    Реверс-инжиниринг. Устоявшийся термин, кмк. Обратный инжиниринг, обратная разработка... Как только не пытаются перевести то, что переводить не нужно.


  1. Javian
    25.04.2024 04:56

    офф А по логу можно что-то узнать какое ПО, какой производитель и т.п.

    Есть вебкамера без надписей без модели, веб интерфейс запаролен, видеопоток по RTSP требует пароль. Что это и как добраться до пароля мне не понято. Сохранил лог загрузки и дамп ПЗУ - был бы благодарен за подсказку как из дампа получить разделы/файлы.

    Hidden text
    =~=~=~=~=~=~=~=~=~=~=~= PuTTY log 2024.03.15 15:06:00 =~=~=~=~=~=~=~=~=~=~=~=
    net_print_ip_log, line:753] wlan1 ip: 192.168.66.1
    audio_enable=0, cam_enable=1
    qr_cnt = 42, average tick = 238 ms
    audio_enable=0, cam_enable=1
    >>>>>>RTC: write 1678412147
    qr_cnt = 42, average tick = 238 ms
    audio_enable=0, cam_enable=1
    
    
    Login timed out 
    process '/usr/bin/login.sh' (pid 1157) exited. Scheduling for restart.
    
    Please press Enter to activate this console. qr_cnt = 43, average tick = 237 ms
    APL_SHOWSTAT_WIFI_TOBE_CONFIG
    [net_print_ip_log, line:753] wlan1 ip: 192.168.66.1
    audio_enable=0, cam_enable=1
    qr_cnt = 43, average tick = 237 ms
    audio_enable=0, cam_enable=1
    ROM:Use nor flash.
    
    ROM:Init DDR..Training done. 
    
    ROM:Ok
    
    
    
    U-Boot 2010.06-dirty (Feb 01 2021 - 22:09:18)
    
    
    DRAM:  64 MiB
    
    master [ctl : mem] = [0 : 0]
    
    SF: Got idcode 52 22 17 52 22
    
    use default flash ops...
    
    spi_flash_probe_default multi wire open flag is 0
    
    Net:   FH EMAC
    
    Press 'E' to stop autoboot:  1  0 
    
    master [ctl : mem] = [0 : 0]
    
    SF: Got idcode 52 22 17 52 22
    
    use default flash ops...
    
    spi_flash_probe_default multi wire open flag is 0
    
    verify flash image OK
    
    gpio 28 dir out val 0
    
    result: out, 0
    
    gpio 4 dir out val 0
    
    result: out, 0
    
    gpio 5 dir out val 0
    
    result: out, 0
    
    gpio 0 dir out val 0
    
    result: out, 0
    
    gpio 1 dir out val 0
    
    result: out, 0
    
    gpio 2 dir out val 0
    
    result: out, 0
    
    gpio 3 dir out val 0
    
    result: out, 0
    
    gpio 6 dir out val 0
    
    result: out, 0
    
    gpio 7 dir out val 0
    
    result: out, 0
    
    gpio 50 dir out val 0
    
    result: out, 0
    
    gpio 51 dir out val 0
    
    result: out, 0
    
    load kernel 0x00050000(0x002e0000) to 0xa1000000
    
    ## Booting kernel from Legacy Image at a1000000 ...
    
       Image Name:   Linux-3.0.8
    
       Created:      2021-03-20   3:09:08 UTC
    
       Image Type:   ARM Linux Kernel Image (uncompressed)
    
       Data Size:    2813808 Bytes = 2.7 MiB
    
       Load Address: a0008000
    
       Entry Point:  a0008000
    
       Verifying Checksum ... OK
    
       Loading Kernel Image ... OK
    
    OK
    
    prepare atags
    
    
    Starting kernel ...
    
    
    Uncompressing Linux... done, booting the kernel.
    [    0.000000] Linux version 3.0.8 (szfullhan@ubuntu) (gcc version 5.5.0 (b220190606) ) #1 Sat Mar 20 11:09:06 CST 2021
    [    0.000000] CPU: ARMv6-compatible processor [410fb767] revision 7 (ARMv7), cr=00c5387d
    [    0.000000] CPU: VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
    [    0.000000] Machine: FH8626V100
    [    0.000000] Memory policy: ECC disabled, Data cache writeback
    [    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 10160
    [    0.000000] Kernel command line: console=ttyS0,115200 ip=192.168.1.203 mem=40M mtdparts=spi_flash:64k(bootstrap),64k(uboot-env),192k(uboot),3M(kernel),512k(data),-(app)
    [    0.000000] PID hash table entries: 256 (order: -2, 1024 bytes)
    [    0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
    [    0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
    [    0.000000] Memory: 40MB = 40MB total
    [    0.000000] Memory: 35628k/35628k available, 5332k reserved, 0K highmem
    [    0.000000] Virtual kernel memory layout:
    [    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
    [    0.000000]     fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
    [    0.000000]     DMA     : 0xffc00000 - 0xffe00000   (   2 MB)
    [    0.000000]     vmalloc : 0xc3000000 - 0xfe000000   ( 944 MB)
    [    0.000000]     lowmem  : 0xc0000000 - 0xc2800000   (  40 MB)
    [    0.000000]     modules : 0xbf000000 - 0xc0000000   (  16 MB)
    [    0.000000]       .init : 0xc0008000 - 0xc00df000   ( 860 kB)
    [    0.000000]       .text : 0xc00df000 - 0xc047e000   (3708 kB)
    [    0.000000]       .data : 0xc047e000 - 0xc04a3e60   ( 152 kB)
    [    0.000000]        .bss : 0xc04a3e84 - 0xc04cd294   ( 166 kB)
    [    0.000000] SLUB: Genslabs=13, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
    [    0.000000] NR_IRQS:128
    [    0.000000] timer mult: 0xc8000000, timer shift: 0x19
    [    0.000000] sched_clock: 32 bits at 10MHz, resolution 100ns, wraps every 429496ms
    [    0.000000] Console: colour dummy device 80x30
    [    0.000000] console [ttyS0] enabled
    [    0.176853] Calibrating delay loop... 597.60 BogoMIPS (lpj=2988032)
    [    0.241246] pid_max: default: 32768 minimum: 301
    [    0.246022] Mount-cache hash table entries: 512
    [    0.250851] CPU: Testing write buffer coherency: ok
    [    0.256023] devtmpfs: initialized
    [    0.261490] NET: Registered protocol family 16
    [    0.267716] FH8626V100 board init
    [    0.346213] bio: create slab <bio-0> at 0
    [    0.352329] fh_dmac fh_dmac.0: FH DMA Controller, 6 channels
    [    0.359009] usbcore: registered new interface driver usbfs
    [    0.363981] usbcore: registered new interface driver hub
    [    0.368758] usbcore: registered new device driver usb
    [    0.377405] cfg80211: Calling CRDA to update world regulatory domain
    [    0.384579] Switching to clocksource fh_clocksource
    [    0.429681] NET: Registered protocol family 2
    [    0.432785] IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
    [    0.439844] TCP established hash table entries: 2048 (order: 2, 16384 bytes)
    [    0.446526] TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
    [    0.452773] TCP: Hash tables configured (established 2048 bind 2048)
    [    0.459005] TCP reno registered
    [    0.462149] UDP hash table entries: 256 (order: 0, 4096 bytes)
    [    0.467936] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
    [    0.474560] NET: Registered protocol family 1
    [    0.479030] RPC: Registered named UNIX socket transport module.
    [    0.484372] RPC: Registered udp transport module.
    [    0.488986] RPC: Registered tcp transport module.
    [    0.493675] RPC: Registered tcp NFSv4.1 backchannel transport module.
    [    0.918449] squashfs: version 4.0 (2009/01/31) Phillip Lougher
    [    0.944899] JFFS2 version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
    [    0.960764] exFAT: Version 1.2.9
    [    0.967781] msgmni has been set to 69
    [    0.981087] NET: Registered protocol family 38
    [    0.984113] io scheduler noop registered (default)
    [    1.005731] ttyS.0: ttyS0 at MMIO 0xf0700000 (irq = 18) is a ttyS
    [    1.020356] ttyS.1: ttyS1 at MMIO 0xf0800000 (irq = 19) is a ttyS
    [    1.027066] ttyS.2: ttyS2 at MMIO 0xf1300000 (irq = 20) is a ttyS
    [    1.053694] brd: module loaded
    [    1.086582] CLK misc driver init successfully
    [    1.136994] m25p80 spi0.0: unrecognized JEDEC id 522217
    [    1.141170] m25p80 spi0.0: Try default64
    [    1.145398] m25p80 spi0.0: found default64, expected m25p80
    [    1.151514] m25p80 spi0.0: set_qe : 249  default not support multi wire..
    [    1.158894] m25p80 spi0.0: default64 (8192 Kbytes)
    [    1.164138] DEBUG-CMDLINE-PART: parsing <64k(bootstrap),64k(uboot-env),192k(uboot),3M(kernel),512k(data),-(app)>
    [    1.175274] DEBUG-CMDLINE-PART: partition 5: name <app>, offset ffffffff, size ffffffff, mask flags 0
    [    1.185330] DEBUG-CMDLINE-PART: partition 4: name <data>, offset ffffffff, size 80000, mask flags 0
    [    1.195209] DEBUG-CMDLINE-PART: partition 3: name <kernel>, offset ffffffff, size 300000, mask flags 0
    [    1.205376] DEBUG-CMDLINE-PART: partition 2: name <uboot>, offset ffffffff, size 30000, mask flags 0
    [    1.215356] DEBUG-CMDLINE-PART: partition 1: name <uboot-env>, offset ffffffff, size 10000, mask flags 0
    [    1.225715] DEBUG-CMDLINE-PART: partition 0: name <bootstrap>, offset ffffffff, size 10000, mask flags 0
    [    1.236075] DEBUG-CMDLINE-PART: mtdid=<spi_flash> num_parts=<6>
    [    1.242547] 6 cmdlinepart partitions found on MTD device spi_flash
    [    1.249274] Creating 6 MTD partitions on "spi_flash":
    [    1.254814] 0x000000000000-0x000000010000 : "bootstrap"
    [    1.280773] 0x000000010000-0x000000020000 : "uboot-env"
    [    1.308159] 0x000000020000-0x000000050000 : "uboot"
    [    1.333656] 0x000000050000-0x000000350000 : "kernel"
    [    1.359264] 0x000000350000-0x0000003d0000 : "data"
    [    1.384651] 0x0000003d0000-0x000000800000 : "app"
    [    1.435711] console [netcon0] enabled
    [    1.438119] netconsole: network logging started
    [    1.472086] resource: start=e0700000, len=00100000
    [    1.475801] base=0xc3200000 (after adjust) 
    [    1.480342] fh_otg_driver_probe: mapped PA 0xe0700000 to VA 0xc3200000
    [    1.587315] Core Release: 3.30a
    [    1.589159] Setting default values for core params
    [    1.793905] dma_enable :1
    [    1.795168] dma_desc_enable :1
    [    1.998055] Using Descriptor DMA mode
    [    2.000486] Periodic Transfer Interrupt Enhancement - disabled
    [    2.006831] Multiprocessor Interrupt Enhancement - disabled
    [    2.012936] OTG VER PARAM: 0, OTG VER FLAG: 0
    [    2.017671] FH OTG HCD INIT (c2074e80)
    [    2.021781] hcd regs before base(c3200000)
    [    2.026295] fh_otg fh_otg: FH OTG Controller
    [    2.031070] fh_otg fh_otg: new USB bus registered, assigned bus number 1
    [    2.038254] fh_otg fh_otg: irq 27, io mem 0x00000000
    [    2.043683] Init: Power Port (0)
    [    2.047295] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
    [    2.054586] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
    [    2.062456] usb usb1: Product: FH OTG Controller
    [    2.067469] usb usb1: Manufacturer: Linux 3.0.8 fh_otg_hcd
    [    2.073476] usb usb1: SerialNumber: fh_otg
    [    2.084700] hub 1-0:1.0: USB hub found
    [    2.087234] hub 1-0:1.0: 1 port detected
    [    2.118745] rtc GET CORE REG TIMEOUT line 349
    [    2.121944] rtc get time:rtc core busy
    [    2.126001] rtc get time:rtc core busy
    [    2.130105] rtc get time:rtc core busy
    [    2.134198] fh rtc get time error
    [    2.137791] rtc get time:rtc core busy 335
    [    2.152261] fh_rtc fh_rtc.0: rtc core: registered rtc as rtc0
    [    2.157824] rtc get time:rtc core busy
    [    2.161093] rtc get time:rtc core busy
    [    2.165128] rtc get time:rtc core busy
    [    2.169213] rtc get time:rtc core busy
    [    2.173335] rtc get time:rtc core busy
    [    2.177389] rtc get time:rtc core busy
    [    2.181493] rtc get time:rtc core busy
    [    2.185561] rtc get time:rtc core busy
    [    2.189646] rtc get time:rtc core busy
    [    2.193759] rtc get time:rtc core busy
    [    2.197820] rtc get time:rtc core busy
    [    2.201926] rtc get time:rtc core busy
    [    2.206000] rtc get time:rtc core busy 335
    [    2.210477] rtc get time:rtc core busy
    [    2.214548] rtc get time:rtc core busy 335
    [    2.219014] rtc get time:rtc core busy
    [    2.223115] rtc get time:rtc core busy
    [    2.230548] i2c /dev entries driver
    [    2.239935] I2C driver:
    [    2.239951] platform registration... 
    [    2.245032] Clock: 20000khz, Standard-mode HCNT:LCNT = 83:99
    [    2.251418] tx fifo depth: 16, rx fifo depth: 16
    [    2.267235] I2C - (dev. name: fh_i2c - id: 0, IRQ #9
    [    2.267249] IO base addr: 0xc30a0000)
    [    2.275439] I2C driver:
    [    2.275451] platform registration... 
    [    2.282002] Clock: 20000khz, Standard-mode HCNT:LCNT = 83:99
    [    2.288378] tx fifo depth: 16, rx fifo depth: 16
    [    2.314587] I2C - (dev. name: fh_i2c - id: 1, IRQ #10
    [    2.314602] IO base addr: 0xc30a8000)
    [    2.322901] I2C driver:
    [    2.322913] platform registration... 
    [    2.329423] Clock: 20000khz, Standard-mode HCNT:LCNT = 83:99
    [    2.335860] tx fifo depth: 16, rx fifo depth: 16
    [    2.341628] Indeed it is in host mode hprt0 = 00021501
    [    2.416702] I2C - (dev. name: fh_i2c - id: 2, IRQ #11
    [    2.416717] IO base addr: 0xc30b0000)
    [    2.434753] WARN: set clk wdt_clk to 1000000, but get 1004132
    [    2.461113] card0 disconnected!
    [    2.480317] TCP cubic registered
    [    2.482261] NET: Registered protocol family 17
    [    2.487144] lib80211: common routines for IEEE802.11 drivers
    [    2.493346] Registering the dns_resolver key type
    [    2.498487] VFP support v0.3: implementor 41 architecture 1 part 20 variant b rev 5
    [    2.520446] usb 1-1: new high speed USB device number 2 using fh_otg
    [    2.542063] Indeed it is in host mode hprt0 = 00001101
    [    2.611441] GMAC driver:
    [    2.611458] platform registration... 
    [    2.616623] using random MAC address: fa:90:c5:88:4e:76
    [    2.648250] fh_gmac fh_gmac.0: eth0: mixed HW and IP checksum settings.
    [    2.653954] fh_gmac fh_gmac.0: eth0: mixed no checksumming and other settings.
    [    2.662006] eth0 - (dev. name: fh_gmac - id: 0, IRQ #13
    [    2.662020] IO base addr: 0xc30d0000)
    [    2.684070] fh rtc get time error
    [    2.686137] fh_rtc fh_rtc.0: setting system clock to 2059-09-19 08:04:03 UTC (2831184243)
    [    2.735372] aes driver registered
    [    2.760307] usb 1-1: New USB device found, idVendor=8065, idProduct=6000
    [    2.766045] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
    [    2.773882] usb 1-1: Product: iComm USB
    [    2.778017] usb 1-1: Manufacturer: iComm
    [    2.782317] usb 1-1: SerialNumber: 1234
    [    2.935029] gmac_rmii: probed
    [    2.936996] eth0: PHY ID 937c4023 at 0 IRQ -1 (0:00) active
    [    2.943925] fh_gmac fh_gmac.0: eth0: mixed HW and IP checksum settings.
    [    2.949992] fh_gmac fh_gmac.0: eth0: mixed no checksumming and other settings.
    [    2.970174] IP-Config: Guessing netmask 255.255.255.0
    [    2.974418] IP-Config: Complete:
    [    2.977626]      device=eth0, addr=192.168.1.203, mask=255.255.255.0, gw=255.255.255.255,
    [    2.986276]      host=192.168.1.203, domain=, nis-domain=(none),
    [    2.992859]      bootserver=255.255.255.255, rootserver=255.255.255.255, rootpath=
    [    3.010942] Freeing init memory: 860K
    
    starting pid 494, tty '': '/etc/init.d/rcS'
    [RCS]: /etc/init.d/S01udev
    Starting udev:      [ OK ]
    [RCS]: /etc/init.d/S02init_rootfs
    init_rootfs begin
    target=release
    /bin/mount -t squashfs /dev/mtdblock5 /app
    /bin/mount -t jffs2 /dev/mtdblock4 /app/userdata
    init_rootfs OK
    [RCS]: /etc/init.d/S03network
    [RCS]: /etc/init.d/S04app
    Replace /usr/bin/iu.sh v7.1 with /app/iu.sh v7.2
    Replace /usr/bin/myinfo.sh v3.8 with /app/myinfo.sh v4.0
    Replace /usr/bin/sd_hotplug.sh v1.3 with /app/sd_hotplug.sh v1.6
    Replace /usr/bin/noodles v8.9 with /app/abin/noodles v9.5
    Replace /usr/bin/img_up v8.1 with /app/bin/img_up v8.7
    Replace /usr/bin/fw_printenv v1.7 with /app/bin/fw_printenv v2.0
    Current prodid: PQEWN-01
    =============================================
    Kernel version : 3.0.8
    SDK version    : FH8626V100_IPC_V1.0.0_20190930
    patch:FH8626V100_IPC_V1.0.0.FP33_20210112
    Model name     : AJL33PC0862
    FW version     : v210602.1420
    =============================================
    Sat Jan  1 00:00:00 CST 2000
    ifconfig: SIOCSIFHWADDR: Device or resource busy
    vmm with 23488K
    insmod /app/modules/vmm.ko mmz=anonymous,0,0xa2800000,23488K anony=1
    insmod /app/modules/rtvbus.ko ra=0xa3ef0000 rs=65536 fn=rtthread_arc.bin fa=0xa3f00000
    insmod /app/modules/media_process.ko
    insmod /app/modules/isp.ko
    insmod /app/modules/enc.ko
    insmod /app/modules/jpeg.ko
    insmod /app/modules/bgm.ko
    insmod /app/modules/vbus_ac.ko
    insmod /app/modules/gpio_wave.ko GW_TIMER_INTERVAL=100
    insmod /app/modules/pwmv2-fullhan.ko
    insmod /app/modules/ssv6x5x.ko stacfgpath=/lib/firmware/ssv6x5x/ssv6x5x-wifi.cfg
    [   10.642964] SSV6XXX HCI TX Task started.
    sensor_probe(v3.0): auto probe sensor
    gc1054_mipi
    echo "cap_0_1920_1080" > /proc/driver/vpu
    echo "cap_1_640_360" > /proc/driver/vpu
    echo "cap_2_640_360" > /proc/driver/vpu
    echo "buf_0_1" > /proc/driver/vpu
    echo "buf_1_2" > /proc/driver/vpu
    echo "buf_2_2" > /proc/driver/vpu
    [ut_cmd_server_init, line:115] INFO: cmd server init ok: #sh_server
    srv_system[/app/wifi_mode.sh sta start]
    exec cmd: "/app/wifi_mode.sh sta start"
    
    starting pid 906, tty '': '/sbin/inetd -f -e /etc/inetd.conf'
    
    Please press Enter to activate this console. @@@@@@@@@@ NOODLES v9.5 START @@@@@@@@@@@@@@@@@
    [   12.868789] SSV WLAN driver SSV6006D: Set new macaddr
    [   12.877806] SSV WLAN driver SSV6006D: VIF 84:ea:97:10:db:26 of type 2 is added.
    Network config wlan0
         ret=0 WIFEXITED(ret)=1 WEXITSTATUS(ret)=0
    Run netcfg: wlan0
    srv_system[udhcpc -p /var/lock/udhcpc_wlan0.pid -t 30 -T 1 -b -s /usr/share/udhcpc/default.script -i wlan0 &]
    exec cmd: "udhcpc -p /var/lock/udhcpc_wlan0.pid -t 30 -T 1 -b -s /usr/share/udhcpc/default.script -i wlan0 &"
         ret=0 WIFEXITED(ret)=1 WEXITSTATUS(ret)=0
    set wlan0 dns 114.114.114.114
    set wlan0 dns 8.8.8.8
    udhcpc: started, v1.26.2
    Setting IP address 0.0.0.0 on wlan0
    @@@@@@@@@@@@@@@@@ MainApp START @@@@@@@@@@@@@@@@@
    ver:YGT.AJL33PC0862-v210602.1420
    Set timezone="CST-8", daylight="false"
    Set TZ=PST-8:00
    app_system[echo CST-8 > /etc/TZ]
    srv_system[echo CST-8 > /etc/TZ]
    exec cmd: "echo CST-8 > /etc/TZ"
         ret=0 WIFEXITED(ret)=1 WEXITSTATUS(ret)=0
    remote sytem: cmd="echo CST-8 > /etc/TZ", result="0"
    Create timer: apl_timer_watchdog
    [apl_watchdog_open, line:83] INFO: Enable watchdog
    telnetd started
    
    process '/sbin/inetd -f -e /etc/inetd.conf' (pid 906) exited. Scheduling for restart.
    ftpd stopped
    enter 1890
    set service avbuf_size=524288
    Set sensor: gc1054_mipi
    Set sensor width: 1280
    Set sensor height: 720
    enter 1899
    [dsp] version: V1.0.0.P16(gec43063),build: 2020-04-17
    
    starting pid 984, tty '': '/sbin/inetd -f -e /etc/inetd.conf'
    >>>>>>RTC: write 1678412207
    !!!FH_SYS_Init ok
    [gpio_ircon]5
    [gpio_ircoff]4
    [gpio_infrared_val]0
    [gpio_infrared]27
    [gpio_white_light_val]0
    [gpio_white_light]28
    [gpio_signal]26
    [gpio_ao_mute_val]1
    [gpio_ao_mute]24
    [gpio_sensor_reset]13
    [pan_motor]1
    [tilt_motor]1
    [pan_distance]1028
    [tilt_distance]154
    [pan_invert]1
    [tilt_invert]1
    [pan_delay]4
    [tilt_delay]12
    [pan_visc]0
    [tilt_visc]0
    ptz_init_delay= 0
    [audio_vol]100
    [audio_micvol]2
    [ai_period]320
    [ao_period]320
    [ai_ns_enable]1
    [ai_ns_level]3
    [ai_mute_when_ptz]4
    [voice_end_timeout]1000
    [audio_in]MIC
    [audio_out]LINE
    [rcmode]avbr
    [sadc_ldr]0
    [daynight_forbid_time]600
    [daynight_forbid_time_in_white]30
    >>>>>>>>>>>>>>>>>>>>>>>>ldr_region(): [0,2500,day],[2100,-1,night]
    g_service_ldr_positive = 0
    g_service_ldr_region[0] = [0,2500,day]
    g_service_ldr_region[1] = [2100,2147483647,night]
    service_jpeg_init
    jpg cfg[0]: chan[0] disabled
    jpg cfg[1]: chan[1] resize_mode[2] qp[76] speed[4] buf_limit[-1]
    jpg buffer limit size: 65536
    enter 1904
    !!!FH_VPSS_SetViAttr ok . width = 1280, height = 720
    !!!FH_VPSS_Enable ok
    isp_check_format:width=1280, height=720, framerate=25.000000, sensor format=3(0x00000003)
    [isp] version:V1.0.0.P22(g86d2dc5),build: 2020-05-24
    [ispcore] version:V1.0.0.P25(g2e77cc7),build: 2020-06-09
    ADV_ISP version: V1.0.0.P30(g4e9112d), build: 2020-11-26
    probe sensor: gc1054_mipi
    [sensor_gpios] not defined!
    [mipi] version:V1.0.0.P6(gccfcfe6),build: 2019-11-27
    [sensor_gpios] not defined!
    !!!API_ISP_Init ok
    app_system[echo "cis_clk_out,enable,16000000" > /proc/driver/clock]
    srv_system[echo "cis_clk_out,enable,16000000" > /proc/driver/clock]
    exec cmd: "echo "cis_clk_out,enable,16000000" > /proc/driver/clock"
         ret=0 WIFEXITED(ret)=1 WEXITSTATUS(ret)=0
    remote sytem: cmd="echo "cis_clk_out,enable,16000000" > /proc/driver/clock", result="0"
    set cis_clk 16000000
    [service_load_scene_hex, line:174] INFO: Get sensor data ok: scene=0, style=0
    isp param version is not compitable with current setting!
    !!!FHAdv_Isp_Init ok
    g_service_bus_ircut 1
    night_light_on = 0
    [_service_bus_light_ctrl, line:848] INFO: g_service_night_light_on = 0, g_service_white_light = -1
    [_service_bus_light_ctrl, line:901]
    [_service_bus_light_ctrl, line:907] INFO: set g_service_gpio_white_light:1
    [_service_bus_light_ctrl, line:912] INFO: set g_service_gpio_infrared:1
    service_venc_start_org<0>: { width<1920>height<1080>fr<16.660000>rc<1>level<182>bitrate<786432>keyinv<100>smart<2>} 
    [_service_venc_start, line:1606] INFO: FH_SMART_H264
    [_service_venc_start, line:1772] INFO: FH_RC_H264_AVBR
    FH_START_CHANNEL<0>: { width<1920>height<1080>fr<16.660000>rc<1>level<182>bitrate<786432:lv 0>keyinv<100>} 
    !!!FH_VPSS_SetChnAttr<0> ok
    !!!FH_VPSS_OpenChn<0> ok
    !!!FH_VPSS_SetFramectrl<0> ok
    !!!FH_VENC_CreateChn<0> ok


    1. Kurochkin
      25.04.2024 04:56
      +1

      Не веб, ip-камера.

      Производитель не особо важен , а чипы все у вас в логе указаны - начинайте копать с FH8... (FullHan), если повезёт - найдется что-то вроде OpenIPC под ваше железо.


      1. NutsUnderline
        25.04.2024 04:56
        +1

        поддерживают OpenIPC некоторые чипсеты от них https://github.com/OpenIPC/firmware/tree/master/br-ext-chip-fullhan

        но работа в зачаточном состоянии, готового, точнее ни гарантированного рецепта на прошивку нет ни гарантий работы


    1. NutsUnderline
      25.04.2024 04:56
      +2

      дамп еще через uboot можно считать.

      есть несколько утилит которые сканируют и разбирают образ памяти на части, плюс в документике на проц частенько бывают адреса (смещения в дампе) . Есть конечно кое какие распаковщики для windows, но в целом для этого надо в линуксы ходить. Есть например шикарная binwalk, (winbinwalk для windows), есть пакет firmware-mod-kit (но он не обновляется, старый довольно таки). ну или копаться в heх

      uboot там в начале, потом переменные uboot (уже много чего можно сотворить, даже root консоль получить, их редактируя, но главное там есть адреса в прошивке), потом ядро, потом rootfs.

      ищем строчки вида

      mtdparts=sfc:256K(boot),1664K(kernel),14464K(rootfs)

      bootcmd=

      rootfstype=

      root=/dev/

      rootfs обычно нетрудно определить, подобрать утилиту, распаковать. Но самое интересное может быть спрятано в упакованном ядре. Его проще через binwalk в несколько проходов


    1. sergios52 Автор
      25.04.2024 04:56
      +1

      @Kurochkinда, наверное это выход!
      https://github.com/OpenIPC/firmware там много информации есть полезной
      А в целом, раз Вы к ней прицепились putty, то попробуйте поиграть с ssh, telnet, tftp. Перепрошить можно без особых доп. девайсов через uart ил тот же tftp.


  1. NutsUnderline
    25.04.2024 04:56
    +1

    меня друг просил спросить: а не опасно ли нонче брать девайсы такого вида


    1. sergios52 Автор
      25.04.2024 04:56

      ))) это не hidden камера, у нее нет признаков скрытности (подделки под игрушку или ручку, например). А если вопрос в отслеживании сторонними серверами, то это так на любом худо-бедно обмозгованном гаджете с выходом в интернет.


  1. NutsUnderline
    25.04.2024 04:56

    я вот не совсем понял пока что: на этой плате нет uboot а свой загрузчик или же вывод его не показан (сразу с подачи питания смотрим, весьма вероятно что на другой скорости) или же он идет другим путем (заблокирован). чрез uboot то ведь вполне дамп можно сделать


    1. sergios52 Автор
      25.04.2024 04:56

      к сожалению uboot в понимании linux kernel на этих мини камерах нет.