diegomarino/faro-fan-flipper-remote
GitHub: diegomarino/faro-fan-flipper-remote
通过 Flipper Zero 利用 433 MHz 吊扇系列的广播后门地址实现通用遥控,并提供完整的逆向工程工具链和信号文件。
Stars: 2 | Forks: 0
# faro-fan-flipper-remote
通过 **Flipper Zero** 控制一个 433 MHz 吊扇系列——还包括完整的逆向工程工具链以及达成目标的记录。
就像大多数故事一样,这一切都是从弄丢遥控器开始的 :D
幸运的是,在家里翻新期间,我安装了好几台同款吊扇——相同的电路板,同为 2017 年批次——因此至少有一个能用的遥控器幸存了下来。但是(总会遇到一个*但是*——那种将你卷入一场充满黑客精神和纯粹固执的传奇故事的转折):这些设备是**出厂配对的,并且没有对码按钮**,因此每个接收器只服从*其自身*遥控器的固定地址。此外,这也是一个完美的借口,可以向我的妻子证明 Flipper Zero 是一份极棒的圣诞礼物——多亏了这件事,它现在可以说已经回本了。
恢复丢失遥控器的地址看起来似乎需要直接从接收器中提取 EEPROM dump……直到后来发现了一个简单得多的事实。

## 发现:`0xFFFFF` 是一个广播后门
能用的遥控器解码后得到一个稳定的固定码:一个 **20 位的共享地址**(`0xFFF12`)加上一个 9 位的按键字段。地址空间是 20 位,因此最后一个可能的地址是 `0xFFFFF`——**全是 1**。
这个全 1 的地址充当了一个**广播/出厂后门**:该系列中的每个接收器都会对它做出响应,无论它最初配对的专属地址是什么。已在两台吊扇上验证通过。因此,“丢失地址”的问题迎刃而解——你根本不需要餐厅原来的代码。你只需发送 `0xFFFFF`,范围内的*每一台*吊扇都会听从指令。
`signals/` 中的所有内容都是可用遥控器的真实捕获波形,并**被重新定向到了 `0xFFFFF`**(真实的空中传输时序,仅更改了地址位——参见 `tools/clone_patch.py`)。
## 识别出的硬件
| 部件 | 数值 |
|------|-------|
| 电路板丝印 | `FNT-AC230W18TG-FIR2 V2.0`(日期为 2016-12-21) |
| 接收器贴纸 | `F30-60Q34-L`,批次 `7H11D0182`,2017.08.2x |
| 可用遥控器贴纸 | 批次 `7H11D0118`,2017.08.21 |
| RF | 433.92 MHz OOK,固定码(非滚动码) |
| 帧 | 20 位地址 + 9 位按键字段,约 7.15 ms 同步间隔 |
| Burst | 作为 **40 帧**的 Burst 发送——边缘化的接收器需要长 Burst 才能锁存(快速单击会被忽略);真实的遥控器会发送约 52-65 帧 |
| 风速编码 | 6 个绝对档位,信息字段 = `32 - 2xlevel`(互补对) |
| 配对 | 出厂配对,**没有对码按钮,没有 DIP 开关** |
`F30-60Q34-L` 和 `FNT-AC230W18TG-FIR2` 是通用的 OEM 部件——没有公开的数据手册或配对手册。
遥控器贴纸——`7H11D0080`(卧室设备,遥控器现已没电)和 `7H11D0118`(可用的参考遥控器,地址为 `0xFFF12`),同为 2017.08.21 批次:

接收器外壳——序列号 `7H11D0182`,部件号 `F30-60Q34-L`:

接收器 PCB(`FNT-AC230W18TG-FIR2 V2.0`,日期为 2016-12-21):左侧是电机 `U/V/W` 接线端子和 `RY1` 灯继电器,中右侧是 QFP MCU,右上角是 6 引脚的 `CN3`(解调后的 RF 数据,而非市电),紧挨着 MCU 右侧的是作为候选 EEPROM 的 SOIC-8 芯片:

SOIC-8 芯片特写——标有 `SG1A` / `1631`(日期代码 2016 年第 31 周),带有一个类似 MCU 上的螺旋状内部 Logo。这就是通过提取 EEPROM dump 来恢复地址时需要针对的芯片;其确切型号尚未确认(这是一个内部/供应商代码,不是普通的 24Cxx):

## 目录结构
```
signals/ 10 working .sub files at 0xFFFFF (speeds 1-6, fan/light/reverse/dimmer)
app/
fan_remote/ the custom Flipper app (embedded waveforms, prebuilt .fap)
fan_debug/ transmit-path diagnostic (logs each TX step on screen)
tools/ the reverse-engineering pipeline (Python, stdlib only)
captures/ raw .sub recordings of the original remote (source data)
docs/ findings.md (technical log) + images
```
## 使用说明 - 应用程序
这个自定义应用程序**不需要复制任何文件**:波形已经内嵌其中,它会自动进行配置。将预编译好的 `app/fan_remote/dist/momentum/fan_remote.fap` 复制到你的 Flipper(`SD/apps/Sub-GHz/`),或者自行构建它——请参阅
[`app/fan_remote/README.md`](app/fan_remote/README.md)。然后在 Momentum 中启用
**MNTM → Protocols → SubGHz → Bypass Region Lock**(请参阅下方的免责声明)。
控制方式:**上/下** = 风速 1–6,**◄** = 反转,**►** = 吊扇开/关,
**●/OK** = 灯光开/关。
### …或者不使用应用程序
更喜欢使用 Flipper 原生的 **Sub-GHz → Saved** 菜单?只需将 `signals/*.sub` 复制到 SD 卡上的
`/ext/subghz/` 目录下并直接播放它们即可。波形是一样的。
## 使用说明 - 工具链
`tools/` 下的所有内容都是纯 Python 编写的(仅使用标准库),并将文件路径作为参数。生成 `signals/` 的流水线如下:
```
# 1. 从其 captures 中解码原始 remote -> 共享地址 0xFFF12
python3 tools/subghz.py "captures/RAW-2026*.sub"
# 2. 从一次杂乱的 up/down sweep 中重建 1..6 speed 顺序
python3 tools/order_levels.py captures/speeds.sub # (or: selftest)
# 3. 将一次真实的 capture 重新定向至 40 frames 的 0xFFFFF broadcast(出厂
# burst length;button 为 light_onoff,即 gen_signals_h.py 读取的名称)
python3 tools/clone_patch.py captures/bedroom-light.sub 0xFFFFF light_onoff signals 40
# 4. 从 signals/*.sub 重新生成两个 app 的 embedded signals.h (byte-exact),
# 然后验证它们是否同步(gate 在任何 source<->header drift 时都会失败):
python3 tools/gen_signals_h.py signals app/fan_remote/signals.h
python3 tools/gen_signals_h.py signals app/fan_debug/signals.h
python3 tools/verify.py
```
其他工具:`sweep.py`(对 256 个候选地址进行时间同步的暴力破解,这是在发现广播后门之前的后备方案),`synth.py`(理想化的波形合成——作为参考保留;它在真实硬件上*失败了*,这就是为什么 `clone_patch.py` 要复用真实时序的原因),`label_hypothesis.py`(证伪了将贴纸数字当作地址的猜测)。
## 走过的死胡同(记录下来以免重蹈覆辙)
- **在空中暴力破解 2^20 个组合** - 验证才是最麻烦的问题,而且一旦 `0xFFFFF` 起作用,这就毫无意义了。
`tools/sweep.py` 曾将其范围缩小到 256 个(固定的 `0xFFF`
前导码 + 未知的低位字节),但最终即便是这也被证明是不必要的。
- **贴纸数字(`0118` / `0182`)** - *并非* RF 密钥。在
`tools/label_hypothesis.py` 中已被证伪。
- **读取接收器的 EEPROM** - 这是恢复丢失的设备专属地址的“正规”途径。虽然经过了充分的分析推演,但最终从未派上用场:广播功能使其变得毫无意义。分析详情请参见 `docs/findings.md`。
## ⚠️ RF 射频传输 - 法律与道德声明
本项目会在 **433.92 MHz** 频率上进行发射,并使用了一个广播地址,能够控制无线电范围内该吊扇系列中的**任何**接收器——包括邻居家的吊扇,而不仅仅是你自己的。
- **频谱合规性由你个人负责。** 各国关于 ISM 频段的法规各不相同;请查看你所在地区允许进行何种低功率的无线电传输。
- **仅对你拥有或获得授权控制的硬件进行发射。**
- 启用 Momentum 的 **Bypass Region Lock** 属于*对固件内置监管保护机制的蓄意覆盖*。在进行此操作之前,请务必了解你关闭的到底是什么。
提供此项目旨在实现互操作性、维修和教育目的。请负责任地使用。
## 许可证
[MIT](LICENSE)。
标签:433MHz射频, Flipper Zero, 云资产清单, 客户端加密, 智能家居, 物联网, 逆向工具, 逆向工程