9

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

 3 years ago
source link: https://sskaje.me/2021/04/redmi-play-firmware-upgrade-check/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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

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

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

case "$1" in
    success)
    set_upgrade_status success
    check)
    check
    check_and_upgrade $2 $3 $4
    upgrade)
    check_and_upgrade $2 $3 $4
    slient)
    slient_check_and_upgrade

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

root@L07A:~# ota ble
--2021-04-13 16:19:53--  https://cdn.cnbj1.fds.api.mi-img.com/xiaoqiang/rom/l07a/mico_skr_firmware_xxxx_1.76.2.bin
Resolving cdn.cnbj1.fds.api.mi-img.com... 220.194.223.76, 123.125.46.228, 2408:8706:0:5700:40::3, ...
Connecting to cdn.cnbj1.fds.api.mi-img.com|220.194.223.76|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2560 (2.5K) [application/octet-stream]
Saving to: '/tmp/mico_ota.bin'
/tmp/mico_ota.bin                                           100%[=========================================================================================================================================>]   2.50K  --.-KB/s    in 0.001s  
2021-04-13 16:19:53 (3.94 MB/s) - '/tmp/mico_ota.bin' saved [2560/2560]
Start downloading kernel :   100%
Start downloading rootfs :   100%

从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 命令的前几行。解包完的目录里多了三个文件

-rw-r--r--    1 root     root           559 Apr 13 16:38 mico_l07a_firmware.json
-rw-r--r--    1 root     root           396 Apr 13 16:38 system.cfg
-rw-r--r--    1 root     root           780 Apr 13 16:38 version

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

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

root@L07A:~# ldd /usr/bin/matool
/lib/ld-musl-armhf.so.1 (0xb6f44000)
libxiaomi_mico.so => /usr/lib/libxiaomi_mico.so (0xb6f08000)
libxiaomi_miot.so => /usr/lib/libxiaomi_miot.so (0xb6ef3000)
libmico-common.so => /usr/lib/libmico-common.so (0xb6ed0000)
libxiaomi_http.so => /usr/lib/libxiaomi_http.so (0xb6eba000)
libxiaomi_json.so => /usr/lib/libxiaomi_json.so (0xb6ea6000)
libxiaomi_crypto.so => /usr/lib/libxiaomi_crypto.so (0xb6e8b000)
libssl.so.1.0.0 => /usr/lib/libssl.so.1.0.0 (0xb6e37000)
libxiaomi_utils.so => /usr/lib/libxiaomi_utils.so (0xb6e04000)
liblibma.so => /usr/lib/liblibma.so (0xb6de9000)
libblobmsg_json.so => /lib/libblobmsg_json.so (0xb6dd6000)
libcurl.so.4 => /usr/lib/libcurl.so.4 (0xb6d8a000)
libglog.so.0.3.5 => /usr/lib/libglog.so.0.3.5 (0xb6d57000)
libjson-c.so.2 => /usr/lib/libjson-c.so.2 (0xb6d3f000)
libmbedtls.so.9 => /usr/lib/libmbedtls.so.9 (0xb6cf3000)
libubox.so => /lib/libubox.so (0xb6cda000)
libubus.so => /lib/libubus.so (0xb6cc4000)
libz.so.1 => /usr/lib/libz.so.1 (0xb6ca3000)
libcrypto.so.1.0.0 => /usr/lib/libcrypto.so.1.0.0 (0xb6b76000)
libuuid.so.1 => /usr/lib/libuuid.so.1 (0xb6b62000)
libglib-2.0.so.0 => /usr/lib/libglib-2.0.so.0 (0xb6a70000)
libgobject-2.0.so.0 => /usr/lib/libgobject-2.0.so.0 (0xb6a24000)
libiconv.so.2 => /usr/lib/libiconv.so.2 (0xb69d9000)
libintl.so.8 => /usr/lib/libintl.so.8 (0xb69c0000)
libthrift_c_glib.so.0 => /usr/lib/libthrift_c_glib.so.0 (0xb698e000)
libstdc++.so.6 => /lib/libstdc++.so.6 (0xb688d000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb6873000)
libc.so => /lib/ld-musl-armhf.so.1 (0xb6f44000)
libconfig.so.11 => /usr/lib/libconfig.so.11 (0xb685a000)
libnghttp2.so.14 => /usr/lib/libnghttp2.so.14 (0xb682e000)
libpcre.so.1 => /usr/lib/libpcre.so.1 (0xb67e3000)
libffi.so.6 => /usr/lib/libffi.so.6 (0xb67cf000)
root@L07A:~#

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

  sub_2202C(&v87, "8007236f-a2d6-4847-ac83-c49395ad6d65");
  xiaomi::mico::api::UpgradeAPI::computeS(&v84, &v67, &v87);

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

<?php
$s = 'channel=release&countryCode=CN&filterID=序列号/序列号&locale=zh_CN&platform=L07A&version=1.70.8&8007236f-a2d6-4847-ac83-c49395ad6d65';
$b = base64_encode($s);
$m = md5($b);
var_dump(strtoupper($m));
红米音箱固件更新检查逻辑 by @sskaje: https://sskaje.me/2021/04/redmi-play-firmware-upgrade-check/
Link to this post!

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK