Maku-hub/TrikiScope

GitHub: Maku-hub/TrikiScope

一款基于终端的 BLE 设备检查工具,用于逆向分析 Żabka Triki 纽扣控制器的 IMU 数据流、3D 姿态及 GATT 协议。

Stars: 1 | Forks: 0

# TrikiScope [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/) [![Tests](https://github.com/Maku-hub/TrikiScope/actions/workflows/tests.yml/badge.svg)](https://github.com/Maku-hub/TrikiScope/actions/workflows/tests.yml) 一个开源的终端 (TUI) BLE 读取器和检查器,专为 **Żabka Triki** 设备设计, 使用 Python 编写——旨在获取关于该设备的**最大量信息**。 Żabka 的 **Triki** 是一款外形像纽扣的微型移动游戏控制器, 可与 Żappka 应用程序配合使用。它通过动作控制游戏(根据成绩可获得 żappsy、 折扣以及 Żabka 生态系统中的奖励)。其内部带有一个 IMU 传感器(陀螺仪 + 加速度计), 因此能够检测旋转、倾斜和抛掷动作。它通过 Bluetooth Low Energy 与智能手机进行连接。 TrikiScope 通过 BLE 连接到该纽扣设备,读取所有可读取的数据,解码 IMU 数据流,并实时可视化 3D 姿态。 ![演示操作](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/e100c92684140916.gif) ## 功能展示 丰富的终端仪表盘(基于 Textual/Rich),包含以下标签页: - **Overview** — 连接状态、连接运行时间 (uptime)、BLE 广播数据 (RSSI、发射功率、带有 Company ID 解码的 `manufacturer data`、service UUIDs、service data)、完整的设备信息(制造商、型号、序列号、 firmware/hardware/software 版本、System ID、PnP ID、MTU、从名称解析的 Device ID)、电池电量以及 LED 指示灯状态。 - **GATT** — 完整的 GATT 数据库清查:services (服务) → characteristics (特征) → descriptors (描述符),包含其属性(read/write/notify/indicate)、句柄以及 读取到的值(文本 + 十六进制)。部分选定值会解码为 “人类可读”的形式(连接参数、PnP ID、appearance、电池等)。 - **IMU** — 实时数据流:原始的 `int16` 以及转换后的陀螺仪 (deg/s) 和加速度计 值、向量大小 (magnitudes)、活动状态 sparkline 图表、流统计信息 (通知数、帧数、丢失字节数、中断间隔、采样频率、 数据包大小直方图、带宽)以及最新一帧的十六进制数据。 **Motion** 面板:按钮状态 + 按压计数、检测到的手势 (TAP/IMPACT、FREE-FALL/THROW、SHAKE、SPIN)以及陀螺仪/加速度计的峰值数据。 - **Orientation** — 通过 **Madgwick AHRS**(或 互补滤波器)计算的 3D 姿态,并通过旋转的 ASCII 立方体骨架进行可视化显示, 包含 pitch/roll/yaw 角度和四元数。在数据流启动时进行自动校准。 - **Games** — 几款由纽扣设备实时控制的简单 ASCII 游戏(基于 同一个 IMU 数据流):**Tilt Maze**(通过倾斜引导小球到达目标)、 **Spin Meter**(尽快旋转纽扣——测量峰值旋转 速度)和 **Reflex Catch**(反应测试:在出现信号时通过点击/按键作出反应)。使用 `[` / `]` 键切换游戏,`g` 键重启当前游戏。 - **Log** — 可滚动的事件日志(连接、按键、手势、LED 等)。 数据可以保存为 **CSV**(IMU 数据流 + 角度 + 按钮状态)和 **事件日志**。可以通过按 `l` 键控制纽扣设备上的 LED 指示灯。 ## 系统要求 - 开启了蓝牙的 Windows 10/11(得益于 `bleak`,也可在 Linux/macOS 上运行), - Python 3.10+, - 开启状态的 Triki 设备且在附近(如果处于休眠状态——在进行连接前 请按一下纽扣设备上的按钮)。 ## 安装说明 ``` cd TrikiScope python -m venv .venv .\.venv\Scripts\python.exe -m pip install -r requirements.txt ``` ## 运行说明 最简单的方法是使用启动器(无需手动激活 venv): ``` .\run.ps1 # PowerShell – z auto-połączeniem ``` ``` run.bat :: cmd / dwuklik w Eksploratorze – z auto-połączeniem ``` 或者直接通过模块运行: ``` .\.venv\Scripts\python.exe -m trikiscope --auto-connect ``` 不自动连接(在应用程序中按 `c` 键进行连接): ``` .\.venv\Scripts\python.exe -m trikiscope ``` 如果纽扣设备处于休眠状态——在连接前按下其按钮以唤醒设备。 ### 快捷键 | 按键 | 操作 | |--------|-------| | `c` | 连接(扫描 + 连接) | | `d` | 断开连接 | | `r` | 在当前姿态下重置方向 | | `z` | 重新校准(请保持静止) | | `m` | 切换方向滤波器(Madgwick / 互补滤波器) | | `s` | 开启/关闭 CSV 录制 | | `l` | 点亮/熄灭纽扣设备上的 LED | | `1`–`6` | 切换标签页 (Overview / GATT / IMU / Orientation / Games / Log) | | `[` / `]` | (Games) 上一个 / 下一个游戏 | | `g` | (Games) 重启当前游戏 | | `q` | 退出 | ### 扫描模式(无 TUI) 列出所有正在广播的 BLE 设备(有助于查找设备名称/地址): ``` .\run.ps1 --scan ``` ### 常用选项 ``` --name TEXT fragment nazwy urządzenia (domyślnie "Triki") --scan-timeout SEC czas skanowania (domyślnie 30) --gyro-scale FLOAT LSB na deg/s (domyślnie 131.0) --accel-scale FLOAT LSB na g (domyślnie 2048.0) --settle-delay SEC odczekaj N s przed wysłaniem komendy startowej (domyślnie 0) --discard N liczba początkowych próbek do odrzucenia (domyślnie 20) --start-command HEX komenda startowa na NUS RX (domyślnie 201000D007680003) --no-start nie wysyłaj komendy startowej automatycznie --auto-connect połącz się zaraz po starcie --mode {madgwick,complementary} filtr orientacji (domyślnie madgwick) --record nagrywaj od razu --csv PATH / --log PATH ścieżki plików wyjściowych --scan wypisz urządzenia BLE i zakończ (bez TUI) ``` 通过 `.\run.ps1 --help` 查看完整列表。 ## BLE 规范 该设备使用 **Nordic UART Service** 进行通信: - Service UUID: `6e400001-b5a3-f393-e0a9-e50e24dcca9e` - RX Characteristic (写入,手机 → 设备): `6e400002-b5a3-f393-e0a9-e50e24dcca9e` - TX Characteristic (通知,设备 → 手机): `6e400003-b5a3-f393-e0a9-e50e24dcca9e` 应用程序订阅来自 TX 的通知,并向 RX 发送初始化数据传输的命令: ``` 20 10 00 D0 07 68 00 03 ``` 此外,在 NUS 服务中还有一个 `6e400004-…` 特征(支持 read/write)。我们通过 实时的实验发现,其 **bit 0 控制着** 纽扣设备上的 **LED 指示灯**(`01` = 亮起, `00` = 熄灭;该值会被掩码处理为 1 个 bit)。在应用程序中按下 `l` 键即可点亮/熄灭 LED。 ## IMU 数据格式 IMU 数据以带有 `22 00` 标头的 **14 字节** 数据帧形式传入: ``` 22 00 | gyroX | gyroY | gyroZ | accelX | accelY | accelZ ``` 每个轴均为采用 little-endian 格式的带符号 16 位整数。 默认的硬件缩放转换系数为:陀螺仪 `131.0`(LSB 转换为 deg/s) 以及加速度计 `2048.0`(LSB 转换为 g)。 **标头的第二个字节是按钮标志**(通过在监听 BLE 时按下按钮发现):`22 00` = 按钮释放,`22 01` = 按钮按下。在这两种情况下,payload 是 完全相同的。TrikiScope 会对这两种标头进行解析,因此在 按下操作期间不会丢失数据帧,并能显示按钮状态以及按压计数。 对捕获的 BLE 通信以及 Żappka `4.37.0` 应用程序的分析表明,该数据流 以 BLE burst(突发传输)的形式到达,通常在短数据包中包含多个数据帧。TrikiScope 使用 BLE 通知的 timestamp 作为采样时间源(因为在实际应用中,实验性的约 `104 Hz` 的固定时钟效果较差)。解析器会在标头 (`22 00` 或 `22 01`)之后重新同步,因此在出现粘连/截断的通知后能够恢复数据流 并且不会丢失按下按钮时的数据帧。 在数据流启动时,设备会发出短暂的“噪音”——最初的几个采样(默认为 20 个) 会被丢弃。 ## 方向姿态 姿态通过两种可互换的滤波器进行计算(通过 `m` 键切换): - **Madgwick AHRS** — 将陀螺仪和加速度计数据进行融合以转换为四元数,带有自动校准(静止时 auto-zero)、 SLERP 平滑处理以及视觉盲区。 - **互补滤波器** — 直接从互补滤波器中提取 pitch/roll/yaw 数据 (“Zappka-like”模式)。 ## 硬件 Triki 基于: - **MCU:** Nordic Semiconductor nRF52810 (BLE), - **IMU:** ST LSM6DSL (加速度计 + 陀螺仪), - **外部 Flash:** Macronix MX25R8035F (8 Mbit / 1 MB, SPI), - **DEBUG:** PCB 上的 SWD 引脚;设备受 **Nordic APPROTECT** 保护 (在不完全擦除芯片的情况下,读取 firmware/debug 将被阻止)。 详细的硬件说明(引脚分配、PCB 照片、OpenOCD/SWD、Flash 转储)位于 独立的项目中:。 ## 诊断工具 (`tools/`) 在对设备进行逆向工程时使用的辅助脚本(需在 TUI 应用程序关闭时单独运行): - `diagnose.py` — 完整转储:广播数据、带值的 GATT、数据流分析。 - `probe_button.py` — 用于检测按钮数据帧 (`22 01`) 的交互式测试。 - `probe_led.py` — 确认 LED 控制(闪烁模式)。 - `probe_write_vendor.py` — 针对 `6e400004` 的安全测试。 - `probe_ble_layer.py` — 生产级 BLE 端到端层测试。 ``` .\.venv\Scripts\python.exe tools\diagnose.py ``` ## 测试 ``` .\.venv\Scripts\python.exe -m pip install pytest .\.venv\Scripts\python.exe -m pytest ``` ## 姊妹项目 — TrikiEmu **[TrikiEmu](https://github.com/Maku-hub/TrikiEmu)** 是 TrikiScope 的逆向项目:它不是去*读取*纽扣设备,而是**模拟**该设备。由 ESP32 充当 BLE *peripheral*,重现 Triki 的身份和配置文件(广播、NUS、IMU 数据流),从而使得 Żappka 应用程序像连接真实的纽扣设备一样连接到它,并且动作数据可从计算机端输入。 TrikiScope 是 BLE *central*(客户端),而 TrikiEmu 是 *peripheral*(服务端);所有关于协议的知识 均来源于此处完成的逆向工程工作。TrikiScope 还充当 **验证仿真器的已知良好 central 端**,然后才会将其接入 Żabka 应用程序中。 ## 免责声明 本项目出于教育和文档说明目的。与 Żabka 公司无任何关联。
标签:GATT协议, Python, 传感器数据分析, 安全规则引擎, 无后门, 物联网, 物联网设备调试, 终端用户界面(TUI), 蓝牙低功耗(BLE), 逆向工具