基于ICSim的基础实践
1、ICSim模拟环境搭建
1、安装ICSim
# 安装依赖
sudo apt install libsdl2-dev libsdl2-image-dev can-utils maven autoconf -y
# 下载ICSim
git clone https://github.com/zombieCraig/ICSim.git
# 编译安装
cd ICSim/
sudo make

2、安装socketcand
# 下载socketcand
git clone https://github.com/linux-can/socketcand.git
cd socketcand
# 获取缺少的文件
wget https://raw.githubusercontent.com/dschanoeh/socketcand/master/config.h.in
# 编译安装
autoconf
./configure
make clean
make
sudo make install
教程上的应该是不能用了,文件夹中不存在makrfile文件
使用官方教程安装
$ meson setup -Dlibconfig=true --buildtype=release build
$ meson compile -C build
$ meson install -C build

3、安装Kayak
# 下载
git clone https://github.com/dschanoeh/Kayak.git
# 安装jdk
sudo apt-get install openjdk-8-jdk
# 安装
cd Kayak
mvn clean package

2、启动模拟器
./icsim vcan0 #模拟器
./controls vcan0 #控制面
其控制器的按键说明如下:
| 功能 | 按键 |
|---|---|
| 加速 | 上方向键 |
| 左转向 | 左方向键 |
| 右转向 | 右方向键 |
| 开/关左车门(前)锁 | 右/左shift+A |
| 开/关右车门(前)锁 | 右/左shift+B |
| 开/关左车门(后)锁 | 右/左shift+X |
| 开/关右车门(后)锁 | 右/左shift+Y |
| 开启所有车门锁 | 右shift+左shift |
| 关闭所有车门锁 | 左shift+右shift |
1、加速

2、左转

3、前门开启


关闭

3、can数据分析
我们使用candump进行数据的收集

然后,找到与转向灯控制、车门控制、加速控制相关的CAN数据帧。
我们根据统计频率进行查找
代码如下:
import sys
def read_can_data(file_path):
"""
读取文件并提取CAN ID和数据。
参数:
file_path (str): 文件路径。
返回:
tuple: (CAN ID 列表, CAN 数据列表)
"""
result_id = []
result_data = []
with open(file_path, "r") as file:
for line in file:
parts = line.split(' ')[2]
can_id = parts.split('#')[0]
result_id.append(can_id)
result_data.append(parts)
return result_id, result_data
def print_id_counts(result_id):
"""
打印每个CAN ID出现的次数。
参数:
result_id (list): CAN ID 列表。
"""
unique_ids = set(result_id)
for can_id in unique_ids:
print(f"{can_id}: {result_id.count(can_id)}")
def search_data_by_id(result_data):
"""
根据用户输入的CAN ID搜索并打印对应的数据。
参数:
result_data (list): CAN 数据列表。
"""
while True:
inp = input("please input id: ")
for data in result_data:
if inp in data.split("#")[0]:
print(data)
def main():
"""
主函数,执行读取数据、打印统计信息和搜索数据功能。
"""
if len(sys.argv) < 2:
print("Usage: python script.py <input_file>")
return
file_path = sys.argv[1]
result_id, result_data = read_can_data(file_path)
print_id_counts(result_id)
search_data_by_id(result_data)
if __name__ == "__main__":
main()
查找转向灯控制的帧,我只转向一次,因此形成的数据帧应当较少
频率如下

首先从5a1看起

这里没有仅一次操作的,接下来是188

这里有仅一次的操作
我们对其进行cansend重放,经过操作发现左转灯可以亮起

因此左转的帧id为
188#01000000
同理,这里对非0字段进行测试,发现仅有1,2,3分别控制左转,右转和双闪
188#02000000
开关门帧分析
我这里限制开关门次数,首先只开了前左门一次,查看频率

这里19B为一次,那么就是该帧,对字段进行修改,发现如下结果

19B#00000E000000 #前左门打开
19B#00000C000000 #前右门和前左门打开
19B#000008000000 #仅右后门关闭
19B#000000000000 #车门全开
二分法
由于加减速控制很难通过数量去分析,这里只能使用二分法来进行分析
省略前置步骤,目前加速锁定在50条数据中

如图所示,我们将其分割为五个文件,进行重放测试,发现只有xab触发了加速
对xab进行分割

发现其分割后的xab能够触发加速控制
draw@draw-ubuntu:~/Desktop$ cat xab
(1753163620.410724) vcan0 244#00000015B6
(1753163620.411180) vcan0 095#800007F400000026
(1753163620.411201) vcan0 166#D0320036
(1753163620.411209) vcan0 158#0000000000000037
(1753163620.411212) vcan0 161#000005500108003A
对其逐个测试

发现该帧能够触发加速控制,所以速度控制的帧id为244
4、SavvyCAN使用
首先需要安装qt环境,这里我使用5.14.2版本(https://download.qt.io/archive/qt/5.14/5.14.2/)(savvyCAN环境要求>=5.14.0版本),下载".run"的在线安装程序,然后其赋予执行权限(chmod 755 qt-xxx.run),使用"./qt-xxx.run"进行安装,这里我安装完毕后的目录为"~/Qt5.14.2/5.14.2"。

git clone https://github.com/collin80/SavvyCAN.git
sudo apt install libqt5serialbus5-dev libqt5serialport5-dev qtdeclarative5-dev qttools5-dev
cd SavvyCAN
~/Qt5.14.2/5.14.2/gcc_64/bin/qmake
make

使用该命令启动工具
./savvyCAN
界面如下:

我们需要先连接vcan0才能进行下一步操作。点击Connection然后点击"open Connection Window"。

点击"Add New Device Connection - QT SerialBus Device-socketcan-vcan0",然后点击"Create New Connections",最后"Save Bus Settings"就创建好连接了。

savvyCAN工具部分功能与我们上面使用的can-utils工具相同,下图为RE tools中的sniffer功能,与我们上面操作使用的cansniffer功能相同,但是savvyCAN中变化的数据使用了颜色进行标记,更便于我们辨识数据。
然后启动模拟器

这里能看到许多帧
1、RE Tools
Detailed frame data

左侧:Frame IDs ,当前捕获数据中出现的所有唯一的 CAN 帧 ID
然后是details,其中有如下信息
帧数量,数据长度,对每位数据的统计

例如该图中,该位数据的范围是0x00-0x2B,且给出每种数据的帧数
Bitfield Histogram****直方图

统计该帧 ID 所有数据字节中,每个比特位 (Bit) 出现 0 或 1 的频数
Flow view

该工具在特定的frame id下,以时间线为顺序,逐帧显示变化的bit位,按下->按钮

在这里,红色代表之前为1的位置,绿色代表当前为1的bit位置
下方的->按钮则是自动按照时间顺序进行帧播放
5、通过其FUZZ功能筛选灯控、门控、加速的关键数据帧。
(1)这里通过fuzz进行筛选控制帧
这里设置 id=0x244,bit选择random

开始fuzz以后,速度变化非常快(车门在fuzz前打开)
所以速度控制的canid=0x244
得到id以后,对其控制字段进行fuzz,首先设置第一个字节为00

这里状态不发生变化,依照此原理,进行修改
直到第四个字节设置以后,速度不发生变化,那么,该帧为控制字段

然后,设置单bit进行fuzz
将首bit设置为0时


将单bit设置为1时


对比发现,当首bit=0时,是从0速度开始加速的,而首bit=1时,是从最大速度进行减速的,因此该字段应当是控制加减字段
进行测试,我们设置后7字段为固定值1010101


因此,该值为控制加减速字段
而后,测试后续字段
设置为00010101

设置00110100

经过测试该字段应当是控制加速/减速力度
因此加速控制如下:
canid#000000[control_bit(1)|speed_bits(7)]00
(2)通过fuzz筛选转向控制帧
设置id=0x188,依然选择random,开始fuzz

转向灯快速变化,因此转向控制canid=0x188
步骤如上,测试字节位置

因此控制字段在首字节
然后测试bit,经过测试
0x01为左转控制

0x02为右转控制

左转:188#01000000
右转:188#02000000
双闪:188#03000000
(3)通过fuzz筛选门控帧
设置id=0x19B,依然选择random,开始fuzz



在这里车门状态快速变换,因此车门控制canid=0x19B
步骤同上,测试第三个字节为控制字段

经过测试,是由低四个bit来控制车门打开关闭
0000表示车门全开

0001表示仅左前车门关闭

0010表示仅右前车门关闭

步骤同上,测试完成

浙公网安备 33010602011771号