我們應該知道,面對iOS 上架 遇到4.3a的問題或者制作馬甲包.最基礎的操作就是混淆代碼
尤其是我們專業做上架的,需要對各種語言的編譯模式,產物,以及ipa構成都需要非常了解, 每種語言開發的App的編譯產物不同,針對不同的編譯產物做不同的處理方式
有一些經驗的開發者, 應該知道 目前的混淆方式大概可以分為是三種
1: 源代碼混淆
顧名思義, 就是通過處理源代碼,讓代碼達到翻新的效果, 比如修改一些靜態特征,代碼結構
難度: ?低
優點: 效率高,限制低
缺點:
1: 難以維護最難級別, ?源代碼改動之后,難以辨別, 對維護多個項目造成非常大的工作量
2: 需要針對各種語言分別開發,比如當前開發iOS的app 的語言有iOS , swift, c++, 需要針對各種不同的語言開發不同的混淆工具, 這個工作量太大, 能夠開發iOS的app 的語言高達十幾種, 制作十幾種語言的混淆工具 根本不現實
2: 編譯器混淆
這種混淆方式不需要處理源代碼, 直接通過xcode在編譯時混淆,也就是在xcode將源代碼編譯成.o的時機接入混淆,替換符號
難度: 中
優點: 不需要改動源代碼, 不涉及到維護難度,不區分語言, 可混淆各種語言的代碼
缺點:
1: 處理范圍小, 只能對一些符號進行替換, 比如你想改變一些代碼結構, 這個基本無法實現.
2: 能力有限,比如一些靜態庫在xcode編譯前就已經被編譯好, 所有靜態庫無法替換符號 ,也就是說他只能處理編譯列表的文件
3: 替換符號可能會造成閃退,因為有些訪問是通過kvc來完成的,如果符號被替換了, kvc還是使用原來的字符串去訪問就會造成閃退或者功能異常
3: 直接修改二進制-加固
你是否聽到了熟悉的詞語-"加固", 我們這行把直接修改二進制的方法喜歡叫成" 加固", 直接修改二進制,達到混淆的效果,也就是說我們直接最終編譯的ipa中的可執行文件
舉個例子, 比如我們正在考試.
1: 修改源代碼的方式相當于,你勤勤懇懇的學習,然后提交試卷后,等待老師審查
2: 編譯器的方式相當于, 你在考試的提交試卷的時候替換了別人的考卷,等到老師審查
3: iOS加固的方式相當于, 直接修改考試分數
我們簡單的了解加固的概念后,進入正題:
難度指數:滿級
優點:非常多,不需要關注源代碼,不需要打開xcode, 你只需要給我一個ipa, 我返回給你一個ipa
我們先簡單了解什么是二級制:?
我們通過拆解ipa, 你往往會看到一個黑色的小盒子, 這就是一個可執行文件 ,我們簡稱二進制,當然這個文件不能直接打開或者雙擊執行
這個可執行文件的大小, 往往取決于你的代碼量, 代碼量越大, 這個文件越大,這個里面是什么東西呢??
機器碼
沒錯這個二進制里面全是機器碼,我們使用xxd命令查看最原始的內容
沒錯這個就是二進制的最原始的內容,但是這種機器碼我們根本無法閱讀,?
匯編代碼
這些原始的機器碼(十六進制字節)正是由匯編代碼(Assembly Code)轉換(“匯編”)而來的。這個轉換過程由匯編器(Assembler)?完成。
我們使用otool -tV 命令進行反匯編查看內容
是不是發現了一些帶語義的符號了? ?但是仍然難以閱讀, 我們來翻編譯更高級的語言
高級語言
反編譯的目標是將機器碼/匯編代碼轉換回更抽象、可讀性更高的偽代碼, 還需要一個解析的過程,不同語言所在二進制的位置不同, ?解析方式也不同,這里不過多介紹, 我們直接來看解析后的結果
這個是不是就是你最熟悉的oc代碼了??
它們的層級關系是:
高級語言 (C/C++/Swift) -> 編譯器 -> 匯編代碼 (Assembly) -> 匯編器 -> 機器碼 (Machine Code)
我們繼續關注二進制里面的結構,看看它內部是怎么劃分的, 我們使用size-m 查看二進制的概覽情況
我們發現內容非常多, 非常亂, 不過像我看多了就習慣了, 大致就是分為幾個段, 段里面又被分成了各種小的節
三大段
1:?__LINKEDIT (符號表主要存放位置)
2:?__TEXT (代碼主要存放位置)
3:?__DATA (靜態變量主要存放位置)
我們發現text段中的text節 占據了主要的體積 , 沒錯, 這就是你的源代碼主要存放的位置, 我們加固重點就是處理這個text節?