- iOS應用逆向工程:分析與實戰
- 沙梓社 吳航 劉瑾
- 88字
- 2019-03-01 16:16:05
第1章
iOS逆向工程簡介
雖然從理論上來說iOS App是一個運行于沙箱(sandbox)中的程序,但并不表示我們就對它束手無策,事實上,可以通過逆向工程來一窺其究竟。接下來,就引入iOS軟件逆向工程的概念。
1.1 iOS軟件逆向工程的要求
iOS軟件逆向工程指的是在軟件層面上進行逆向分析的一個過程。讀者如果想要達到對iOS軟件較強的逆向分析能力,最好能非常熟悉iOS設備的硬件構成、iOS系統的運行原理,還要具備豐富的iOS開發經驗。比如:拿到一個App之后能夠清晰地推斷出這個App使用的技術,包括引用了哪些framework、哪些經典的第三方代碼,以及整個App工程大致的文件個數、大致的代碼行數,另外,還要想象一下如果由自己來組織設計開發,需要投入的人員、時間和精力等。
這要求高嗎?其實真的不算高!不過,這些條件都是充分非必要的。如果你目前還不具備這些技術條件,那么有兩個必要條件則一定要滿足:強烈的好奇心和鍥而不舍的精神。因為在iOS軟件逆向工程中,好奇心會驅動你去鉆研經典的App,而在鉆研的過程中會遇到一系列的困難和障礙,各種各樣的技術坑,別人埋的、自己挖的,此時就需要鍥而不舍的精神來支撐你一步步向前走。但是請相信,在投入大量精力去編寫代碼、調試程序、分析邏輯之后,你會在不斷的試驗和錯誤中感受到逆向工程的藝術之美。
1.2 iOS軟件逆向工程的作用
打個比喻,iOS逆向工程就像一桿長矛,專門用于刺破目標程序本以為安全的保護盾,而且還是從想象不到的角度來刺破。
對于微信、陌陌、WhatsApp之類的IM軟件,交流的信息是它們的核心;對于銀行、交易支付、電商類的軟件,交易和客戶信息是它們的核心。所有的核心數據都是需要重點保護的,于是,數據庫加密、網絡連接加密、云存儲等,開發人員通過各種手段重重保護,為的就是讓使用者能夠高枕無憂。
可是iOS逆向工程對這些常規App的攻擊不是來自同一個維度!這些攻擊可用一個詞來定義:維度攻擊(“維度攻擊”的概念來自科幻小說《三體》,在此向《三體》致敬)。
從維度的角度來解釋,我們看待常規App的感覺更像是將App的所有數據、UI、邏輯內容都平展地鋪開在一張二維的大紙上,外圍圈上厚厚的城墻。它的平面圖概念如同圖1-1所示的谷歌地圖一般。

圖1-1 飛到二維城市的上空來俯瞰整座城市
但是當我們跳躍到城墻之外,在三維的天空中俯瞰這個App的二維城堡,這個城堡的內部結構幾乎完全開放在眼前,包括所有的Objective-C函數定義、所有的接口數據、甚至所有的函數內執行代碼。城墻的防護意義已經蕩然無存!此時限制我們的只是這個二維平面城堡到底有多大,里面的內容到底有多豐富,以及排列是整齊有序的還是雜亂無章的。
此時,基于逆向工程的技術能力,可以選擇想進入的任意點“高維進入”,監視甚至改變二維平面上的運行邏輯,從而達到獲取核心信息或軟件設計原理等戰術目的,而不是從二維世界打破外圍城墻強行攻破。
說得似乎很玄乎,但事實上,就筆者對十余款經典App以及iOS系統進行逆向的經歷過程來看,逆向工程的使用確實無一例外地達到了目標。
上面的比喻雖有些不恰當,但也形象地說明了iOS逆向工程的強大能力。現在回到正題,概括起來,iOS逆向工程主要有兩個作用:
?攻破目標程序,拿到關鍵信息,可以歸類于與安全相關的逆向工程;
?借鑒他人的程序功能來開發自己的軟件,可以歸類于與開發相關的逆向工程。
接下來就讓我們將這些內容逐步展開。
1.2.1 與安全相關的iOS逆向工程
從前面的內容介紹已可以大致了解,iOS逆向工程最突出的應用領域就是與安全相關的。比如:工程師通過逆向一個金融類App,來評定這個軟件的安全等級;安全專家通過逆向iOS病毒,來找到殺毒的方法;安全公司通過逆向iOS系統電話、短信功能,來構建一個手機防火墻……
1.評定安全等級
iOS中那些具有交易功能的App一般會先加密敏感數據,然后將加密過的數據存儲在本地或通過互聯網傳輸。而如果安全意識不夠強,就完全有可能將重要的用戶信息(如銀行賬號和密碼)直接用明文保存或傳輸,安全隱患極大。
假如一個有名望的公司考慮推出一款App,為了讓自己App的質量能夠對得起用戶的信任,該公司請一家安全公司幫忙評估這個App的安全性。這家安全公司自然是不會被授權使用這個App源代碼的,也就是說,正向分析其安全性不可行,所以他們只有通過逆向工程,來嘗試“攻擊”這個App,然后依據結果評定其安全等級。
補充說明:前面在介紹“維度攻擊”的概念時已經提及,App雖然可以將低維的攻擊防守得如銅墻鐵壁一般,但是擋不住高維的逆向攻擊。不過不可以據此得出App不安全的結論,因為iOS逆向工程的使用均來自一個前提:iOS越獄。普通用戶可能不知道,在將iOS設備越獄之后,即將整個平臺都置于風險之中,此時也就更談不上App的絕對安全了。在這種環境下,我們使用這些逆向工程技術來分析評估目標App中可被攻擊點有多少,可攻擊點越少的自然就是越安全的。
2.逆向惡意軟件
iOS是智能移動終端操作系統,它同計算機操作系統已沒有本質區別。從第一代開始,它就已具備了上網功能,而互聯網正是惡意軟件傳播的最好媒介。2009年暴露的Ikee病毒是iOS上公開的第一款蠕蟲病毒,它會感染那些已經越獄并且安裝了SSH,但是又沒有更改其默認root密碼"alpine"的iOS設備,并且將它們的鎖屏背景圖改成一個英國歌手的照片。
對于惡意軟件的開發者來說,他們通過逆向工程定位系統和軟件漏洞,利用漏洞滲透進目標主機,獲取敏感數據,甚至為所欲為。
對于殺毒軟件的開發者來說,他們通過逆向工程剖析病毒樣本,觀察病毒行為,嘗試殺掉被感染主機上的病毒,并總結出可以防范病毒的方法。
3.檢查軟件后門
開源軟件的一大好處是其具有較好的安全性。成千上萬的程序員瀏覽并修改開源軟件的代碼,代碼中幾乎不可能存在任何后門,軟件的安全問題往往在大白于天下之前就能及時得到解決。而對于閉源軟件,逆向工程是檢查其軟件后門的方法之一,比如我們常會在越獄的iPhone上安裝360、金山、騰訊等各家手機安全助手,這些服務程序的權限極高,無一例外都擁有超強的能力,可以訪問用戶的通話記錄、短信記錄甚至更多,但我們不知道它們會不會收集不該收集的用戶信息,并把這些信息上傳到自己的服務器。這種“有或沒有”的結論一直是個爭議,我們得不到可信的官方數據,那么就只能通過逆向工程來檢查該軟件是否存在類似的后門。
補充說一句,這些手機安全助手的開發者們本身也是逆向工程的高手,善用矛的同時也善用盾,想要達到同臺PK的水平需要積累鍛煉足夠長的時間才行。
4.去除軟件使用限制
iOS開發者通過App Store或Cydia出售自己的App,作為他們最主要的經濟來源之一。在軟件的世界里,收費與盜版永遠是同時存在的,而不少iOS開發者也在自己的App里加入了反盜版的功能。但這場矛與盾的戰爭永遠不會停止,再好的防御也會有被攻破的一天,防止盜版幾乎是一項不可能完成的任務。比如,Cydia上最知名的“共享”源xsellize能夠在幾乎所有收費軟件發布后的3天內對其完成破解,讓他們的用戶免費享受到收費軟件的功能。
1.2.2 與開發相關的iOS逆向工程
對于iOS開發者來說,逆向工程是最為實用的技術之一。例如,工程師可以逆向系統調用,在自己的程序里使用一些文檔中沒有提及的私有功能,還可以逆向一些經典的軟件,包括競爭對手的軟件,從而研究自己的軟件能夠借鑒些什么技術。
1.逆向系統調用
程序員編寫的軟件能夠運行在操作系統中,提供各種各樣的功能,是因為操作系統本身已經內嵌了這些功能,軟件只是拿來重新組合使用罷了。眾所周知,能在App Store上架的App的功能十分有限,在蘋果公司嚴格的審核制度下,絕大多數App的實現都源于公開的開發文檔,而不能使用諸如鎖屏、關機等文檔中不涉及的功能。如果你的程序面向Cydia,那么不采用非公開功能將導致程序幾乎沒有競爭力。如果你的程序想擁有打電話、發短信等不公開的功能,最有效的途徑就是逆向iOS系統調用,還原系統實現相應功能的代碼,并應用到自己的程序中。
2.借鑒別的軟件
逆向工程最受歡迎的應用場合就是“借鑒”他人的軟件功能。對于來源是App Store的App來說,大多數技術的實現并不復雜,巧妙的創意和良好的運營才是其成功的關鍵。如果只是單純借鑒其功能,那么采用逆向工程,費時費力,性價比不高,從頭開發一個功能類似的軟件反而要省時省力得多。但是,當我們不知道被借鑒軟件中的某個功能是如何實現的時候,逆向工程就能起到關鍵性的作用。這種情況在大量使用私有函數的Cydia軟件中尤其常見,比如2013年3月面世的,號稱iOS平臺上第一款通話錄音軟件的Audio Recorder,足夠有趣,但我們不知其原理如何,此時使用逆向工程的技術就能夠對它了解一二。
有些軟件,比如微信,功能經典,結構也非常復雜,所涉及的代碼自然十分多。圖1-2是使用class-dump獲取微信4.5的.h文件目錄。

圖1-2 通過class-dump獲取的微信4.5的.h文件目錄
可以看到,在目錄中共有2267個.h文件,光是將文件名一個個地看下來,天都要黑了。那這種情況下應該怎么辦?當然不可能這樣傻傻地一個文件一個文件地讀過去,事實上,這時便可以通過合適的逆向分析工具加上豐富的開發經驗來幫助定位關鍵信息點。對于微信這樣足夠經典的目標程序,使用的技術及框架都非常有借鑒意義,所以也值得我們對它進行逆向工程,收集相關的知識并學習,進而一步步地掌握其精髓。
1.3 iOS軟件逆向工程的一般過程
當我們想要逆向一個iOS軟件時,應該從何入手?應該怎么思考?這本書的初衷就是引導初學者走進iOS逆向工程的大門,培養讀者從逆向的角度思考問題。
所謂的iOS逆向工程初學者,其實至少也是iOS App開發的中高級程序員了,理論上都擁有相當豐富的開發經驗。所以在后續的過程中,對于一些非常初級的技術原理,可能會講得非常簡單,甚至直接被忽略,畢竟讀那些內容對有經驗的開發人員來說是在浪費時間。
一般來說,軟件逆向工程可以看做系統分析和代碼分析兩個階段的有機結合。在系統分析階段,要從整體上觀察目標程序的行為特征、文件的組織架構,從而找到我們感興趣的地方。一旦能夠較為熟練地操作這個程序,并且找到了我們想要逆向的點,就可以進入代碼分析階段,利用各種工具對程序本身的二進制文件進行分析,達到我們的目的。
1.3.1 系統分析
在系統分析階段,應在不同的條件下運行目標程序,在程序中進行各種各樣的操作,觀察程序的行為特征,同時尋找我們感興趣的功能點。比如:選擇哪個選項會彈框,按下哪個按鈕會發聲,輸入什么內容屏幕會有什么顯示;同時,還可以瀏覽文件系統,觀察程序顯示的圖片、程序的配置文件存放在哪里,對應的數據庫文件中存放了哪些信息、是否加密等。
以新浪微博App為例,當我們將微博的目錄展開時,會看到如圖1-3所示的結構。在微博目錄下有Documents、Library等子目錄,這些目錄中放著對應的數據庫文件以及緩存的圖片文件等。
另外,在Documents目錄下還可以看到db_36000_3414827754.dat這樣的文件,從文件名上即可識別出它是數據庫文件,此時使用SQLite工具打開便可看到如圖1-4所示的數據內容。

圖1-3 新浪微博App的Documents目錄

圖1-4 新浪微博App的個人數據文件
此時,我們能夠看到在新浪微博里的聯系人、所發的微博內容等信息。
因為這些信息已經通過App自身的目錄文件結構呈現在我們面前,所以可以看到,對iOS平臺以及App的理解程度直接決定了我們在逆向工程時所需要花費的時間和精力,以及所獲取信息的性價比。
1.3.2 代碼分析
在外圍的分析完成之后,接下來就是對程序的可執行文件進行代碼這一層級的分析了。
使用逆向分析的方法可以倒推出這個程序的設計思路、內部算法和實現細節,這是一個非常復雜的過程,甚至可以說是一種解構的藝術。要想讓自己的逆向工程水平達到藝術的高度,需要對軟件開發、CPU工作原理和iOS有透徹的理解。而且很多軟件的復雜度很高,即使其代碼規范、文檔詳盡,可是一旦開源,很多人還是會因其具有的復雜度而驚嘆,比如Activator這樣的系統級插件程序。一點一點地分析程序的底層指令絕非易事,也不是一本書能夠完全闡述清楚的。
本書的目標僅僅是向初學者講述iOS逆向工程入門時所用到的工具和可能的思路,書中所提及的工具及知識均是筆者長期積累的個人經驗之談,對知識點的覆蓋不可能面面俱到,期望讀者能結合書中的理論和實例舉一反三,形成自己的學習方法。
1.4 iOS軟件逆向工程用到的工具
對于iOS的逆向工程,除了掌握理論知識之外,最重點的內容就是使用好各種工具了。整個iOS逆向工程所涉及的工具數量達到數十款之多,而且這還未100%覆蓋到。因為畢竟在這一方向沒有一套統一的教學規范來指明哪些工具該用,哪些工具不該用,各個參與者都是根據自己掌握的深度及喜好來選擇最稱手的工具的。
好的工具,以及對這些工具的熟練使用能夠極大地協助我們進行高效的逆向工程。在本階段的逆向工程中,介紹的工具集主要可以分為四大類:監測工具、開發工具、反匯編器(disassembler)、調試器(debugger)。
1.4.1 監測工具
在逆向工程中,起到嗅探、監測、記錄目標程序行為的工具統稱為監測工具。這些工具通常可以記錄并顯示目標程序的某些操作,如網絡活動、文件訪問等。iOS逆向常用的監測工具有Reveal、tcpdump、libNotifyWatch和PonyDebugger等。
圖1-5中所呈現的是一款監測工具——Reveal,它可用來查看目標App的UI元素。

圖1-5 Reveal——用來查看目標App的UI元素的監測工具
使用Reveal可以非常直觀地看見App的界面上各個UI元素之間的從屬關系,并且輕松、快捷地定位到我們想查看的UI元素。有了類似這樣的工具,很多我們原本以為會非常枯燥的分析工作均可以輕松搞定,達到事半功倍的效果。
1.4.2 開發工具
進入代碼分析這一層級,就必須掌握開發工具的使用了。實際上監測工具與開發工具一直都是組合使用的,單純使用某一類工具根本無法深入。
對于有成熟開發經驗的iOS程序員來說,Xcode是最常用的開發工具,但在此之外,還有可以用于開發越獄代碼的工具,其中最方便也最有名的一個工具就是Theos。這是一個非常簡單易用的開發工具,但是它能編譯生成最具威力的tweak插件,直刺App心臟,完成我們期望它完成的任務。
圖1-6是Theos的創建工程命令行。

圖1-6 Theos——tweak開發工具
在后面的工具篇中會詳細介紹Theos的使用方法。僅從個人體驗來說,這是讓筆者最為興奮的開發工具,在接觸、使用Theos之前,筆者感覺自己一直都被限制在普通App的低維世界中,直到學會并掌握了Theos的使用方法,才覺得真正突破了普通App的開發界限,跨越了維度的限制,可以從高維來看待App了。
1.4.3 反編譯器
隨著自己能力的一步步進階,反編譯器就會出現在我們的視野中。在iOS逆向工程領域,反編譯器主要就是IDA。
IDA是逆向工程中最常用的工具之一,橫跨Windows/Linux/Mac平臺,它會把目標程序的可執行文件作為輸入,然后輸出這個程序的匯編代碼,甚至偽代碼。
反編譯是跟CPU架構相關的,但像IDA這樣強大的反編譯器支持多種CPU架構,如圖1-7所示。
IDA有免費版本,可以輸出函數列表及對應的匯編代碼。而相較于免費版的IDA,收費版本所能帶來的功能就更為震撼了。圖1-8是IDA Pro(收費版)的截圖,對于iOS App,它能做到的不僅僅是反匯編,甚至連偽代碼都能高度接近。

圖1-7 IDA——強大的反編譯器

圖1-8 IDA反編譯App的偽代碼
筆者第一次看到這樣的偽代碼時,不禁感嘆:逆向分析工具都強大到了這一步,還有什么是能藏得住的?
1.4.4 調試器
對程序員來說,調試器是相當熟悉的了,最常見、最熟悉的就是在Xcode中的單步調試,程序員可以在某一行代碼上設置斷點,使調試器能夠在那一行代碼執行之前暫停程序執行,并且顯示程序當前的狀態。
因為程序員擁有自己程序的源代碼,所以調試器的斷點可以指定在源代碼的代碼行上,單步調試可以以源代碼的行為單位執行代碼。而熟悉Xcode調試的人也都知道,其實所謂Xcode的調試器,不過就是把GDB(GNU Debugger)或LLDB做了一層圖形化的包裝,集成在一起更好用而已。
但是在逆向工程中,我們往往沒有目標程序的源代碼,而且需要在iOS設備上進行調試,此時就需要在iOS設備上運行基于命令行的GDB了。圖1-9是使用GDB進行調試的示例。

圖1-9 GDB——調試利器
當然,我們同樣可以利用調試器設置斷點、單步調試,來觀察甚至更改程序的執行流程,從而達到分析程序的目的,只不過這個過程不如擁有代碼調試那么直觀、方便。
1.5 小結
本章介紹了iOS軟件逆向工程的基本概念、作用和一般的逆向過程,以及需要用到的一些有代表意義的工具等,旨在讓讀者對iOS逆向工程有一個概念上的了解,詳細的技術內容會在后面的章節中逐一講解。