「隨着物聯網時代的開啓,須要解決的安全問題會越來越多,而代碼安全是其餘安全方案的底層支撐。面對芯片架構繁多,運行環境複雜的嵌入式物聯網設備,傳統的代碼安全方案都將會失效,LLVM編譯器爲咱們帶來了終極代碼安全解決方案。」前端
日前,幾維安全CTO劉柏江在2018 ISC互聯網安全大會「網絡安全技術創新及應用論壇」上發表了題爲《IoT時代LLVM編譯器防禦的藝術》的主題演講。算法
劉柏江,幾維安全CTO,聯合創始人,KiwiVM的締造者編程
移動互聯網、萬物互聯網,歸根結底都是硬件組成,軟件驅動。軟件代碼承載着咱們生活的方方面面,利用App打車、購物、支付、聊天等無一不是經過代碼來實現具體的服務功能。然而因爲黑灰產的存在,裸奔的代碼將會給咱們的生活帶來各類糟糕的體驗和危險。尤爲是隨着物聯網時代的開啓,須要解決的安全問題會越來越多,而代碼安全是其餘安全方案的底層支撐。面對芯片架構繁多,運行環境複雜的嵌入式物聯網設備,傳統的代碼安全方案都將會失效,LLVM編譯器爲咱們帶來了終極代碼安全解決方案。架構無關、函數粒度、強度可調,堪稱代碼安全防禦的藝術,也是今天要分享的實操性很是強的技術。後端
萬物互聯,代碼安全先行安全
安全圈的同仁們最近幾年都提到一個觀點:萬物互聯,安全先行。但這裏的安全是一個寬泛的概念,它多是指設備的物理安全,防止丟失或者被盜;也可能指芯片以及操做系統安全,防止底層漏洞被惡意利用;還可能指物聯網設備承載的業務安全,防止用戶隱私數據泄漏。網絡
這些安全我稱之爲策略安全,它們是經過設計完備的規則以及良好的代碼實現來達到保護的目的。可是這類安全問題咱們絕大多數人是遇不到的,它們屬於Intel、ARM、Apple、Google這類芯片和操做系統巨頭公司的考慮範疇。架構
軟件代碼是科技公司最寶貴的財富之一,代碼安全是咱們每位IT從業者均可能會遇到的問題,也是頗有必要去解決的問題。代碼加密能帶來以下好處:第一,防止核心算法被重構,保護軟件資產;第二,提高策略安全的強度;第三,加大破解難度,延長破解時間,爲運營爭取更多的有利窗口期;第四,提升破解成本,將逆向菜鳥拒之門外。模塊化
物聯網時代已經來臨函數
從2007年iPhone的誕生到如今,移動互聯網已趨於成熟,萬物互聯網也已打響軍備競賽,好比Google的Android Things、阿里的AliOS Things,他們都在爲新一輪的物聯網平臺佈局。能夠預見,將來咱們身邊將有數不清的與生活息息相關的智能終端設備。做爲對策略安全的一個強力補充,代碼安全也將會繼續爲整個生態安全貢獻力量。工具
芯片體系多
在PC時代,三大主流的桌面操做系統均跑在x86體系下面。而到了移動互聯網時代,咱們主要面對的芯片體系是arm,可是arm有thumb、arm、arm64三種不一樣的指令集,這已經開始有點讓我們這些作安全和逆向的人感到心力交瘁了。然而到了物聯網時代,鑑於成本、使用場景、性能要求等因素,物聯網設備所使用的微處理器芯片體系可能會多到讓人難以置信,足以讓安全開發者們癲狂。
運行內存小
不像PC或者手機動不動就是幾個G的內存容量,物聯網設備的運行內存容量相較PC或手機要小得多的,它們的內存可能只有少得可憐的幾十幾百K。
運行環境複雜
物聯網操做系統運行的環境有以下特色:第一,跑在種類繁多的芯片架構上;第二,運行在內存通常偏小的環境;第三,受限於功耗硬件性能低下。這些特性給咱們作代碼安全提出了不小的挑戰。在引入咱們新型的代碼加密方案以前,咱們先看看歷史方案的作法以及缺陷。
傳統黑盒代碼加密及侷限
首先,咱們科普兩個簡單的概念。黑盒代碼加密處理的對象是最終的軟件執行體,它們都是以二進制的方式存在,好比Windows的exe、Android的so以及dex;白盒代碼加密處理的對象是源代碼,它們都是以文本的方式存在,須要用對應的編譯器才能轉換成二進制,好比C/C++/Objective-C/Swift源文件。
黑盒代碼加密的應用
黑盒代碼加密的典型應用有四種場景。第一種是加殼,通常是對執行體壓縮或加密,而後運行的時候動態解密,好比適用於Windows、Linux、Android的UPX殼。第二種是加花指令,好比x86架構下面利用指令的可變長特性增長誤導反彙編程序的垃圾指令。第三種是加虛擬機,這種是直接把對應的指令集轉換成自定義的指令集,好比Windows平臺很是著名的VMProtect,它就是把x86指令集轉碼爲私有的指令集格式。第四種是劫持運行時,好比Android平臺的Dex加固就屬於這一類。
黑盒代碼加密的侷限
從黑盒代碼加密的實現原理來看,它們針對的操做系統以及芯片架構都是特定於一個很小的集合,這樣帶來一些很明顯的限制和缺陷,一個是可移植性差,另外一個是兼容性差。可移植性差主要體如今如下兩點:一是很難對多端且同源的代碼作一致性的保護;二是芯片架構不兼容、內存需求顯著增長,很難適應新的像IoT這樣的平臺。兼容性差主要體如今黑盒方案每每須要干預正常的App運行時(專業的叫法稱之爲Hook技術)。可是對於像Android這類高碎片化的平臺,干預運行時意味着很難把方案作到完備;而對於像iOS這類徹底封閉的平臺,干預運行時意味着方案無法工做,由於蘋果基於安全的考慮不容許不少底層的操做好比動態分配代碼內存。
新型代碼加密方案 - LLVM編譯器
下面咱們看看怎樣利用LLVM來從新定義代碼安全的實現思路。LLVM是模塊化、可複用的編譯器工具鏈集合,它提供了很是完整的API操做接口,能夠自定義整個編譯過程。它的編譯流程能夠抽象爲源文件經過編譯器前端生成架構無關的IR(IR是中間表示的英文縮寫), 而後被編譯器後端生成架構相關的目標文件。從這個抽象的編譯流程咱們能夠看到,架構無關的IR給了咱們設計代碼安全方案的機會。
LLVM-IR的抽象結構
IR的抽象結構以下圖所示,去除一些數據和描述信息,IR由函數構成,函數由基本塊構成,基本塊由IR指令構成。LLVM提供了完整的IR指令操做API,讓咱們能夠對IR模塊作修改,這是咱們基於LLVM編譯器作代碼安全的基礎和核心,也是咱們能克服黑盒方案缺陷的關鍵。
LLVM-IR的潛能
基於LLVM-IR作代碼安全能帶來的好處衆多且方案的設計思路靈活,它能完美的處理移動互聯網和物聯網操做系統環境下的代碼安全問題。第一,在架構無關的IR級別作防禦,能夠適應任意芯片架構;第二,能作到以函數爲單位進行防禦,能夠適應低內存運行環境;第三,能夠根據不一樣的需求,定製化實現不一樣級別的安全防禦。
基於LLVM編譯器的代碼安全方案
初級防禦 - 混淆編譯器
Obfuscator-LLVM,這是2013年開源的一個混淆編譯器,也是咱們國產安全編譯器的鼻祖。不少友商的安全編譯器都是從這個項目衍生而來。它能實現代碼膨脹、塊亂序等功能。
這是兩張彙編代碼反編譯流程圖 ,圖中的白色部分表明着一個最小單位的指令塊。左邊是正常的流程圖,右邊是混淆以後的流程圖。從流程圖中咱們能夠看到,混淆以後把代碼量增大了,執行邏輯也作了轉換。從逆向分析的角度看,代碼量的增長在必定程度提升了逆向的難度。但因爲這個方案比較初級,所以強度不是很高,如今也已經有了針對混淆的自動化反混淆腳本。
高級防禦 - 塊調度編譯器
Obfuscator-LLVM給了咱們一個好的開頭,同時也是一個重要的啓示。基於LLVM,咱們還能作得更多。從逆向分析的角度看,只要函數邏輯是連貫的,那麼咱們老是能夠作分析,無論你如何膨脹,代碼就在那裏。因此,切斷函數邏輯,是一個代碼防禦的方向。基於該方向的思考,咱們作出了塊調度編譯器,它完美的掐斷了原始函數的邏輯,讓逆向的人無法分析。
塊調度編譯器的實現原理是這樣的,好比一個函數裏面有三個基本的代碼塊A、B、C,A執行完成以後會根據不一樣的條件跳轉到B或者C。正常的執行流程咱們經過專業的反編譯程序能夠一眼就能看出這三者的邏輯關係,進而分析它的實現原理將變得易如反掌。而塊調度呢,會把A跳轉到B或者C這個跳轉過程加密,這樣出來的效果呢就像右邊的圖同樣,各個基本的關鍵代碼塊成爲了彼此獨立的實體,靜態反編譯工具將無法作代碼的連續性分析,這將使得逆向分析沒法進行。另外,塊調度還會把函數調用加密,那麼咱們經常使用的經過函數調用了哪些函數來猜想函數邏輯將變得不可能。所以,塊調度的強度遠遠高於普通的混淆,若是將混淆和塊調度疊加使用,那麼效果將會出奇的好,讓逆向分析的人無比痛苦。
旗艦防禦 - KiwiVM代碼虛擬化
一直以來,在外掛、反外掛最激烈的Windows網絡遊戲攻防戰場,虛擬機防禦每每是最後一道防線,也是強度最高的一道防線。高水平的逆向分析者每每須要花費數月甚至數年才能大體搞明白被虛擬機保護的代碼,而通常的逆向分析者幾乎無法展開虛擬機的分析。所以,虛擬機是代碼安全的最高堡壘。
做爲國內專業的白盒代碼安全方案提供商,幾維安全於2016年就基於LLVM研發出了全平臺全架構支持的代碼虛擬化產品KiwiVM。它小巧精緻,不只適用於移動互聯網,同時也天生適應物聯網,這是基於LLVM的頂級藝術品。
因爲LLVM-IR的平臺無關性,所以KiwiVM也能平臺無關的實現函數級的虛擬化,能夠在性能和安全兩方面取得良好的平衡。KiwiVM代碼虛擬化屬於靜態代碼加密技術,一旦成功虛擬化,配合虛擬CPU的運行時便可完整的實現原始代碼的功能,不存在干預運行時的Hook操做,所以兼容性能夠達到100%。
KiwiVM的中心思想是利用LLVM-IR編碼成自定義虛擬CPU的指令集和元數據,包括指令集數據、重定位數據、函數調用簽名數據等。轉換過程是源碼轉源碼,好比C/C++/ObjC源代碼經過LLVM前端編譯爲BC文件(IR模塊的載體),而後KiwiVM核心算法把該BC文件作自定義的編碼生成功能等價的標準C源代碼文件,最後再編譯爲目標平臺須要的二進制文件。前面咱們提到物聯網設備的芯片可能會是很是冷門的,甚至其編譯工具鏈都是徹底私有定製的,和常規的GCC交叉工具鏈都不同。面對這種冷門環境,因爲KiwiVM擁有源代碼轉源代碼的能力,因此能夠完美的兼容它的代碼安全需求。
原始函數被虛擬化以後代碼邏輯徹底變爲單一的虛擬機入口,無論多麼複雜的函數成功虛擬化以後,最終出來都是這樣一個無比「單純」的白板。
結語
至此,咱們分享了基於LLVM編譯器作的不一樣防禦級別的三種代碼安全方案。從下圖咱們能夠清楚的看出混淆、塊調度、代碼虛擬化三者之間的區別。
幾維安全已經在LLVM編譯器代碼安全方面有了完整的產品佈局,全部的安全編譯器產品都支持iOS、Android、IoT三大平臺。
其中初級防禦產品混淆編譯器能實現代碼膨脹、亂序執行、字符串加密等功能。高級防禦產品塊調度編譯器能實現邏輯斷鏈、函數調用隱藏、字符串加密等功能,而且能夠和混淆編譯器疊加使用,強度更高。幾維安全旗艦防禦產品代碼虛擬化編譯器能實現虛擬CPU執行,徹底隱藏函數邏輯,讓逆向工程完全沒法進行。