前言です。事情的起因是作者最近在折腾手机当 CPE(就是那种拿 5G 手机插 USB 给全家供网的骚操作),测着测着速突然盯着 MIUI 的 Wi-Fi 列表发呆——为什么「黑可实验室」旁边有个专属的小米标,而隔壁 OpenWrt 的「小猫看世界」就只有个光秃秃的 Wi-Fi 图标?
作者一开始信誓旦旦地跟朋友说:「肯定是看 BSSID 的 OUI 啦,小米给自家路由注册了一堆 MAC 段,手机端维护一张白名单就完事了」。
然后作者把 HyperOS 的 Settings 拆了,发现判定逻辑压根不看 BSSID,当场被打脸。🤡 不仅被打脸,这个判定还宽松得离谱——宽松到任何路由器都能白嫖。改白不改,开整!
测试环境
| 项目 | 配置详情 |
|---|---|
| 被反编译对象 | HyperOS Settings(小米手机系统设置,Wi-Fi 列表的徽标就是它画的) |
| 小米路由 | 小米路由器 BE3600(内部型号 RD16,WPA2-PSK,5G 信道 44) |
| 对照组 | CMCC RAX3000M 刷 ImmortalWrt(SSID「小猫看世界」,sae-mixed) |
| 逆向工具 | adb + jadx 1.5.6(字符串定位 → 单 dex 反编译,两分钟出人话) |
| 抓包工具 | iw scan(Linux,MT7922 网卡) |
准备材料
- 一部小米手机(HyperOS,型号随意,能连 adb 就行)
- 一台电脑(我不到啊,我就喜欢 Linux)
- jadx 一位(推荐 jadx,别的反编译器都玩不明白 r8 的 lambda 命名,截止 2026 年 9 月 9 日)
- 良好的网络环境(GitHub 直连不动,你知道我在说什么👁)
- 极强的动手 / 思考 / 搜索能力
适用人群
会用 Linux 和 adb,此教程并不适合小白。
先把判定逻辑挖出来
思路很清晰:Wi-Fi 列表的图标是 Settings 画的,那就从它下手。把 Settings.apk 拉下来,先 strings 撒网找关键词 XiaoMiRouter、xiaomi_router,锁到 classes4.dex(Wi-Fi 相关的代码都住这),再丢给 jadx 单文件反编译——然后就看到了 com.android.settings.wifi.XiaomiRouterUtils,判定函数 isXiaomiRouter() 明明白白:
// 遍历扫描结果里的每个 Vendor Specific IE(ID 221 = 0xDD):
if (IE长度 > 3 && OUI == 00:17:92) → 小米路由
if (IE长度 > 6 && OUI == 80:AD:16 && 后3字节 == 01 01 01) → 小米路由
if (IE原始字节转小写后包含 "xiaomi") → 小米路由
什么?!就这么点?就这么点。判定只看广播帧里的 Vendor Specific 信息元素,SSID 什么都不看,BSSID 的 OUI 什么都不看。作者那个「小米维护 OUI 白名单」的推测直接卒。
三条规则逐个考证
| 规则 | OUI 归属 | 考据结果 |
|---|---|---|
| 00:17:92 | Falcom Wireless Comunications GmbH(德国,2006-04 注册) | 和小米毫无关系,纯历史遗留。疑似早期某批小米硬件用了这家的模块,或者是写代码时抄来的老列表 |
| 80:AD:16 + 01 01 01 | Xiaomi Communications(2017-12-11 注册) | 小米自家的路由私有 IE 格式,货真价实 |
| 字节流包含 “xiaomi” | —— | 小米官方路由命中的就是这条!BE3600 的 WPS IE(OUI 00:50:F2)里写着 Manufacturer: xiaomi 和 Device name: XiaoMiRouter,整段字节一转小写就中招 |
我嘞个豆,小米路由靠的是「WPS 字段里恰好有小米俩字」这种巧合式匹配,而不是什么专门的识别协议。那普通路由器白嫖起来就是改一个字符串的事。
实操:hostapd / OpenWrt
规则 3 是子串匹配,那最短路径就是广播一个内容为 xiaomi 的 221 号 IE。xiaomi 的 ASCII 十六进制是 78 69 61 6f 6d 69,整个 IE 长这样:
dd 06 78 69 61 6f 6d 69
│ │ └── "xiaomi" 的 ASCII
│ └── IE 长度 = 6
└── IE 类型 = 0xDD(221,Vendor Specific)
hostapd 配置(Padavan / 梅林 / OpenWrt 底层都是它):
# /etc/hostapd/hostapd.conf
vendor_elements=dd067869616f6d69
OpenWrt 一条命令:
uci set wireless.default_radio1.vendor_elements='dd067869616f6d69'
uci commit wireless
wifi reload
验证(主机上扫一下):
$ iw dev wlan0 scan | grep -A1 'Vendor specific'
Vendor specific: OUI 00:00:00, data: 78 69 61 6f 6d 69
然后掏出小米手机刷新 Wi-Fi 列表——小米标就这么白嫖到手了😋。
⚠️Tips
- IE 长度(
06)要和 payload 对得上,算错了整段 IE 直接被驱动丢掉,白忙活; - 这是纯显示层标记:米家绑定、远程管理、路由器 App 配网统统不生效,别指望白嫖出个小家;
- 两个 BSSID(2.4G/5G)最好都加,因为判定是对整组扫描结果做的,漏一个频段偶尔会翻车。
彩蛋
- 同一个文件里还躺着
wx / dp / mt / nm四个指示器——微信连Wi-Fi、大众点评、美团、糯米的门户标,老网民的青春回来了; - Wi-Fi 详情页里的「管理路由器」按钮,逻辑是打开
http://<当前网关>,取不到网关就回落http://192.168.31.1(小米默认地址),抄作业的时候顺手把 WPS 的 UUID 写成了87654321-9abc-def0-1234-<MAC后6位>,确实好笑。
感谢名单
- 感谢 @skylot(jadx 作者),字符串定位 → 单 dex 反编译的工作流纯属他赏饭;
- 感谢 maclookup.app 和 uic.io,OUI 归属查证全靠这俩;
- 感谢 miot-spec(小米米家产品库),
xiaomi.router.rd16→ BE3600 的型号对号入座就是在这查的。
声明
本文仅为逆向研究记录。标识骗得来,功能骗不来,米家绑定该失败还是失败。另外这匹配宽松到什么程度呢——你甚至可以在 IE 里写「不是小米」然后它也中招,因为 contains(“xiaomi”)……哦不对,「不是小米」里确实有小米。行了,就写到这。