基于 CAN 总线操作汽车仪表盘模拟器实用指南

  • A+
所属分类:安全文章

基于 CAN 总线操作汽车仪表盘模拟器实用指南

最近在外文博客看了相关的系列文章,学习结束后决定翻译整理做一个笔记,整理笔记的过程中曾试图放弃,阅读实践半小时,整理笔记用几天,以后再慢慢培养整理笔记的技能吧。重要的事情说三遍:文末有彩蛋、文末有彩蛋、文末有彩蛋。

CAN 相关知识

CAN总线简介

CAN 是控制器局域网络(Controller Area Network)的简称,是实现汽车所有或部分部件之间通信的中枢神经系统,由以研发和生产汽车电子产品著称的德国 BOSCH 公司开发并最终成为国际标准(ISO 11898),是国际上应用最广泛的现场总线之一。在使用 CAN 作为车内通信系统之前,汽车制造商使用的是点对点布线系统,当汽车内部电子单元越来越多时,这种布线系统会显得特别庞大且维护成本太高,后来通过使用 CAN 代替来解决这个问题。

简单来说,CAN 可以让汽车上的各个电子单元相互通信、共享数据,提出 CAN 的主要原因是它允许多个 ECU(Electronic Control Unit,电子控制单元)共用一根导线进行通信。在一辆现代汽车中存在多达 70 个 ECU,例如:发动机控制单元、安全气囊、变速箱、齿轮单元、防抱死制动系统(ABS)、信息娱乐系统、气候控制系统、车窗、车门等部件,为了让这些单元之间能够相互通信,点对点布线会显得特别庞大。试想一下,每一个组件都连接到其它全部组件,对于后期故障诊断和排除来说是相当糟糕的,但是有了 CAN 就可以用单线代替,每个元件之间的通信就简单了许多。

基于 CAN 总线操作汽车仪表盘模拟器实用指南

CAN 总线可以被认为是一个嘈杂、拥挤、慢速版的以太网局域网,只是流量是 UDP 而不是 TCP。值得注意的是,并不是所有的汽车控制系统都使用 CAN,而且 CAN 不仅仅是汽车系统中使用的通信协议,还可能有其它协议,如蓝牙、GSM/LTE 蜂窝网络、卫星无线电、LIN(Local Interconnect Network)等。在实际场景中,CAN 并不是唯一的攻击面,可能还存在很多其它的攻击面。

CAN 的工作

一辆汽车可以有多个节点,能够发送或接收报文,这个报文基本上由一个 ID 组成,它的优先级,也可以包含 CAN 报文,一次可以是 8 个字节或更少。如果两个或两个以上的节点同时开始发送报文,那么以主导 ID 发送的报文将覆盖依次主导 ID 发送的报文,这就是所谓的基于优先级的总线仲裁。ID 数值越小的报文优先级越高,这就是节点判断报文传输先后的依据。来自制动器的报文比来自音频播放器的报文具有更高的优先级。

CAN 总线由两根不同的导线组成,由于它是总线,因此这些导线可以连接到多个设备。一个 CAN 帧有 3 个主要部分:

1、仲裁标识符

2、数据长度代码

3、数据领域

下面来看看 CAN 数据帧的结构:

基于 CAN 总线操作汽车仪表盘模拟器实用指南

基于 CAN 总线操作汽车仪表盘模拟器实用指南

如何在真实的汽车上访问 CAN 总线

为了访问汽车的 CAN 总线,需要先访问车载自诊断端口,也就是 OBD。虽然可能存在数以百计的其它诊断标准或者端口,但基本上现在所有汽车都使用的 OBD-Ⅱ,这也正是修车修理工用来识别汽车故障的途径,OBD 是最直接访问 CAN 的,找到 OBD-Ⅱ 的方法非常简单,它通常位于乘客座椅或者驾驶员座椅附近,且不用使用螺丝刀就能访问。

这就是 OBD 的具体样子:

基于 CAN 总线操作汽车仪表盘模拟器实用指南

如果您想知道 OBD 的引脚,下面是 OBD 端口的引脚:

基于 CAN 总线操作汽车仪表盘模拟器实用指南

通过 OBD 访问 CAN 所需的硬件和软件

因为电脑不能直接与 CAN 连接,为了与 CAN 总线交互,需要类似 USB 转 CAN 的工具,通过 USB 连接到 OBD-II 端口,这样就可以发送或接收 CAN 数据包。同时在软件上需要一些能够读取或写入 CAN 数据包以及编码或解码 CAN 数据包的工具。只要有一点硬件和软件,绝对可以连接 CAN。

硬件

连接 OBD-II 所需的硬件可以很容易地在市场上找到,有昂贵以及廉价的硬件设备。高端设备包括 Kvaser 和 EMS,这些设备价格昂贵且矫枉过正,性价比很高的组合是 USB2CAN 和原生的 Linux 系统。

基于 CAN 总线操作汽车仪表盘模拟器实用指南

另外,很多时候会遇到 ELM327,它是一个基于蓝牙的设备,但对于黑客来说是非常糟糕的,原因是它的数据速率比较慢,最后会丢失很多数据包。

基于 CAN 总线操作汽车仪表盘模拟器实用指南

Macchina M2 是一个开源的汽车接口,可以通过 OBD-II 与 CAN 总线通信。Macchina M2 最大的优点是它是模块化的,也就是说可以在 Macchina M2 的基础上增加 WiFi、GSM、LTE、BLE 模块。Macchina M2 有 2 个 CAN 通道。Macchina M2 还具有 LIN,可以通过访问链接:

https://www.macchina.cc/catalog/m2-boards/m2-under-dash

获取更多关于 Macchina M2 的信息。

基于 CAN 总线操作汽车仪表盘模拟器实用指南

另一个低成本的选择是 CSS 电子公司的 CLX000,它可以记录和流式传输 CAN 数据,数据可以在免费的开源软件 Wireshark 中可视化,一个插件便可以实现逆向功能,CLX000 是可视化和远程信息处理的理想选择。

可以通过访问链接:

https://www.csselectronics.com/screen/page/reverse-engineering-can-bus-messages-with-wireshark/language/en

获取更多关于 CLX000 的信息,在博客中也有一些关于 CAN 的文章。

软件

在软件方面,Linux 内核中内置了 SocketCAN、can-utils、vcan,它们的作用是发送和接收 CAN 数据包,对数据进行编码或解码,也可以通过 Wireshark 分析 CAN 数据包。

如果想了解更多关于 CAN 操作的知识,而又不想破坏自己的汽车,ICSim 将会是首选工具:

https://github.com/zombieCraig/ICSim

ICSim 安装及设置

安装 SDL 库

SDL 是用于计算机图形和音频的跨平台开发库,由于 ISCim 使用 SDL 绘制虚拟汽车组合仪表板的动画,因此必须安装。这可以通过 apt-get 安装:

sudo apt-get install libsdl2-dev libsdl2-image-dev -y

安装 CAN Utils

can-utils 是一套 Linux 特有的实用工具,它可以让 Linux 与车辆上的 CAN 网络进行通信,为了发送、接收和分析 CAN 数据包,需要安装 CAN utils。canutils 主要包括 5 个经常使用的工具:

1、cansniffer 用于嗅探数据包

2、cansend 发送一条数据

3、candump 转储所有接收的数据包

4、canplayer 重播 CAN 数据包

5、cangen 随机生成 CAN 数据包

这可以通过 apt-get 安装:

sudo apt-get install can-utils -y

安装 ICSim

git clone https://github.com/zombieCraig/ICSim

cd ICSim

make

准备虚拟 CAN 网络

进入 ICSim 目录,有一个名为 setup_vcan.sh 的 shell 脚本:

基于 CAN 总线操作汽车仪表盘模拟器实用指南

modprobe 命令是用来加载内核模块,比如 can 和 vcan 模块,最后两行将创建一个 vcan0 接口以便模拟汽车网络,可以运行下面的命令来设置一个虚拟的 can 接口:

./setup_vcan.sh

要验证 vcan0 接口,如果配置 vcan0 将显示:

基于 CAN 总线操作汽车仪表盘模拟器实用指南

运行 ICSim

运行 ICSim 至少需要两个组件,一个仪表盘和一个控制器,用来模拟加速、刹车、控制车门、转向灯等,需要至少 3 个终端窗口或标签来运行仪表盘、控制器和 can-utils。

运行仪表盘

为了运行仪表盘,需要运行一个名为 icsim 的文件,参数为 vcan0,也就是之前创建的接口。

./icsim vcan0

基于 CAN 总线操作汽车仪表盘模拟器实用指南

运行控制器

此时,仪表盘仍无法正常工作,包括速度表、转向灯、刹车和车门。这是因为接口 vcn0 上没有流量,为了模拟接口 vcan0 上的流量,这里需要启动控制器。

./controls vcan0

基于 CAN 总线操作汽车仪表盘模拟器实用指南

控制器操作仪表盘

vcan0 是一个虚拟的 CAN 接口,ICSim 将通过它来发送和接收 CAN 帧,当启动控制面板时,可以观察到车速表有一些波动,这是因为控制面板模拟了噪声,启动控制面板后,便可以使用键盘来模拟流量。

行为 快捷键
加速
左右转向 ←/→
解锁前左右车门 Right-Shift + A/B
解锁后左右车门 Right-Shift + X/Y
锁定全部车门 Right-Shift + Left-Shift
解锁全部车门 Left-Shift + Right-Shift

CAN 总线操作

CAN 报文

基于 CAN 总线操作汽车仪表盘模拟器实用指南

这是 CAN 报文通过 can-utils 采集后的具体样子,如果把这几列细分的话,第一列是接口,第二列是仲裁 ID,第三列是 CAN 报文的大小,这个不能超过 8 个字节,如果看一下 CAN 帧,就更明白为什么这个不能超过 8 个字节,第四列是 CAN 数据本身。

理解 CAN 报文

基于 CAN 总线操作汽车仪表盘模拟器实用指南

在这个例子中,这是一个 8 字节的帧,该消息是由一个仲裁 ID 0x111 发送的,仪表盘看到这个报文后,首先会确定这个报文是否是为仪表盘准备的,如果是那么它就会读取这个报文,这个报文的数据是 0x0BB8,即十进制的 3000,现在仪表盘会将转速表的指针移到 3000。

基于 CAN 总线操作汽车仪表盘模拟器实用指南

了解了 CAN 报文的意义后,就可以进一步通过 ODB-II 在 CAN 总线上注入假的或修改后的数据包来欺骗转速表或其它东西。

can-utils

在进入 ICSim 的演示之前,需要先看看 can-utils 提供的其它工具是如何工作的,要做到这一点首先需要设置虚拟 can 接口,下面的内容主要是讲解 setup_vcan.sh 文件内的命令具体是什么含义,在实际操作中可以直接运行 setup_vcan.sh 文件。

设置虚拟 CAN 接口

加载 CAN 的内核模块以及虚拟 CAN 的内核模块:

sudo modprobe can

sudo modprobe vcan

验证是否加载了所需的内核模块:

lsmod | grep can

这将显示 can 和 vcan 的内核模块是否被加载:

基于 CAN 总线操作汽车仪表盘模拟器实用指南

接下来设置虚拟接口:

sudo ip link add dev vcan0 type vcan

sudo ip link set up vcan0

可以通过下面方法来验证虚拟 CAN 接口是否设置成功:

ifconfig vcan0

基于 CAN 总线操作汽车仪表盘模拟器实用指南

虚拟 CAN 接口设置成功后就可以在这个接口中发送或接收 CAN 数据包了,接下来使用 can-utils 中的一个叫做 cangen 的工具来生成虚拟的 CAN 数据包。

cangen

基于 CAN 总线操作汽车仪表盘模拟器实用指南

cangen 可以生成用于测试的 CAN 帧,要使用 cangen 需要指定要生成 CAN 帧的接口,这里 vcan0 是创建的虚拟 CAN 接口:

cangen vcan0

生成 CAN 帧后,有很多工具可以查看 CAN 帧的内容,这里以 Wireshark 举例。

基于 CAN 总线操作汽车仪表盘模拟器实用指南

这里可能会看到很多接口可用,但只需要关注 CAN 帧生成的接口 vcan0,点击 vcan0 接口便可以看到 CAN 帧的内容:

基于 CAN 总线操作汽车仪表盘模拟器实用指南

还能看到更多 CAN 帧的详细信息:

基于 CAN 总线操作汽车仪表盘模拟器实用指南

另外,可以选择使用 can-utils 提供的工具,比如 cansniffer 和 candump,它们的功能和 Wireshark 差不多。

candump

基于 CAN 总线操作汽车仪表盘模拟器实用指南

可以使用 candump 转储或记录 CAN 帧:

candump vcan0

candump 会将 CAN 帧输出显示:

基于 CAN 总线操作汽车仪表盘模拟器实用指南

下面的终端中正在运行 cangen 生成 CAN 帧,上面的终端正在运行 candump 记录 CAN 帧,记录的 CAN 帧可以分为四列,第一列是 CAN 接口,第二列是仲裁 ID,第三列是 CAN 数据的大小,第四列是数据本身。

candump 还可以转储 CAN 帧,如果想进行重放攻击,需要先转储 CAN 帧,然后使用 canplayer 对转储的 CAN 帧进行重放,CAN 帧的转储可以使用 -l 参数启动:

candump -l vcan0

基于 CAN 总线操作汽车仪表盘模拟器实用指南

使用 candump 转储 CAN 帧时,会创建一个以 candump 为前缀和日期命令的文件,如果想查看转储文件的内容,可以在 Linux 中使用 cat 命令查看:

基于 CAN 总线操作汽车仪表盘模拟器实用指南

canplayer

基于 CAN 总线操作汽车仪表盘模拟器实用指南

顾名思义,canplayer 是用来重放 CAN 帧的工具。理想情况下,当必须进行重放攻击时,首先需要转储或记录 CAN 帧,然后使用 canplayer 对 CAN 帧进行重放。

想象一个场景,希望对转速表进行欺骗,但是却不知道转速表的读数在哪个仲裁 ID 上工作,这种情况需要先用 candump 的 -l 参数转储 CAN 帧数,然后用 canplayer 重放转储的 CAN 帧,使用 canplayer 重放 CAN 帧时需要通过 -I 参数来接受输入文件:

canplayer -I canfile.log

canplayer 还有一些其它非常好用的参数,可以通过man canplayer获取。

cansniffer

基于 CAN 总线操作汽车仪表盘模拟器实用指南

cansniffer 是用于嗅探 CAN 数据包的工具。cansniffer 的 -c 参数可以通过颜色高亮突出变化的字节,当需要判断执行某些操作是否会导致 CAN 数据变化时使用。

cansniffer -c vcan0

基于 CAN 总线操作汽车仪表盘模拟器实用指南

cansniffer 可以通过仲裁 ID 进行过滤,当需要只显示某一个特定仲裁 ID 的帧时,只需在嗅探的过程中,按减号(-)然后输入 000000,再按 Enter 键清除所有的帧,按加号(+)然后输入仲裁 ID,再按 Enter 键便只显示特定仲裁 ID 的帧。

cansend

基于 CAN 总线操作汽车仪表盘模拟器实用指南

cansend 是用于将 CAN 帧发送到特定 CAN 接口的工具:

cansend interface frame

以上就是在 ICSim 中将会使用到的工具。

启动 ICSim

前面已经介绍了如何安装和设置 ICSim,这里直接启动仪表盘和控制器:

./icsim vcan0

./controls vcan0

基于 CAN 总线操作汽车仪表盘模拟器实用指南

如果按照前面的流程,这里应该没有什么问题,可以看到速度表指针正在来回移动,这是噪音引起的预期行为。

嗅探 ICSim 的 CAN 帧

将使用 can-utils 提供的 cansniffer 工具来嗅探数据包,可以打开一个新的终端并启动 cansniffer,并通过 -c 参数显示 CAN 帧内字节的变化:

cansniffer -c vcan0

基于 CAN 总线操作汽车仪表盘模拟器实用指南

可以看到 CAN 帧的变化非常快,很难跟上通信发生的速度,在真实的汽车中,这种通信会发生得更快,为了跟上它的速度,可以使用仲裁 ID 过滤。如果只想查看仲裁 ID 为 40C 的帧,可以按减号(-)然后输入 000000,再按 Enter 键清除所有的帧,按加号(+)然后输入 40C,再按 Enter 键便只显示仲裁 ID 为 40C 的帧。

基于 CAN 总线操作汽车仪表盘模拟器实用指南

重放攻击

在进行重放攻击前需要打开 ICSim,这个时候会在 cansnifer 工具中看到 CAN 帧的变化,在使用candump -l vcan0转储 CAN 帧的同时在控制器对仪表盘进行操作,例如:加速、转向,然后停止转储,将会看到创建了一个 candump-XXXXX.log 命名的文件,接下来使用canplayer -I candump-XXXXX.log对转储的 CAN 帧进行重放,将会在仪表盘中看到转储时进行的操作。

转储 CAN 帧分析

在真实的汽车中,CAN 总线的噪音可能会大很多,且 CAN 帧出现速度也会快很多,所以如何识别出关键的仲裁 ID 是一个难题,这里列出两种方法:二分法和统计法,推荐使用统计法。

二分法

将转储的 CAN 帧文件一分为二,然后分别重放观察哪一个文件包含了关键的仲裁 ID,然后对相应的文件再进行操作,依次循环。

统计法

以仲裁 ID 或仲裁 ID 和 CAN 数据为依据,统计出 CAN 帧文件各仲裁 ID 或仲裁 ID 和 CAN 数据出现的次数,根据出现的此处进行判断。

SavvyCAN

目前有很多软件可以监控和过滤 CAN 通信,其中包含收费的专业工具和免费的开源工具,这篇文章的主要目的是在免费的情况下学习汽车黑客,所以不会对收费的专业工具进行介绍。前面已经介绍了 can-utils、Wireshark 两款免费的工具,下面将介绍另外一款图形界面的工具,SavvyCAN 提供了更多额外的功能,它除了能够轻轻的浏览、过滤数据包和仲裁 ID,还可以在 CAN 帧上执行脚本、Fuzzing,以及内置了几个逆向工具。

"SavvyCAN "是一个基于 QT 的跨平台 C++ 程序。它是一个 CAN 总线逆向和捕获工具。它最初是为了利用 EVTV 硬件,如 EVTVDue 和 CANDue 硬件而编写的。它已经扩展到能够使用任何 socketCAN 兼容设备以及 Macchina M2 和 Teensy 3.x 板。它可以同时采集并发送至多个总线和 CAN 采集设备。"

SavvyCAN 官网是这么介绍这款工具的,可以通过链接:

https://www.savvycan.com/

获取更多关于 SavvyCAN 的内容,个人感觉 SavvyCAN比can-utils 更容易使用,这里只是个人观点,不进行争论,大家可以选择自己习惯的工具完成相应的操作。

基于 CAN 总线操作汽车仪表盘模拟器实用指南

安装 SavvyCAN

SavvyCAN 的安装非常简单,可以直接通过访问链接:

https://www.savvycan.com

下载 windows、Linux、mac os 下的二进制文件。这里只在 Linux 下进行演示:

wget https://github.com/collin80/SavvyCAN/releases/download/V199.1/SavvyCAN-305dafd-x86_64.AppImage

这里下载的直接是二进制文件,不需要安装便可运行:

chmod 744 SavvyCAN-305dafd-x86_64.AppImage

./SavvyCAN-305dafd-x86_64.AppImage

基于 CAN 总线操作汽车仪表盘模拟器实用指南

当 SavvyCAN 与 Macchina M2 或任何其它兼容硬件一起使用时,不需要再安装其它额外的东西,但是当与 ICSim 一起使用时,由于需要连接 QT SerialBus Devices,运行直接下载的 SavvyCAN 二进制文件,在 Connection->Open Connection Window->Add New Device Connection 中可以观察到 QT SerialBus Devices 被禁用,需要手动编译 SavvyCAN:

基于 CAN 总线操作汽车仪表盘模拟器实用指南

安装 qt5

wget http://download.qt.io/official_releases/qt/5.12/5.12.4/qt-opensource-linux-x64-5.12.4.run

chmod +x ./qt-opensource-linux-x64-5.12.4.run

sudo ./qt-opensource-linux-x64-5.12.4.run

基于 CAN 总线操作汽车仪表盘模拟器实用指南

安装的过程中如果提示登陆账号,断网重新安装便可。

编译 SavvyCAN

外文博客中这里还编译安装了 qtserialbus,在编译 qtserialbus 的过程中出现了报错,可能是由于版本原因造成的,后来发现不安装 qtserialbus 的情况下也可以正常使用 SavvyCAN。

git clone https://github.com/collin80/SavvyCAN

cd SavvyCAN

/opt/Qt5.12.4/5.12.4/gcc_64/bin/qmake CONFIG+=debug

make

基于 CAN 总线操作汽车仪表盘模拟器实用指南

编译完成后,就可以启动 ICSim 模拟器,接下来不再使用 can-utils,而是使用 SocketCAN 捕获 CAN 通信。

启动 Savvycan

这里启动的是刚刚编译的 Savvycan 二进制文件,而不是前面下载的 Savvycan 二进制文件,如果在真实的汽车上使用,那么无需手动编译,直接运行下载的 Savvycan 二进制文件即可。

cd SavvyCAN

./SavvyCAN

基于 CAN 总线操作汽车仪表盘模拟器实用指南

配置 Savvycan

在 Connection->Open Connection Window->Add New Device Connection 中选择 QT SerialBus Devices,将 SerialBus Devices 选择为 socketcan,将 Port 选择为虚拟端口 vcan0:

基于 CAN 总线操作汽车仪表盘模拟器实用指南

创建新连接结束后,在 SavvyCAN 窗口可以看到已经捕获到了 CAN 帧:

基于 CAN 总线操作汽车仪表盘模拟器实用指南

为了更好的了解 SavvyCAN 的功能,将使用 SavvyCAN 完成前面用 can-utils 完成的操作,在 SavvyCAN 窗口的右边可能通过选择来过滤仲裁 ID:

基于 CAN 总线操作汽车仪表盘模拟器实用指南

由于一些玄学问题,SavvyCAN 的功能并没有完全使用,下面只介绍几个功能,更多功能和用法还是需要以后慢慢摸索。

重放攻击

使用 SavvyCAN 执行重放攻击要容易得多,在 Send Frames 中选择 Playback,可以从文件加载数据或直接从捕获的数据加载数据,还可以从 ID 筛选菜单中选择要重播的 ID。

识别仲裁 ID

SavvyCAN 提供了许多逆向工具,其中经常使用的是 Sniffer,它能够弹出非活动字节,通过二分法过滤仲裁 ID 便可以快速识别出关键的仲裁 ID:

基于 CAN 总线操作汽车仪表盘模拟器实用指南

在上面勾选的仲裁 ID 中并没有发现任何与操作相对应的字节变化,接下来选择上面未勾选的仲裁 ID 进行观察:

基于 CAN 总线操作汽车仪表盘模拟器实用指南

发送自定义帧

SavvyCAN 还有一个非常实用的功能,在 Send Frames 中选择 Custom,它能够发送自定义的帧并可以实时修改:

基于 CAN 总线操作汽车仪表盘模拟器实用指南

Fuzzing

SavvyCAN 还有一个非常酷的功能,在 Send Frames 中选择 Fuzzing,它能够非常容易的对 CAN 帧进行 fuzzing。

挑战

识别油门、车门和转向信号的仲裁 ID,并通过 CAN 完成加速、打开关闭车门、转向的操作。

遗憾

模拟器实践结束,总感觉与真车相比会有很大不同,但是又买不起车,又没有窃格瓦拉的技术,还是需要有机会在真车上实践一番。

参考文章

Car Hacking 101: Practical Guide to Exploiting CAN-Bus using Instrument Cluster Simulator — Part I: Setting Up:

https://yogeshojha.com/me/car-hacking-101-practical-guide-to-exploiting-can-bus-using-instrument-cluster-simulator-part-i-setting-up/

Car Hacking 101: Practical Guide to Exploiting CAN-Bus using Instrument Cluster Simulator — Part II: Exploitation:

https://yogeshojha.com/me/car-hacking-101-practical-guide-to-exploiting-can-bus-using-instrument-cluster-simulator-part-ii-exploitation/

Car Hacking 101: Practical Guide to Exploiting CAN-Bus using Instrument Cluster Simulator - Part III: SavvyCAN, Fuzzing CAN Frame and playing around with CAN frames:

https://yogeshojha.com/me/car-hacking-101-practical-guide-to-exploiting-can-bus-using-instrument-cluster-simulator%e2%80%8a-%e2%80%8apart-iii-savvycan-fuzzing-can-frame-and-playing-around-with-can-frames/

彩蛋

文章都看完了?是不是一脸懵?懵不懵不重要,重要的是寻找小伙伴,一起搞感兴趣的、有意思的事情。

新手小白快点来,一起学习才能嗨。大佬巨牛碗里来,带着菜鸡飞起来。

基于 CAN 总线操作汽车仪表盘模拟器实用指南

本文始发于微信公众号(信安之路):基于 CAN 总线操作汽车仪表盘模拟器实用指南

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: