iOS開發(fā)系列--代碼混淆

由于iOS系統(tǒng)的封閉性,相對于安卓來說,iOS開發(fā)過程中代碼混淆可能就顯得并不是得非有不可了。但是在安全性(可通過class-dump反編譯暴露出類的方法名)和特殊需求上(例如馬甲包的混淆過審)還是有一定需求的!
此腳本借鑒于kaich/codeobscure。在使用原作者腳本的過程中,發(fā)現(xiàn)了一些BUG和不足,比如正則表達(dá)式的判斷不準(zhǔn)確,生成過多無用的替換宏,需要花費(fèi)過多時(shí)間去人工排錯(cuò)...
由于本人對python并不是很熟,所以只是在原作者的基礎(chǔ)上作了一些完善修改。

優(yōu)化內(nèi)容:

  • 修改正則表達(dá)式,更精準(zhǔn)地找出關(guān)鍵詞。
  • 替換規(guī)則更改:隨機(jī)字符串==>隨機(jī)生成2個(gè)單詞拼接。防止蘋果審核過程被誤認(rèn)加入混淆亂碼。
  • 增加-k選項(xiàng),通過ignoreKey.txt文件添加需要過濾的關(guān)鍵詞,可避免每次生成都要手動(dòng)刪除部分關(guān)鍵詞的麻煩。
  • 增加property關(guān)鍵詞、懶加載方法名過濾,減少無用宏的生成。
  • 增加IBAction方法關(guān)鍵詞的二次過濾(原腳本存在自定義方法跟IBAction方法重名,無法排除的情況)。

以下內(nèi)容大部分來源于kaich/codeobscure

實(shí)現(xiàn)原理

其實(shí)插件的實(shí)現(xiàn)方式十分簡單,提取用戶編寫的文件中的方法名,使用宏定義將其更換為任意的無規(guī)則字符串。但這種方式有一些需要注意的點(diǎn):

  1. 對于系統(tǒng)庫產(chǎn)生的方法名,不可替換;對于系統(tǒng)使用到的關(guān)鍵字,也不可以替換;否則會(huì)報(bào)錯(cuò);
  2. Swift混編的項(xiàng)目,Swift中的代碼不可替換;同時(shí)Swift調(diào)用Objective-C的特定方法名也不可以輕易替換;
  3. 第三方庫暴露的頭文件的方法名,不可替換;

根據(jù)上面的規(guī)則(可能有遺漏),該腳本采用了相對簡單的方法來避免:

  1. 只掃描.h和.m文件,只掃描方法名。(對于屬性名,嘗試過掃描,但由于屬性的訪問方式多樣,并不建議做混淆,會(huì)產(chǎn)生額外的工作量);
  2. 對于系統(tǒng)庫,讓用戶手動(dòng)指定,這個(gè)是可以提取的,直接拿到系統(tǒng)庫的頭文件即可,腳本會(huì)自動(dòng)掃描到所有的系統(tǒng)關(guān)鍵字,直接做排除處理。(以iOS11的SDK為例,系統(tǒng)關(guān)鍵字約6萬個(gè));
  3. 對于Swift代碼,可以直接排除在掃描目錄外;
  4. 對于第三方庫,用戶可以手動(dòng)指定目錄,腳本會(huì)自動(dòng)掃描提取關(guān)鍵字,在混淆時(shí)避免這些關(guān)鍵字。

依據(jù)上述原理,基本可以避免多數(shù)情況下產(chǎn)生的混淆錯(cuò)誤;當(dāng)然,由于各種項(xiàng)目的復(fù)雜性,有一些復(fù)雜的混淆錯(cuò)誤無法避免,需要后續(xù)手動(dòng)調(diào)整代碼。

使用方式

  1. clone本倉庫;
  2. 你需要安裝python3的運(yùn)行環(huán)境,這個(gè)可以使用brew進(jìn)行安裝,這里不再贅述。
  3. 你首先需要確定以下幾項(xiàng):
  • 提取一份你當(dāng)前項(xiàng)目編譯環(huán)境的SDK庫頭文件目錄;(Demo中提取了iOS11的SDK頭文件目錄)
  • 你需要混淆的代碼的目錄;
  • 你不需要混淆的代碼的目錄;
  • 你需要提取關(guān)鍵字做排除混淆的目錄;(例如Pod倉庫、第三方頭文件)
  • Swift代碼目錄;(理論上不會(huì)掃描替換,可以用于排除橋接文件)
  • 輸出文件目錄;腳本運(yùn)行后會(huì)產(chǎn)生多個(gè)log文件,以及最終需要使用到的混淆頭文件;

注:建議目錄使用絕對路徑,相對路徑容易出問題。

  1. 確定以上幾項(xiàng)后,找到倉庫根目錄的Confuse.py文件,使用以下命令行模板運(yùn)行:
python3 Confuse.py \
-i 你需要混淆的代碼的目錄,可以是多個(gè)目錄,以`,`分隔 \
-s 當(dāng)前項(xiàng)目編譯環(huán)境的SDK庫頭文件目錄,可以是多個(gè)目錄,以`,`分隔 \
-e 你不需要混淆的代碼的目錄,Swift代碼目錄,可以是多個(gè)目錄,以`,`分隔 \
-c 你需要提取關(guān)鍵字做排除混淆的目錄,可以是多個(gè)目錄,以`,`分隔 \
-k 可選,用于存放需要過濾的key(增加內(nèi)容)
-o 輸出文件目錄

注:各參數(shù)的意義如下:

  • -i(input_dirs):必須,項(xiàng)目需要處理的主要文件所在的目錄
  • -s(system_dirs):可選,配置系統(tǒng)Framework文件的目錄,一般用于做排除字典,避免替換系統(tǒng)關(guān)鍵字
  • -e(exclusive_dirs):可選,用于存放不掃描處理的文件的目錄,比如Swift文件目錄
  • -c(clean_dirs):可選,用于存放排除關(guān)鍵字的文件的目錄,例如Pods下的目錄,或者靜態(tài)庫(頭文件修改后會(huì)出錯(cuò))
  • -k(ignore_key_dir):可選,用于存放需要過濾的key(增加內(nèi)容)
  • -o(output_dir):必須,輸出文件的目錄,用于輸出關(guān)鍵字、日志以及最后生成的混淆頭文件的目錄
  1. 運(yùn)行后會(huì)在你指定的輸出目錄下產(chǎn)生一份Confuse.h文件,內(nèi)容一般如下:
#ifndef NEED_CONFUSE_h
#define NEED_CONFUSE_h
// 生成時(shí)間: 2018-04-03 17:20:51
#define Function1 linotypistStonecrop
#define function1 exactingnessMimologist
#define function2 sheepmanSupersublimated
#define functionWithTitle kensititeCratinean
#define subTitle icelandicUntell
#endif

這份文件包含了一堆的宏定義,將需要替換的方法名都替換為了一些隨機(jī)的字符串,因?yàn)楹甓x是全局替換,我們只需要將該文件引入到自己的項(xiàng)目中,并在PCH文件中進(jìn)行引入即可。

引入該文件后,Command+B測試編譯,如果無法避免而產(chǎn)生編譯錯(cuò)誤則需要手動(dòng)調(diào)整;由于將所有的替換歸集到了頭文件中了,所以遇到有錯(cuò)誤的地方嘗試刪除對應(yīng)宏定義替換信息重新編輯即可。

另外附上一個(gè)系統(tǒng)系統(tǒng)庫路徑:

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks


圖文教程

了解完原理,接下來用圖文來詳細(xì)介紹使用方法:
首先去我的Github上獲取下源代碼資源文件。

注:關(guān)鍵文件如下:

  • Confuse.h最終生成的替換文件就是這個(gè)了,該文件里記錄了所有需要混淆的方法名和與之對應(yīng)的替換字符串
  • Confuse.py該文件是腳本內(nèi)容所在,所有實(shí)現(xiàn)方法都在這。
  • ignoreKey.txt該文件下記錄需要過濾的特殊key,每個(gè)key換行讀取
  • start.sh開始執(zhí)行腳本 ,在此腳本內(nèi)更改路徑

現(xiàn)在開始集成:

首先需要一個(gè)pch文件,至于pch的用法自行百度吧.。

#ifndef TMPrefixHeader_pch
#define TMPrefixHeader_pch
//代碼混淆關(guān)鍵導(dǎo)入文件頭,注釋后不混淆
#import "Confuse.h"
#endif /* TMPrefixHeader_pch */

根據(jù)自行需求添加特殊keyignoreKey.txt文件內(nèi)

通過start.sh腳本快速執(zhí)行


終端執(zhí)行內(nèi)容大概如下:

生成的混淆文件:

編譯結(jié)果:對無參數(shù)、無返回值、多參數(shù)等方法名完成識別替換。


接下來我們用class-dump來反編譯一下:

class-dump -H /Users/wuaming/Library/Developer/Xcode/DerivedData/TMConfuse-becmpkjuhzbzfldtqwaiznqcmmxq/Build/Products/Debug-iphonesimulator/TMConfuse.app -o /Users/wuaming/Desktop/heads

對比結(jié)果:


附上個(gè)人Github:https://github.com/TMWu/TMConfuse

思否:https://segmentfault.com/a/1190000014167401

最后還是要感謝下幾位大佬!
相關(guān)鏈接:
Objective-C Class-dump 安裝和使用方法(原創(chuàng))
iOS安全攻防(二十三):Objective-C代碼混淆
感謝原作者的Github

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 技 術(shù) 文 章 / 超 人 對于IOS來說,由于系統(tǒng)是封閉的,APP上架需要通過App Store,安全性來說相當(dāng)...
    樹下敲代碼的超人閱讀 10,890評論 47 77
  • 前言 什么!我們的代碼拿去安全掃描啦?什么!還掃描出來問題啦?什么!源碼都別看到啦? 居于上一篇文章iOS簡單逆向...
    甘邦閱讀 18,276評論 24 40
  • app風(fēng)靡的時(shí)代,總有一些奇葩的需求。為了刷量,刷排名,制作殼包,為了通過蘋果爸爸審核,想到代碼混淆,垃圾代碼等策...
    二斤寂寞閱讀 23,147評論 11 52
  • 最近在自己的成長歷程,一段段經(jīng)歷浮現(xiàn)出來。上班路上,一個(gè)聲音說:“你們不是以我引以為豪嗎?我要讓你們失望?!敝共蛔?..
    在云端01閱讀 223評論 2 2

友情鏈接更多精彩內(nèi)容