小米AI音箱(小爱同学)root记录

最近计划搞一搞智能音箱,从网上买了一个二手的小米AI音箱(型号MDZ-25-DA)

拆开看是绿板主板,应该是偏新的批次,主板外观如下图:

参考hassbian的方法对设备进行root,记录一下。

1. 拆机串口登录

从网上找了几个拆解图,基本知道螺丝位置后,正常进行拆解就行。调试串口为间距 1mm 的 3pin 口,淘宝买了根 SH 1.0mm 3pin 线,再焊接3根杜邦线接到 USB2TTL 设备上,波特率 115200 进入 tty,输入任意键,弹出 root 登录提示。

这个 root 密码和 kindle 的 root 密码挺像的,根据串号加固定字符串算出来的,有点HMAC的意思。

网上查找了一些资料,找到几个字符串,经过测试我的设备对应字符串是B0168A6D-119A-F21A-DA58-980732F80A19

大致算法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/usr/bin/env python2.7
#coding:utf8

# 通用说明:
# 1、先找到小爱音响SN码,通常在拆开后的底座里面。
# 例如:SN:20190/122119360
# 2、root登录密码=md5(SN+通配字符串)取值的前14位
# 通配字符串:9C78089F-83C7-3CDC-BCC9-93B378868E7F
# 即:20190/1221193609C78089F-83C7-3CDC-BCC9-93B378868E7F
# 3、使用MD5在线加密工具 https://md5jiami.51240.com/
# 4、将2中的最终待加密代码经md5加密后得到如下32位小写加密信息:(只看32位,且一定小写)
# 865027665beacb8f8240355d7300e0ac
# 取前14位:865027665beacb 即为root登陆密码

from hashlib import md5

MAGIC_SALTS = [\
"5775B10D-15C0-7827-97B9-88EA07FCA97A",\
"0168A6D-119A-F21A-DA58-980732F80A19",\
"A20EDC68-62E5-70C6-76E8-75879721B8EC",\
"B0168A6D-119A-F21A-DA58-980732F80A19",\
]
sn = "1****/9********"
root_password = md5( sn + MAGIC_SALTS[3] ).lower()[:14]
print root_password

2. 临时打开ssh

1
2
3
root@S12A:~# dropbearkey -t rsa -f /data/dropbear_rsa_host_key
root@S12A:~# dropbear -r /data/dropbear_rsa_host_key
root@S12A:~# ifconfig

然后通过 ssh 连入设备,界面上会比USB2TTL的CUI更完善一些。

3. 提取文件系统

mount看一下目前挂载的分区,另外可以ls -alF /dev/mtd*看看还有哪些其他分区,绿板小爱同学有a/b分区备份,建议先刷1个分区,如果能够正常启动的话,再把另一个分区刷了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
root@S12A:~# mount
/dev/mtdblock4 on / type squashfs (ro,noatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,noatime)
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,noatime)
tmpfs on /tmp type tmpfs (rw,nosuid,nodev,noatime)
tmpfs on /dev type tmpfs (rw,nosuid,relatime,size=512k,mode=755)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,mode=600,ptmxmode=000)
debugfs on /sys/kernel/debug type debugfs (rw,noatime)
pstore on /sys/fs/pstore type pstore (rw,relatime)
/dev/ubi0_0 on /data type ubifs (rw,relatime)
/dev/ubi0_0 on /etc/shadow type ubifs (rw,relatime)
root@S12A:~# ll /dev/mtd*
crw------- 1 root root 90, 0 Jan 1 2015 /dev/mtd0
crw------- 1 root root 90, 1 Jan 1 2015 /dev/mtd0ro
crw------- 1 root root 90, 2 Jan 1 2015 /dev/mtd1
crw------- 1 root root 90, 3 Jan 1 2015 /dev/mtd1ro
crw------- 1 root root 90, 4 Jan 1 2015 /dev/mtd2
crw------- 1 root root 90, 5 Jan 1 2015 /dev/mtd2ro
crw------- 1 root root 90, 6 Jan 1 2015 /dev/mtd3
crw------- 1 root root 90, 7 Jan 1 2015 /dev/mtd3ro
crw------- 1 root root 90, 8 Jan 1 2015 /dev/mtd4
crw------- 1 root root 90, 9 Jan 1 2015 /dev/mtd4ro
crw------- 1 root root 90, 10 Jan 1 2015 /dev/mtd5
crw------- 1 root root 90, 11 Jan 1 2015 /dev/mtd5ro
crw------- 1 root root 90, 12 Jan 1 2015 /dev/mtd6
crw------- 1 root root 90, 13 Jan 1 2015 /dev/mtd6ro
brw------- 1 root root 31, 0 Jan 1 2015 /dev/mtdblock0
brw------- 1 root root 31, 1 Jan 1 2015 /dev/mtdblock1
brw------- 1 root root 31, 2 Jan 1 2015 /dev/mtdblock2
brw------- 1 root root 31, 3 Jan 1 2015 /dev/mtdblock3
brw------- 1 root root 31, 4 Jan 1 2015 /dev/mtdblock4
brw------- 1 root root 31, 5 Jan 1 2015 /dev/mtdblock5
brw------- 1 root root 31, 6 Jan 1 2015 /dev/mtdblock6

切到/tmp临时目录,对系统镜像进行提取

1
2
3
4
root@S12A:~# cd /tmp
root@S12A:/tmp# dd if=/dev/mtdblock4 of=/tmp/m4.img
65536+0 records in
65536+0 records out

scp 把 m4.img 复制到另一台 Linux 机器,再回来把 /tmp/m4.img 删除,重新 dd mtdblock5 出来做个b分区备份。

4. 解压并修改分区

4.1 解压分区

在 Linux 机器上解压提取到的 m4.img 镜像,查看 block size,后面重新压缩会用到。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
root@ubuntu:/home/test/Desktop/xiaomi# unsquashfs -s mtdblock4.img
Found a valid SQUASHFS 4:0 superblock on mtdblock4.img.
Creation or last append time Thu Jul 16 13:04:11 2020
Filesystem size 32052.31 Kbytes (31.30 Mbytes)
Compression xz
xz: error reading stored compressor options from filesystem!
Block size 131072
Filesystem is exportable via NFS
Inodes are compressed
Data is compressed
Fragments are compressed
Always-use-fragments option is not specified
Xattrs are not stored
Duplicates are removed
Number of fragments 106
Number of inodes 1763
Number of ids 1

解压镜像,注意这里需要用 root 解压,非 root 账户可能无法创建设备文件等特殊文件,重新打包刷入后,系统会起不来

1
2
3
4
5
6
7
8
9
10
11
root@ubuntu:/home/test/Desktop/xiaomi# unsquashfs -dest m4 mtdblock4.img
Parallel unsquashfs: Using 4 processors
1661 inodes (2074 blocks) to write

[======================================================/] 2074/2074 100%

created 1082 files
created 102 directories
created 578 symlinks
created 1 devices
created 0 fifos

4.2 添加自启动项

修改 /etc/rc.local 添加 /data/init.sh(或者把自启动的命令都写入rc.local也行,反正镜像都改写了),改完的文件如下:

rc.local
1
2
3
4
5
root@ubuntu:/home/test/Desktop/xiaomi# cat m4/etc/rc.local
# the system init finished. By default this file does nothing.
sh /data/init.sh &
exit 0
root@ubuntu:/home/test/Desktop/xiaomi#
/data/init.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
root@S12A:~# chmod +x /data/init.sh					# 添加可执行属性
root@S12A:~# ll /data/init.sh
-rwxr-xr-x 1 root root 188 Dec 24 2019 /data/init.sh*
root@S12A:~# cat /data/init.sh
#!/bin/sh
if [ -e /data/dropbear_rsa_host_key ]
then
echo "exists"
else
echo "not exist"
dropbearkey -t rsa -f /data/dropbear_rsa_host_key
fi
dropbear -r /data/dropbear_rsa_host_key

4.3 写入 ssh 密钥

1
2
root@S12:~# cat /etc/dropbear/authorized_keys
ssh-rsa AAA**************************************************

4.4 关闭 OTA

修改 crontab 文件,关闭 OTA 检查,以防系统更新后自启动项 & ssh 密钥消失。

1
2
3
4
5
6
7
8
9
10
11
12
13
root@S12:~# cat /etc/crontabs/root
# explain crontab in https://crontab.guru/
#
# At every 5th minute.
*/5 * * * * /usr/sbin/easy_logcut size
# At every minute.
* * * * * /usr/sbin/network_probe.sh
# At 04:32.
32 4 * * * /usr/sbin/pns refresh
# At every 10th minute.
*/10 * * * * /usr/bin/check_mediaplayer_status
# At 03:00.
#0 3 * * * /bin/ota slient # check ota

通过查看 ota 脚本,发现 ota 服务器应该是 api.miwifi.com,直接在上级路由将域名屏蔽也可以。

5. 重新打包分区,刷入设备

按之前查看 block size 的信息作为参数重新打包分区,不同设备型号的 block size 可能不同。

仍然用 root 操作,不然有些文件权限会出问题。另外一定要做一定的压缩,如果 img 过大,会出现刷写不完整,导致分区起不来,切换到 b 分区。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
root@ubuntu:/home/test/Desktop/xiaomi# mksquashfs m4 m4_crack.img -b 131072 -comp xz -Xbcj arm -Xdict-size 32K -no-xattrs
Parallel mksquashfs: Using 4 processors
Creating 4.0 filesystem on m4_crack.img, block size 131072.
[======================================================\] 1495/1495 100%

Exportable Squashfs 4.0 filesystem, xz compressed, data block size 131072
compressed data, compressed metadata, compressed fragments, no xattrs
duplicates are removed
Filesystem size 32469.29 Kbytes (31.71 Mbytes)
46.00% of uncompressed filesystem size (70587.29 Kbytes)
Inode table size 15932 bytes (15.56 Kbytes)
24.82% of uncompressed inode table size (64178 bytes)
Directory table size 17978 bytes (17.56 Kbytes)
44.87% of uncompressed directory table size (40068 bytes)
Number of duplicate files found 23
Number of inodes 1763
Number of files 1082
Number of fragments 106
Number of symbolic links 578
Number of device nodes 1
Number of fifo nodes 0
Number of socket nodes 0
Number of directories 102
Number of ids (unique uids + gids) 1
Number of uids 1
root (0)
Number of gids 1
root (0)

在小爱同学上删除 /tmp/m4.img,将修改后的 m4_crack.img 复制回小爱同学的临时目录,刷写镜像到 mtdblock4

1
2
3
4
5
6
7
root@S12:/tmp# mtd write m4_crack.img system0
Unlocking system0 ...

Writing from m4_crack.img to system0 ... [w]
root@S12:/tmp# /usr/bin/fw_env -s boot_part boot0
[ubootenv] update_bootenv_varible name [boot_part]: value [boot0]
[ubootenv] Save ubootenv to /dev/nand_env succeed!

如果重启OK,并且没有切到 b 分区的话,证明刷写成功,可以选择把 b 分区也刷写了

1
2
3
4
5
root@S12:/tmp# mtd write m4_crack.img system1
Unlocking system1 ...

Writing from m4_crack.img to system1 ... [w]
root@S12:/tmp#

6. 后记

从老家寄来了在 MIDC 2017 会议上的礼品,首发版 小米AI音箱,这个拆开看是黑色板子的,大概如图。

这个硬件型号的设备,系统没有 mount 到 ro,可以直接写。

1
2
3
4
5
6
7
8
9
10
11
12
root@S12:~# mount
rootfs on / type rootfs (rw)
/dev/ubi0_0 on / type ubifs (rw,noatime)
devtmpfs on /dev type devtmpfs (rw,relatime,size=115548k,nr_inodes=28887,mode=755)
proc on /proc type proc (rw,nosuid,nodev,noexec,noatime)
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,noatime)
cgroup on /sys/fs/cgroup type cgroup (rw,nosuid,nodev,noexec,relatime,debug,cpu,cpuacct,devices,freezer,net_cls,blkio)
tmpfs on /tmp type tmpfs (rw,nosuid,nodev,noatime)
tmpfs on /dev type tmpfs (rw,nosuid,relatime,size=512k,mode=755)
debugfs on /sys/kernel/debug type debugfs (rw,noatime)
/dev/ubi1_0 on /data type ubifs (rw,relatime)
root@S12:~#

类似方法加入 ssh,禁用 ota 即可。

另外发现 /tmp/mico_aivs_lab/instruction.log 文件中临时存有小爱的交流日志,后面有空可以结合 homeassistant 搞一些事情。

谢谢老板打赏 Or2