2024 年 6 月,Fisker Inc. 申请 Chapter 11 破产保护。公司倒了,但路上还跑着大约 11000 台 Ocean SUV——每台售价 4 万到 7 万美元。问题不只是"没人修车",而是这些车的软件大脑正在快速死亡:OTA 更新停了,联网服务断了,远程诊断没了,保修归零。一辆 2024 年的智能电动车,正以肉眼可见的速度退化成一台带大屏幕的铁壳子。
然后,车主们做了一件在汽车行业前所未有的事:约 4000 名车主自发组织,逆向工程车辆专有软件,破解 CAN 总线协议,试图以开源的方式延续这辆车的数字生命。
智能汽车的"软死亡"问题
传统燃油车破产的影响是有限的——零件供应链还在,独立修车厂能接活。但现代智能汽车不同,软件深度介入了几乎所有核心功能:
- 动力域:电池管理、电机控制、能量回收策略都由固件决定
- 舒适域:空调、座椅、门锁依赖 CAN 总线指令
- 信息域:导航、娱乐、OTA、远程 App 全部需要云端认证
一旦制造商关闭云端服务,这些功能不是"降级",而是直接失效。Fisker Ocean 的车主很快发现:手机 App 无法解锁车门,导航地图不再更新,甚至部分驾驶辅助功能也因为缺少云端校验而受限。
这不是个案。通用汽车曾关闭 Bolt 的远程 App 功能,沃尔沃 Polestar 也出现过服务中断。只是 Fisker 走得更远——公司直接不存在了。
逆向工程:从黑盒到协议文档
车主社区的核心技术路径是逆向工程 CAN 总线协议。现代汽车的内部通信几乎都基于 CAN(Controller Area Network)总线——各个 ECU(电子控制单元)通过标准化的 CAN 帧交换数据。虽然 CAN 帧的物理格式是公开的(ISO 11898),但每条消息的 ID、数据场编码、信号定义是各车企的专有协议,从不公开。
Fisker 车主社区的做法:
- 硬件接入:通过 OBD-II 端口连接 CAN 分析器(如 CANable、Macchina M2),读取总线上的实时流量
- 流量录制:在不同操作场景下(开门、启动、调节空调等)录制 CAN 流量,建立"操作-消息"对照表
- 信号解码:对特定 CAN ID 的数据场进行位级分析,提取温度值、开关状态、转速等信号
- 协议文档化:将逆向结果整理为开放式协议规格,供社区开发替代软件使用
下面是一个实际可用的 CAN 总线嗅探与初步解码示例,基于 python-can 库——这是车主社区和汽车逆向工程师最常用的工具之一:
# 安装依赖:pip install python-can can-utils
# 硬件准备:CANable USB-CAN适配器,连接车辆OBD-II端口
import can
import time
import struct
from collections import defaultdict
# 配置CAN接口——CANable使用slcan模式
bus = can.Bus(interface='slcan', channel='/dev/ttyACM0',
bitrate=500000, tty_baudrate=115200)
# 录制消息,按CAN ID分组统计
message_log = defaultdict(list)
RECORD_SECONDS = 30
print(f"录制 CAN 流量 {RECORD_SECONDS} 秒,请执行目标操作(如开门)...")
start = time.time()
while time.time() - start < RECORD_SECONDS:
msg = bus.recv(timeout=1.0)
if msg:
message_log[msg.arbitration_id].append({
'data': msg.data.hex(),
'timestamp': msg.timestamp,
'dlc': msg.dlc
})
bus.shutdown()
# 输出各ID的消息频率和数据变化
print("\n=== CAN ID 活动摘要 ===")
for arb_id in sorted(message_log.keys()):
msgs = message_log[arb_id]
unique_data = set(m['data'] for m in msgs)
print(f"ID: 0x{arb_id:04X} | 消息数: {len(msgs)} | "
f"不同数据值: {len(unique_data)} | "
f"频率: {len(msgs)/RECORD_SECONDS:.1f} Hz")
if len(unique_data) <= 5:
for d in sorted(unique_data):
print(f" 数据: {d}")
# 初步信号猜测:对变化频繁的ID做字节级差异分析
print("\n=== 可能的控制信号候选 ===")
for arb_id, msgs in message_log.items():
data_set = [bytes.fromhex(m['data']) for m in msgs]
if len(set(data_set)) > 1:
# 找出哪些字节在不同消息间发生了变化
changed_bytes = set()
for i in range(8):
values_at_i = [d[i] if i < len(d) else 0 for d in data_set]
if len(set(values_at_i)) > 1:
changed_bytes.add(i)
if changed_bytes:
print(f"ID 0x{arb_id:04X} 变化字节位: {sorted(changed_bytes)}")
# 示例:如果byte[0]在0x00和0x01之间切换,可能是开关信号
for b in sorted(changed_bytes):
vals = sorted(set(d[b] if b < len(d) else 0 for d in data_set))
print(f" byte[{b}] 取值: {[hex(v) for v in vals]}")
运行前需要:
- 一台 CANable 或类似 USB-CAN 适配器(约 $25–$60)
- 连接车辆的 OBD-II 端口(标准 16 针接口,所有乘用车都有)
- Linux 环境(Windows 可用 can.Bus(interface='vector', ...) 配合 Vector 硬件)
这段代码的核心思路是:录制一段 CAN 流量,统计每个 ID 的消息频率和数据变化,自动标记出"操作时发生了变化"的候选信号。这是逆向 CAN 协议的第一步——从黑盒流量中定位控制指令。
开源替代软件的架构挑战
逆向协议只是起点。真正的目标是构建替代软件栈,让车辆在没有原厂云端的情况下继续运行。社区面临的架构挑战包括:
网关与安全域隔离:现代汽车通常有多个 CAN 子网(动力域 CAN-FD、车身域 CAN、信息娱乐域 Ethernet),通过中央网关隔离。逆向一个子网不等于能控制另一个子网。Fisker Ocean 的网关可能需要单独的认证机制才能跨域发送指令。
ECU 固件签名:大多数 ECU 固件更新需要制造商的数字签名。没有签名密钥,社区无法直接刷写替代固件。可能的绕行路径是在信息娱乐系统(通常基于 Android/QNX)上运行中间层软件,拦截并重写 CAN 指令,而不是替换 ECU 固件本身。
云端功能本地化:远程解锁、导航地图、语音助手等功能依赖云端 API。社区需要搭建本地服务器替代这些 API 端点,并让车载系统指向新地址——这通常需要修改车载系统的 DNS 或 API 配置,有时还需要绕过 TLS 证书校验。
一个简化的本地替代服务架构可以这样搭建:
# docker-compose.yml — Fisker Ocean 本地替代服务栈
# 前提:车载系统已修改API端点指向本地服务器(需root信息娱乐系统)
services:
# 替代远程解锁与车辆状态API
vehicle-api:
build: ./vehicle-api
ports:
- "443:443"
environment:
- CAN_INTERFACE=can0
- VEHICLE_ID=${VIN}
volumes:
- ./certs:/etc/ssl/certs:ro # 自签证书,需车载端信任
- ./can-config:/etc/can-config # 逆向得到的CAN协议定义
network_mode: host # 需要访问CAN接口
# 本地地图与导航服务(基于OpenStreetMap)
navigation:
image: openstreetmap/tile-server:latest
ports:
- "8080:80"
volumes:
- map-data:/var/lib/mod_tile
# OTA模拟服务——社区签发的更新包
ota-server:
build: ./ota-server
ports:
- "8443:8443"
environment:
- UPDATE_REPO=https://github.com/fisker-community/updates
- SIGNING_KEY=${COMMUNITY_KEY_PATH}
volumes:
- ./updates:/var/lib/ota-packages
volumes:
map-data:
这个架构的关键假设是:社区已经成功 root 了车载信息娱乐系统,并能修改其 API 端点配置。在 Fisker Ocean 上,信息娱乐系统基于 Android Automotive,社区正在尝试通过工程模式或已知漏洞获取 root 权限。
法律边界与风险
这项行动的法律风险不容忽视:
- DMCA 1201:美国《数字千年版权法》禁止绕过技术保护措施,逆向工程 ECU 固件可能触发此条款。不过 2021 年 LIBRARY OF Congress 的豁免规则允许对车辆诊断和修复目的的逆向,但范围有限。
- 安全责任:社区修改的软件如果导致动力域异常(如电池管理错误),可能引发安全事故,且没有任何法律主体承担责任。
- 保险影响:改装软件的车辆可能被保险公司拒赔或要求额外保费。
社区正在通过法律顾问寻求合规路径,包括向破产法庭申请获取源代码和签名密钥的许可——这在破产清算中并非不可能,法庭有权将知识产权转移给能维护产品安全的新实体。
更广泛的启示
Fisker 车主的故事暴露了一个系统性问题:智能汽车的软件生命周期正在超过制造商的商业生命周期。一辆车的设计寿命是 10–15 年,但一家初创车企的平均存活时间可能只有 3–5 年。当制造商死亡,软件也跟着死亡,消费者花 5 万美元买的产品就在数字意义上报废了。
可能的制度性解决方案:
| 方案 | 优势 | 难点 |
|---|---|---|
| 破产时源代码强制开源 | 法律路径清晰,法庭已有权力 | 车企可能用第三方IP,无法单方面开源 |
| 车辆软件"预付维护基金" | 经济激励可持续 | 增加购车成本,监管框架缺失 |
| 法定最低软件支持期 | 消费者保护直接 | 需要立法,对初创车企负担重 |
| 社区开源接管 | 无需等待立法,自下而上 | 法律风险大,技术门槛高 |
对于正在购买智能电动车的消费者,一个务实的检查清单:
- 查车企财务健康度:初创车企的破产概率远高于传统车企,这直接影响你的车能活多久
- 评估软件依赖深度:哪些核心功能依赖云端?如果云端消失,车还能开吗?
- 确认 OBD-II 访问权限:法规要求提供 OBD-II 端口,但部分车企通过网关锁限制访问深度
- 关注开源生态:像 Tesla、比亚迪这样销量巨大的车企,社区逆向生态更成熟;小众车型则风险更高
- 保留工程模式入口:购车时了解是否存在工程/诊断模式,这是未来自救的技术窗口
Fisker 车主正在做的事情,本质上是在探索一个新范式:当商业组织无法维护产品时,用户社区能否成为软件的继任维护者? 这不仅是汽车行业的问题——智能家居、IoT 设备、云依赖软件都在面临同样的"制造商死亡=产品死亡"困境。4000 名车主的实践,无论最终成败,都在为这个范式提供第一份真实的数据。