红米音箱固件更新检查逻辑



前一篇,看到了https的协议内容,其中使用了 ota check 检查固件版本,但是实测返回出来的内容是一个只有3k不到的 HDR 开头的文件,猜测这个文件应该是一个加密或者压缩后的response,例如json。

ota这个命令在 /bin/ota,本身是个 shell 脚本,直接读内容,可以看到所有的命令调用的都是 matool 以及它的各个 symlink。其中命令

执行 ota ble,输出如下。(输出被我掐了,因为我怕直接进了更新,就没法调试了)

从charles里拿到rootfs的下载链接,找个linux下下来,直接 squashfuse rootfs_1.76.2_xxxxxx.bin /mnt/ 挂载了,可以看数据。

回过头来,研究协议和算法。

从 ota 这个脚本里看到,执行升级的时候,先把那个小文件下载为 /tmp/mico_ota.bin,再用 /bin/flash.sh /tmp/mico_ota.bin 。再从整个squashfs里找 “Start downloading” 这个字符串,发现在 /bin/skr 里。

再细看里边的代码,最终发现解包命令 miso -x xxx.bin,就在调用 skr 命令的前几行。解包完的目录里多了三个文件

其中 .json 文件里包含了 kernel 和 rootfs的下载链接。

再一个,检查更新的接口有个参数s,是一个签名参数。先ldd

再根据请求的关键词 countryCode,找到固件版本检查的接口构造方法在 libxiaomi_mico.so 里,ida 加载后发现一个 uuid “8007236f-a2d6-4847-ac83-c49395ad6d65”,

Google一搜,好多不同的小米设备都是用这个。大致算法如下



红米音箱固件更新检查逻辑 by @sskaje: https://sskaje.me/2021/04/redmi-play-firmware-upgrade-check/

红米音箱Play 开发调试实验 updating



前盖有内扣,拆好之后直接引三根针出来就可以ttl了。

密码 : substr(md5($SN . “5775B10D-15C0-7827-97B9-88EA07FCA97A”), 0, 14),hash salt在 /bin/mi_console 里写死了,根据设备型号判断。

串口波特率115200.

手动启动 ssh。

劫持流量,发现客户端不认第三方的https证书,错误提示是 SSL handshake with client failed: CA certificate could not be matched with a known, trusted CA (unknown_ca)。查了下libxiaomi_http.so,设置了CURLOPT_CAPATH /etc/ssl/certs,然而系统本身是squashfs直接挂载的ro,所以需要曲线救国。

ldd 查看 libxiaomi_http.so,发现引用了 libmbedtls.so libssl.so libcrypto.so,libcurl 的 vtls 里看了下实现,用了 这个函数,同时对比了各个实现,决定还是手工加一下证书。

鉴于系统是readonly挂载的,所以上 overlay 。

这样就可以在 /tmp/certs 里加证书,实现自定义ca。

具体操作我是在一台ubuntu上,把证书pem 文件命名为 .crt后缀放在 /usr/local/share/ca-certificates 下然后执行 update-ca-certificates 再去看 /etc/ssl/certs 里的symlink的hash。

我开发机的charles ca 证书 hash 是 6a3a5fb6.0,所以在我的小爱音箱里,我把证书 pem 文件copy到 /tmp/certs 然后 创建symlink。

再执行 ota check 的实话,观察charles,已经能看到ssl的请求了。



红米音箱Play 开发调试实验 updating by @sskaje: https://sskaje.me/2021/03/%e7%ba%a2%e7%b1%b3%e9%9f%b3%e7%ae%b1play-%e5%bc%80%e5%8f%91%e8%b0%83%e8%af%95%e5%ae%9e%e9%aa%8c-updating/

meilisearch ubuntu systemd



正在寻求ES的轻量化解决方案,看到了meilisearch,于是上手实验了一把。留了个systemd 配置笔记。

原始安装文档 https://docs.meilisearch.com/guides/advanced_guides/installation.html,官方给的 apt 的安装只有二进制文件,没有配置文件没有启动脚本。

简单来

/etc/default/meilisearch

/etc/systemd/system/meilisearch.service

启动



meilisearch ubuntu systemd by @sskaje: https://sskaje.me/2021/01/meilisearch-ubuntu-systemd/

古老壁挂炉接入米家App



北方自采暖家庭,用的还是最早开发商装的菲斯曼的壁挂燃气炉。2014年重装修时,没有下定决心更换壁挂炉,只是换了一个曼瑞德(manred)的无线温控器。

温控器 – 控制端
温控器 – 接收器

古老的温控器问题很多,例如屏幕显示效果差,老电阻屏的点击操作实在不灵,距离过远无法无线控制(南卧室北阳台),更可怕的是编程的规则掉电就没了。所以这个温控器最后沦为了无线开关,放在客厅,起床睡觉的时候自己点一下。

温控器 – 接收器 – 市电供电

壁挂炉的温控逻辑很简单,只需要把两根控制线短接,壁挂炉就开始进行加热。

无线温控器的原理也很简单,室内的温控端基于温度规则发送控制信号,室外的接收器执行通断。所以,一个能接入米家的继电器就能将这款老旧壁挂炉接入小米的智能家居生态里。搜了下淘宝,这么简单的模块(USB供电,接入米家),能找到最便宜的49,我准备下单的时候还得等13天才发货。放弃,从头整理需求。

  • 温度控制:小米有温湿度计,可以贴在各屋墙上;
  • 网络接入:小米的蓝牙网关插座可以接入家庭Wi-Fi,也可以用米家 App 控制交流电和 USB 供电的开关;
  • 加热控制:一个简单的继电器,用通断电的方式,直接控制温控器控制线的短接状态。
  • 智能规则:米家 App
小米蓝牙插座网关 及 改造的接线方案(实线部分)

目标明确后,淘宝上了买了个5.2元人民币的 microUSB 供电的继电器,翻出了家里多余的一个带 USB 的小米蓝牙网关,一根USB线。

microUSB 供电的继电器,有延时模块

其实买错了,带了延迟功能,不重要,短接一下就好,否则要不按下按钮隔一会儿自动断开。

短接效果示意图

接线的时候,接 COM 和 NO 端。

接线效果

这样一来,只要 USB 通电,继电器就工作,COM 和 NO 就接通了。如果想要默认接通,通电关闭,换用 COM + NC 的接线方式就行了。

接下来是米家的规则。App的智能 tab,创建规则。

米家 App 界面

温控器开启的规则

温控器关闭的规则



古老壁挂炉接入米家App by @sskaje: https://sskaje.me/2020/11/gas-boiler-mi-home/