汽车动力系统 ECU 固件逆向工程初探
作者: gjden
时间: 2016 年 11 月 19 日
偶尔看到国外一些论坛讨论汽车改装(都是基于 ECU 的)的技术问题,于是产生了兴趣,想想如果 ECU 能够被改装,那么它肯定也会面临一些安全问题。所以参阅了一些讨论文章,发现他们讨论的问题基本上都是如何修改 MAP 表 (ECU 中的数据表 ) ,而并没有人基于 ECU 二进制代码的逆向工程,因此有了本文。本文只是做一些关于汽车动力系统 ( 发动机 )ECU 逆向工程的初步探索,在这方面资料稀缺,因此把自己一些粗浅的认知和分析结果放出来,文章必定有错误之处,人外有人天外有天,还望资深人士纠正,另外发出来的目的更希望能够起到抛砖引玉的作用。
一、明确一下 ECU 概念
不必多说, ECU 指的就是汽车电控制单元,也就是 ECU 的本意( Electronic Control Unit )。像防抱死制动系统、自动变速箱、 SAM 模块、多媒体系统、刹车辅助系统、巡航定速系统、自动空调系统、驱动系统、电控自动变速器、主动悬架系统、安全气囊等等都是包含有各自的 ECU, 他们分别由这些 ECU 控制管理并且这些 ECU 都通过 CAN 总线连接起来,形成我们通常所说的汽车网络 ( 车载网络 ) 。
但是汽车行业内大部分人说的 ECU 都特指为发动机 ECU, 也称车载电脑。这种延续了传统老式的叫法,因为早期的汽车只有一个用于管理发动机控制系统的 ECU ,因而大家习惯说的 ECU 实际上指的是发动机 ECU ,比如 ECU 更新、 ECU 调校、 ECU 改装等等概念都是特指发动机 ECU 。包括汽车百科里也都特指 ECU 为行车电脑 / 车载电脑。但国外很多分析文章、论文中涉及 ECU 基本上都是广泛意义的 ECU ,而不特指发动机 ECU 。
下面我截了几张发动机 ECU 的 PCB 图,可以看出 ECU 的 PCB 似乎和普通电子设备的 PCB 差不多。
至于 ECU 控制发动机的原理,几乎所有将汽车的教材中都有,我就不多说了,否则得引出一堆东西,那就是给自己挖了一个大坑,所以还是那一句话:网上资料多,还得靠自摸 ^^ !下图是我从 PPT 上截来的,应该是最直观易懂的图。
二、 ECU 固件获取
先做一点科普,对于大部分汽车玩得比较深的人,对汽车改装都不会陌生,现代意义的汽车改装实际上是对发动机 ECU 固件提取、调校、回写等。 一般通过 ECU 调校可以让发动机输出更高的动力。 ECU 调校通常比较复杂,比如需要对点火时间、喷油量、喷油时间、燃油压力、 增压压力等等参数的调整并且还需要结合负荷、档位、转速、温度等做出最优的调整方案 ,另外还得考虑安全性等等问题。因而需要对汽车系统非常熟悉并且具有丰富的调校经验的工程师才能够完成,所以 ECU 调校的费用也会很高。
ECU 固件的读取和普通设备的固件读取类似,但是也有差别。相似之处就是都需要硬件设备支持,不同在于接口方式的不同(实际上是废话 ^^ )。当然有的 ECU 需要将 ECU 拆解下来进行固件读取,而有的可以直接通过 OBD 口进行固件读取,通过 OBD 读取更加简单,至少不用拆机和焊线。以下是我列举的一些可以进行 ECU 读写的工具,当然并不全,有需要的可以自行搜索购买。
工具名称
简介
CMD Flash
支持 OBD2 、 BDM 和 BOOT 模式对 ECU 进行读写
AZN Tuning
AZN 改装店专用,似乎不向外出售
Galletto 1260
实际就是一根诊断线(内含 OBD 转 USB 芯片)
OpenPort
支持 OBD2 进行数据读写
MPPS V13.02
和 Galletto 1260 类似
当然如果你的汽车支持 OBD2 进行固件读写并且你已经熟悉读写 ECU 固件的诊断命令,那么你也可以连接 OBD2 接口并且向其发送诊断命令来操作,只是相对来说麻烦一些。
下图展示的以上列举的刷 ECU 固件的硬件工具的截图:
Galletto 1260
OpenPort
CMD Flash 工具
AZN Tuning
MPPS v12
如果拆机的话,会涉及接线问题,你可以通过 chip datasheet 来搜索与你车型 ECU 相匹配的芯片手册。下面这张图是奥迪 ECU 的接口图,你可以根据自己 ECU 的类型找到其针脚定义。
目前,大部分的汽车都支持 OBDII 来进行 ECU 的操作,因此来一张 OBDII 关键接口的图:
如果你购买有硬件 FLASH 工具,那么产品相关的说明文档应该可以解决大部分问题,网上也有相当多的资料,实际上 ECU 固件的读写比一般的设备的固件读写简单很多,因而在这里也不细说了。
三、 ECU 固件分析初探
在汽车界玩得最深的估计就是做 ECU 调校了,但是 ECU 调校只是对 ECU MAP 表( ECU 固件中的数据表,后面会有更详细的说明)进行微调并且读修改的数据做校验。但如果对 ECU 固件代码进行逆向工程,我们不仅可以对修改 MAP 表,还可以破解其校验功能(很多买得很贵的 MAP 校验工具就是靠逆向校验函数而编写的,这实际上并不难,因为 MAP 的校验算法本身就不是很复杂),并且修改固件代码流程,甚至可以给其添加功能或者是加一些恶意代码进去,就像我们玩儿 PE 文件一样,在保证其能够正常和安全运行的前提下,你可以自由的改造。
1. 固件信息提取
首先通过二进制数据中的字符串来看看该 ECU 固件的有哪些信息。
上图中我标记的第二行信息是该 ECU 的电子发行包, 我们可以看出该 ECU 是采用的博世的 ECU ME7.1 。此后,我又发现了与发动机相关的信息,如图:
其中 06A906032JB 为发动机零件号,通过零件号可以得知该车型的发动机为宝来发动机,但是 ECU 采用的是博世 ECU ,发动机排量为 1600ml ,变速器为 AG4 自动 4 档位等等。最后,我通过 ME7Info 提取出了更多的信息。比如可能的通信协议硬件号、软件号、软件版本、引擎 ID 等等信息。
2. 指令集识别
如果要对固件进行逆向工程的话,必须知道该固件的 MCU 类型,以便知道该 ECU 采用指令集类型。因此,我首先想到了 binwalk ,因而我尝试了一下, binwalk 识别指令花了很长时间:
Binwalk 识别出来竟然是 ARM ,着实让人兴奋了一把,因为个人对 ARM 指令还是比较熟悉的,更何况 IDA 还可以 F5 。但是看到后面的说明感觉就有点不对,怎么可能只有 540 条有效指令。随后,我用 IDA 来验证了一下,反汇编指令选择 ARM big endian 。并且从 0x12943 的位置开始进行反汇编,如图:
可以明显的看出,这是不正常的代码,并且根据经验,固件开始部分应该会有一大堆中断跳转,但通过 ARM Big Endian 得到的代码却是如下这样:
另外我也尝试了使用 little endian 方式来反汇编,同样是不正确的。
此时,第一步提取的固件信息就很有用了,至少为我们提供了搜索的线索,结合固件涉及的电子属性和发动机相关信息,我发现该 ECU 属于英飞凌的 (Infineon ,前身为西门子集团的半导体部门 ) ,而该 ECU 采用的是 C16X 系列的内核,也就是说该 ECU 封装的实际上 C16X 的 MCU ,这款 MCU 原先属于西门子,因此指令集极有可能也是西门子的。强大的 IDA 果然没有让我失望,其完全支持 C16X 家族系列。在 IDA 中我选择 Siemens C166 进行反汇编,确认后需要填写 RAM 和 ROM 地址 。 RAM 和 ROM 地址目前还不清楚,因而先空着直接反汇编。
从图中我们可以看出部分跳转指令是正常的,但是有的又不正常 ( 红色阴影的地址 ) 。不正常的地址有一个共同点就是都是基于 0x820000 的地址。因而,部分于 MCU 相关的中断服务以及硬件管理代码可能的基地址为 0x000000 ,这就是这部分代码可能映射在 0x0000000 处,而部分与 ECU 相关的中断服务和硬件管理代码可能的基地址为 0x820000 。如果你关心 MCU 的代码可以将固件分割后进行分段加载,我这里只是简单将整个固件映射到 0x800000 ,因为我只关心 ECU 的代码,所以将该 ROM 的起始地址设置为 0x800000, 而我们的固件大小为 1M ,因此 ROM 大小设置为 0x100000 ,加载地址和大小和 ROM 设置成为一样。 RAM 采用默认的方式不管它。
反汇编后,我们可以看到 MCU 相关的中断跳转表。
OK ,现在我们可以正常的分析该 ECU 固件了。当然如果你想逆向分析该 ECU 固件,你得熟悉 C166 汇编语言,还得要十足的耐性。下表我列举了 C166 汇编指令及其功能 ( 也基本上来自于网络 ) ,如果想要更新详细的信息,那就去看 Infineon 的手册吧。
算数指令
指令 1
指令 2
功能描述
ADD
ADDB
两字或字节加法
ADDC
ADDCB
带进位的两字或字节加法
SUB
SUBB
两字或字节减法
SUBC
SUBCB
带进位的两字或字节减法
MUL
MULU
16 位乘 16 位带符号或无符号乘法
DIV
DIVU
16 位除 16 位带符号或无符号除法
DIVL
DIVLU
32 位除 16 位带符号或无符号除法
CPL
CPLB
一个字或字节的 1 的补数
NEG
NEGB
一个字或字节的 2 的补数
逻辑指令
AND
ANDB
两字或字节位与
OR
ORB
两字或字节位或
XOR
XORB
两字或字节位与或
比较指令
CMP
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
上传的附件: