利用AI逆向蓝牙体脂秤

某品牌体脂秤 M1,官方 App 广告太多了,频繁更新才能用。

借助DeepSeek V4 Flash 0730正式版

先说结果:
能跑,但是最后发现外贸版APP没有广告!并且基本不怎么更新!😂

1、环境

  • Win 10 电脑 Intel 蓝牙(支持 BLE)
  • Python 3.12,python -m venv .venv,装 bleak

2、找设备

1.原理就先踩亮体脂秤触发自带的蓝牙扫描广播

2.手机或者其他收到广播数据

3.然后上传通讯

记得把称放调试设备旁边,避免其他弱信号,我的就在电脑旁(-55dB 左右)

# AI分析:
GATT 一看:`0xFFF0` 服务,`0xFFF1` notify,`0xFFF2` write,固件是某国产 BLE 模块库 V3.0
典型的国产体脂秤自定义协议

3、卡 ErrF

让AI分析写脚本后能接通出现Loading但是因为没有正确传递返回信号,称就出现了ErrF。

# AI订阅 FFF1,收到一堆恒定帧,一秒 8 条,纹丝不动:
A4 12 00 FD 00 00 00 00 9B 0E FF FF 02 5F 00 54 FF BD

网上搜索了一些开源的协议都不对,然后就想到了拆APK。

4、拆 APK

  • 国内版本加壳,得专门的APK环境编译,放弃
  • 外贸版本没壳,可以

androguard 搜 fff0/fff1/fff2 → 协议类 → 型号分发器:目标秤BLE名 → FEScale处理器

关键协议:

用户命令 → FFF2: A1 06 <身高> <年龄> <性别> <校验>
                  校验 = 06 ^ 身高 ^ 年龄 ^ 性别 ^ A1
测量帧   ← FFF1: A4 12 xx xx ...
                  体重 = (byte2<<8|byte3) / 10  kg
                  阻抗 = (byte8<<8|byte9) / 100  Ω
帧确认   → FFF2: B4 04 01 B1

5、通了

A1 06 AA 1E 00 13(示意:男,身高 170cm,年龄 30 岁)→ 回 ACK B1 04 00 B5,不再 ErrF。

踩秤:

(示意帧,真实数值已隐去)
A4 12 xx xx 00 00 00 00 xx xx 00 55 08 74 01 32 FF xx
体重 = (byte2<<8|byte3) / 10   kg   (数值略)
阻抗 = (byte8<<8|byte9) / 100  Ω   (数值略)

再用另一姿势测一次对照解码(坐着测),体重解码正确。

6、体脂

秤只发体重 + 阻抗,体质啥的什么都是固定变量公式算出来的,也就是需要一个固定的公式来计算。

获取公式

开源项目

先用开源项目里的通用公式算,结果完全不准确。

APP真实数据反推

根据APP真值借助AI反推公式。解方程...

体重 xx.x kg  体脂 xx.x%  BMI xx.x  肌肉 xx.x kg  脂肪 xx.x kg
骨骼肌 xx.x kg  蛋白质 xx.x kg  水分 xx.x kg  骨质 xx.x kg

拿着真值反推:

  • 阻抗 = data[8..9]/100 = xxx Ω(符合人体 300~600Ω)
  • 用 Kyle 2001 BIA 方程算去脂体重 FFM,再按比例拆分:
FFM(男) = -4.104 + 0.518×H²/Z + 0.231×W + 4.229
体脂率  = (W - FFM) / W × 100
水分    = 0.735 × FFM
骨质    = 0.064 × FFM
蛋白质  = 0.20 × FFM
肌肉    = FFM - 骨质
骨骼肌  = 0.67 × FFM

验证:用真值代入,对比 App 的读数即可

总结

  • 体脂秤这种普通的其实就两个参数,一个实重 + 一个抗阻。
  • 测量必须赤脚,接触差阻抗虚高,体脂会明显虚高
  • 体脂公式是校准近似(根据结果逆向反推)

收回开头,外贸版APP没有广告! 😂


附录:协议速查

GATT

服务特征角色
0xFFF00xFFF1notify 数据
0xFFF00xFFF2write 命令

A4 测量帧(18 字节)

偏移含义计算
0帧类型0xA4
1长度0x12
2-3体重(b2<<8 or b3)÷10 kg
8-9阻抗(b8<<8 or b9)÷100 Ω
12-13疑似电抗/校验

命令

方向字节
发用户命令A1 06 <身高> <年龄> <性别> <chk>
收秤 ACKB1 04 00 B5
回帧确认B4 04 01 B1