当车企破产:4000 名车主如何用逆向工程与开源续命一辆智能汽车

2026-05-19 31 预计阅读时间:1 分钟
来源:oschina.net AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:13 分钟

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 车主社区的做法:

  1. 硬件接入:通过 OBD-II 端口连接 CAN 分析器(如 CANable、Macchina M2),读取总线上的实时流量
  2. 流量录制:在不同操作场景下(开门、启动、调节空调等)录制 CAN 流量,建立"操作-消息"对照表
  3. 信号解码:对特定 CAN ID 的数据场进行位级分析,提取温度值、开关状态、转速等信号
  4. 协议文档化:将逆向结果整理为开放式协议规格,供社区开发替代软件使用

下面是一个实际可用的 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,无法单方面开源
车辆软件"预付维护基金" 经济激励可持续 增加购车成本,监管框架缺失
法定最低软件支持期 消费者保护直接 需要立法,对初创车企负担重
社区开源接管 无需等待立法,自下而上 法律风险大,技术门槛高

对于正在购买智能电动车的消费者,一个务实的检查清单:

  1. 查车企财务健康度:初创车企的破产概率远高于传统车企,这直接影响你的车能活多久
  2. 评估软件依赖深度:哪些核心功能依赖云端?如果云端消失,车还能开吗?
  3. 确认 OBD-II 访问权限:法规要求提供 OBD-II 端口,但部分车企通过网关锁限制访问深度
  4. 关注开源生态:像 Tesla、比亚迪这样销量巨大的车企,社区逆向生态更成熟;小众车型则风险更高
  5. 保留工程模式入口:购车时了解是否存在工程/诊断模式,这是未来自救的技术窗口

Fisker 车主正在做的事情,本质上是在探索一个新范式:当商业组织无法维护产品时,用户社区能否成为软件的继任维护者? 这不仅是汽车行业的问题——智能家居、IoT 设备、云依赖软件都在面临同样的"制造商死亡=产品死亡"困境。4000 名车主的实践,无论最终成败,都在为这个范式提供第一份真实的数据。


相关推荐