[原創]汽車動力系統ECU韌體逆向工程初探

gjden發表於2016-11-21

汽車動力系統ECU韌體逆向工程初探

 

作者:gjden

時間:20161119

                                             

[原創]汽車動力系統ECU韌體逆向工程初探

偶爾看到國外一些論壇討論汽車改裝(都是基於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

下面我截了幾張發動機ECUPCB圖,可以看出ECUPCB似乎和普通電子裝置的PCB差不多。

[原創]汽車動力系統ECU韌體逆向工程初探

至於ECU控制發動機的原理,幾乎所有將汽車的教材中都有,我就不多說了,否則得引出一堆東西,那就是給自己挖了一個大坑,所以還是那一句話:網上資料多,還得靠自摸^^!下圖是我從PPT上截來的,應該是最直觀易懂的圖。

[原創]汽車動力系統ECU韌體逆向工程初探

 

二、ECU韌體獲取

         先做一點科普,對於大部分汽車玩得比較深的人,對汽車改裝都不會陌生,現代意義的汽車改裝實際上是對發動機ECU韌體提取、調校、回寫等。一般通過ECU調校可以讓發動機輸出更高的動力。ECU調校通常比較複雜,比如需要對點火時間、噴油量、噴油時間、燃油壓力、增壓壓力等等引數的調整並且還需要結合負荷、檔位、轉速、溫度等做出最優的調整方案,另外還得考慮安全性等等問題。因而需要對汽車系統非常熟悉並且具有豐富的調校經驗的工程師才能夠完成,所以ECU調校的費用也會很高。

ECU韌體的讀取和普通裝置的韌體讀取類似,但是也有差別。相似之處就是都需要硬體裝置支援,不同在於介面方式的不同(實際上是廢話^^)。當然有的ECU需要將ECU拆解下來進行韌體讀取,而有的可以直接通過OBD口進行韌體讀取,通過OBD讀取更加簡單,至少不用拆機和焊線。以下是我列舉的一些可以進行ECU讀寫的工具,當然並不全,有需要的可以自行搜尋購買。

工具名稱

簡介

CMD Flash

支援OBD2BDM BOOT模式對ECU進行讀寫

AZN Tuning

AZN改裝店專用,似乎不向外出售

Galletto   1260

實際就是一根診斷線(內含OBD USB晶片)

OpenPort

支援OBD2進行資料讀寫

MPPS V13.02

Galletto   1260類似

 

當然如果你的汽車支援OBD2進行韌體讀寫並且你已經熟悉讀寫ECU韌體的診斷命令,那麼你也可以連線OBD2介面並且向其傳送診斷命令來操作,只是相對來說麻煩一些。

下圖展示的以上列舉的刷ECU韌體的硬體工具的截圖:

[原創]汽車動力系統ECU韌體逆向工程初探

Galletto 1260

[原創]汽車動力系統ECU韌體逆向工程初探

OpenPort

[原創]汽車動力系統ECU韌體逆向工程初探

CMD Flash工具

 

[原創]汽車動力系統ECU韌體逆向工程初探

AZN Tuning

 

[原創]汽車動力系統ECU韌體逆向工程初探

MPPS v12

 

如果拆機的話,會涉及接線問題,你可以通過chip datasheet來搜尋與你車型ECU相匹配的晶片手冊。下面這張圖是奧迪ECU的介面圖,你可以根據自己ECU的型別找到其針腳定義。

[原創]汽車動力系統ECU韌體逆向工程初探

目前,大部分的汽車都支援OBDII來進行ECU的操作,因此來一張OBDII關鍵介面的圖:

[原創]汽車動力系統ECU韌體逆向工程初探

如果你購買有硬體FLASH工具,那麼產品相關的說明文件應該可以解決大部分問題,網上也有相當多的資料,實際上ECU韌體的讀寫比一般的裝置的韌體讀寫簡單很多,因而在這裡也不細說了。

 

三、ECU韌體分析初探

在汽車界玩得最深的估計就是做ECU調校了,但是ECU調校只是對ECU MAP表(ECU韌體中的資料表,後面會有更詳細的說明)進行微調並且讀修改的資料做校驗。但如果對ECU韌體程式碼進行逆向工程,我們不僅可以對修改MAP表,還可以破解其校驗功能(很多買得很貴的MAP校驗工具就是靠逆向校驗函式而編寫的,這實際上並不難,因為MAP的校驗演算法本身就不是很複雜),並且修改韌體程式碼流程,甚至可以給其新增功能或者是加一些惡意程式碼進去,就像我們玩兒PE檔案一樣,在保證其能夠正常和安全執行的前提下,你可以自由的改造。

1. 韌體資訊提取

首先通過二進位制資料中的字串來看看該ECU韌體的有哪些資訊。

[原創]汽車動力系統ECU韌體逆向工程初探

上圖中我標記的第二行資訊是該ECU的電子發行包,我們可以看出該ECU是採用的博世的ECU ME7.1。此後,我又發現了與發動機相關的資訊,如圖:

[原創]汽車動力系統ECU韌體逆向工程初探

其中 06A906032JB為發動機零件號,通過零件號可以得知該車型的發動機為寶來發動機,但是ECU採用的是博世ECU,發動機排量為1600ml,變速器為AG4自動4檔位等等。最後,我通過ME7Info提取出了更多的資訊。比如可能的通訊協議硬體號、軟體號、軟體版本、引擎ID等等資訊。

[原創]汽車動力系統ECU韌體逆向工程初探

[原創]汽車動力系統ECU韌體逆向工程初探

 

2.指令集識別

如果要對韌體進行逆向工程的話,必須知道該韌體的MCU型別,以便知道該ECU採用指令集型別。因此,我首先想到了binwalk,因而我嘗試了一下,binwalk識別指令花了很長時間:

[原創]汽車動力系統ECU韌體逆向工程初探

Binwalk識別出來竟然是ARM,著實讓人興奮了一把,因為個人對ARM指令還是比較熟悉的,更何況IDA還可以F5。但是看到後面的說明感覺就有點不對,怎麼可能只有540條有效指令。隨後,我用IDA來驗證了一下,反彙編指令選擇ARM big endian。並且從0x12943的位置開始進行反彙編,如圖:

[原創]汽車動力系統ECU韌體逆向工程初探

可以明顯的看出,這是不正常的程式碼,並且根據經驗,韌體開始部分應該會有一大堆中斷跳轉,但通過ARM Big Endian 得到的程式碼卻是如下這樣:

[原創]汽車動力系統ECU韌體逆向工程初探

另外我也嘗試了使用little endian方式來反彙編,同樣是不正確的。

此時,第一步提取的韌體資訊就很有用了,至少為我們提供了搜尋的線索,結合韌體涉及的電子屬性和發動機相關資訊,我發現該ECU屬於英飛凌的(Infineon,前身為西門子集團的半導體部門),而該ECU採用的是C16X系列的核心,也就是說該ECU封裝的實際上C16XMCU,這款MCU原先屬於西門子,因此指令集極有可能也是西門子的。強大的IDA果然沒有讓我失望,其完全支援C16X家族系列。在IDA中我選擇Siemens C166進行反彙編,確認後需要填寫RAMROM地址RAMROM地址目前還不清楚,因而先空著直接反彙編。

[原創]汽車動力系統ECU韌體逆向工程初探

從圖中我們可以看出部分跳轉指令是正常的,但是有的又不正常(紅色陰影的地址)。不正常的地址有一個共同點就是都是基於0x820000的地址。因而,部分於MCU相關的中斷服務以及硬體管理程式碼可能的基地址為0x000000,這就是這部分程式碼可能對映在0x0000000處,而部分與ECU相關的中斷服務和硬體管理程式碼可能的基地址為0x820000。如果你關心MCU的程式碼可以將韌體分割後進行分段載入,我這裡只是簡單將整個韌體對映到0x800000,因為我只關心ECU的程式碼,所以將該ROM的起始地址設定為0x800000,而我們的韌體大小為1M,因此ROM大小設定為0x100000,載入地址和大小和ROM設定成為一樣。RAM採用預設的方式不管它。

[原創]汽車動力系統ECU韌體逆向工程初探

 

反彙編後,我們可以看到MCU相關的中斷跳轉表。

[原創]汽車動力系統ECU韌體逆向工程初探

 

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

CMPB

兩字或位元組比較

CMPI1

CMPI2

帶增長12的兩字比較

CMPD1

CMPD2

帶增長12的兩字比較

布林位操作指令

BFLDH/BFLDL

字的高位位元組或低位位元組的可遮蔽位的操作

BSET

對某位置1

BCLR

對某位清零

BMOV

移動某一位

BMOVN

反相移動某位

BAND

兩位相與

BOR

兩位相或

BXOR

兩位相與或

BCMP

兩位比較

移位和迴圈移位指令

SHR

字右移

SHL

字左移

ROR

字迴圈右移

ROL

字迴圈左移

ASHR

帶符號位右移

系統控制指令

SRST

通過軟體復位

IDLE

進入休閒狀態

PWRDN

進入掉電狀態

SRVWDT

服務看門狗定時器

DISWDT

關閉看門狗定時器

 

控制流程指令

JMPA/JMPI/JMPR

當前程式段有條件跳轉到絕對、間接或相對目標地址

JMPS

在任何程式段無條件跳轉到絕對目標地址

JB/JNB

根據選擇位的狀態,在當前程短有條件跳轉到相對目標地址

JBC/JNBS

根據選擇位的狀態,用取反測試位,在當前程式段有條件跳轉到相對目標地址

CALLA/CALLI

在當前程式段中有條件呼叫絕對或間接地址的子程式

CALLR

在當前程式段中無條件呼叫相對地址的子程式

CALLS

在當前程式中無條件呼叫絕對地址的子程式

PCALL

在當前程式段中將選擇暫存器壓入堆疊無條件呼叫絕對地址的子程式

TRAP

在程式段中無條件跳轉到中斷或陷阱向量跳轉表

RET

在當前程式段從子程式返回

RETS

在任何程式段從子程式返回

RETP

在當前程式段從子程式返回,外加從系統堆疊中彈出一個選擇暫存器

RETI

從中斷服務程式中返回

JMPA/JMPI/JMPR

當前程式段有條件跳轉到絕對、間接或相對目標地址

JMPS

在任何程式段無條件跳轉到絕對目標地址

C166

組合語言程式設計.txt

JB/JNB

根據選擇位的狀態,在當前程短有條件跳轉到相對目標地址

JBC/JNBS

根據選擇位的狀態,用取反測試位,在當前程式段有條件跳轉到相對目標地址

CALLA/CALLI

在當前程式段中有條件呼叫絕對或間接地址的子程式

CALLR

在當前程式段中無條件呼叫相對地址的子程式

CALLS

在當前程式中無條件呼叫絕對地址的子程式

 

這裡不一一列舉了,其他指令請查詢C166手冊,此外本文不打算介紹C166的那些暫存器以及ECU自身暫存器(這些暫存器是處在MCU外部,和MCU一起被封裝在ECU中,通常都是對映在RAM中,暫存器太多了,就不做介紹了)。

 

3. 彙編程式碼的二次處理

         通過IDA反彙編得到畢竟只是原始的彙編程式碼,程式碼量巨大並且難以識別,分析起來也會非常吃力。如果有現成的外掛或者指令碼自動識別一些函式或者資料,那麼可以大大減少我們逆向工程的工作量。幸運的是目前還真有這樣的外掛—Bosch Me7x外掛,該外掛針對ME7.17.5來進行函式和MAP表的識別以及做出相應的註釋。這是一款比較老的外掛,對於部分的函式和MAP表的識別有些錯誤。但是有總比沒有好,通過該外掛我們成功找到了一些關鍵函式和MAP表。

如下圖是識別出來的作業系統自身的函式,主要是一些基本操作函式,當然這些函式我們可以不用關心。

[原創]汽車動力系統ECU韌體逆向工程初探

以下是一些識別出來的lookup(這些表構成了MAP)和以及部分操作MAP的函式。此外很多MAP查詢函式都沒有做明確的註釋,只是被命名為LookupA-Z,因而具體的那個函式操作那個MAP需要花費大量的時間來分析。

[原創]汽車動力系統ECU韌體逆向工程初探

查表函式對引數都做了註釋,很人性化

[原創]汽車動力系統ECU韌體逆向工程初探

 

另外,外掛採用的是固定的函式特徵和MAP表特徵, 因而很多MAP表也都沒有識別出來。所以我們還需要結合其他工具來分析。

         在程式碼級別的逆向工程對韌體的操作級別更高,你可以繞過某些邏輯和校驗,甚至可以給ECU新增功能,或者新增一個後門(在某個感測器的值達到一個異常值時觸發後門,對於目前很多將發動機ECU接入CAN網路後,你會有更多的攻擊入口,此處不多說,自己體會吧),而不僅僅限制於修改MAP(大部分都是做ECU改裝)。

 

4. MAP表的進一步分析

MAP表,又稱脈譜表,設計者將提前將計算好的資料採用二維、三維或多維的資料結構方式儲存到ROM裡面去。典型的三維MAP就是噴油MAP,一般橫座標是轉速,縱座標是節氣門開度,縱橫座標交叉點就是噴油量資料。採用這種三維資料結構,能夠精確的表示出每一個不同轉速和不同節氣門開度情況下的噴油量。 ECU通過讀取感測器的工作引數得知引擎各機構當前狀態(如空氣流量、曲軸位置等)並且將讀取的資料作為MAP表的座標引數查出需要控制引擎的資訊等(如噴油時機、噴油量)。

通過更加細緻的分析,我找到了一些MAP表,比如油量表、直接轉矩控制表(DTC)DTS表、油量表、RPM表、進氣溫度表等,以及操作表的函式,比如有做MAP校驗的函式,查表的函式等等。但這是遠遠不夠的,現在汽車的MAP表通常都有幾十上百個MAP表。

因此,為了識別出更多MAP表,我需要一個更加專業的工具,那就是鼎鼎大名的winols,該款工具可以很好的識別出ECU韌體中MAP並且能夠實現這些資料的2D3D展示,最強大的是可以實現MAP資料的編輯和校驗,即便是加密處理過的資料也可以自行解密。

如圖,可以看出winols可以識別出71MAP表,每個MAP表都是以Map “Bosch II”類似的預設名稱命名,這些需要自行進行識別以後進行更改,不同的ECU有不同的MAP表,也沒有固定特徵,需要一些經驗來進行識別。

[原創]汽車動力系統ECU韌體逆向工程初探

針對於每一個MAP表都可以以純資料、2D3D方式來進行顯示。

[原創]汽車動力系統ECU韌體逆向工程初探

3D形式顯示有助於工程師根據3D形狀來判定該MAP的型別,也可以非常直觀的看到MAP修改之後的改變。當然winols還支援修改完自動完成校驗的功能。如果連線上汽車,它還可以實時進行修並且實時校驗,大大方便了ECU的除錯。

[原創]汽車動力系統ECU韌體逆向工程初探

[原創]汽車動力系統ECU韌體逆向工程初探

此外還有很多其他做MAP資料修改的工具比如3D MAP之類的,也都是非常好的工具,此處也不做介紹了。

 

四、總結

         本文僅僅對ECU韌體分析做了一個初步探索和簡單的分析,後續還有很多工作要做,比如ECU MAP資料校驗繞過,新增和修改ECU功能和某些邏輯,二進位制程式碼級別的ECU CAN協議解析逆向,感測器資料解析邏輯以及指令傳送邏輯等等。

 

[原創]汽車動力系統ECU韌體逆向工程初探
上傳的附件:

相關文章