1. 程式人生 > >iOS平臺程式碼混淆指令碼

iOS平臺程式碼混淆指令碼

這是一款用於混淆iOS程式碼的外掛。最近試用了幾款目前很多開源的針對iOS程式碼混淆的外掛,但混淆生成的檔案一直不如人意,執行程式碼報錯的地方依舊很多。同時有些外掛實現的方式個人認為過於複雜,需要使用類似於class-dump的技術來進行反編譯再進行混淆操作,同時很多外掛使用的是直接更換需要混淆的關鍵字,工程過於龐大,對於程式碼的可讀寫性也有影響。於是決定自己寫一個建議的外掛,就有了本倉庫的誕生。

實現原理

其實外掛的實現方式十分簡單,提取使用者編寫的檔案中的方法名,使用巨集定義將其更換為任意的無規則字串。但這種方式有一些需要注意的點:

  1. 對於系統庫產生的方法名,不可替換;對於系統使用到的關鍵字,也不可以替換;否則會報錯;
  2. Swift混編的專案,Swift中的程式碼不可替換;同時Swift呼叫Objective-C的特定方法名也不可以輕易替換;
  3. 第三方庫暴露的標頭檔案的方法名,不可替換;

根據上面的規則(可能有遺漏),該指令碼採用了相對簡單的方法來避免:

  1. 只掃描.h和.m檔案,只掃描方法名。(對於屬性名,嘗試過掃描,但由於屬性的訪問方式多樣,並不建議做混淆,會產生額外的工作量);
  2. 對於系統庫,讓使用者手動指定,這個是可以提取的,直接拿到系統庫的標頭檔案即可,指令碼會自動掃描到所有的系統關鍵字,直接做排除處理。(以iOS11的SDK為例,系統關鍵字約6萬個);
  3. 對於Swift程式碼,可以直接排除在掃描目錄外;
  4. 對於第三方庫,使用者可以手動指定目錄,指令碼會自動掃描提取關鍵字,在混淆時避免這些關鍵字。

依據上述原理,基本可以避免多數情況下產生的混淆錯誤;當然,由於各種專案的複雜性,有一些複雜的混淆錯誤無法避免,需要後續手動調整程式碼。

使用方式

  1. clone本倉庫;
  2. 你需要安裝python3的執行環境,這個可以使用brew進行安裝,這裡不再贅述。
  3. 你首先需要確定以下幾項:
  • 提取一份你當前專案編譯環境的SDK庫標頭檔案目錄;(Demo中提取了iOS11的SDK標頭檔案目錄)
  • 你需要混淆的程式碼的目錄;
  • 你不需要混淆的程式碼的目錄;
  • 你需要提取關鍵字做排除混淆的目錄;(例如Pod倉庫、第三方標頭檔案)
  • Swift程式碼目錄;(理論上不會掃描替換,可以用於排除橋接檔案)
  • 輸出檔案目錄;指令碼執行後會產生多個log檔案,以及最終需要使用到的混淆標頭檔案;

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

  1. 確定以上幾項後,找到倉庫根目錄的Confuse.py檔案,使用以下命令列模板執行:
python3 Confuse.py \
-i 你需要混淆的程式碼的目錄,可以是多個目錄,以`,`分隔 \
-s 當前專案編譯環境的SDK庫標頭檔案目錄,可以是多個目錄,以`,`分隔 \
-e 你不需要混淆的程式碼的目錄,Swift程式碼目錄,可以是多個目錄,以`,`分隔 \
-c 你需要提取關鍵字做排除混淆的目錄,可以是多個目錄,以`,`分隔 \
-o 輸出檔案目錄

注:各引數的意義如下:

  • -i(input_dirs):必須,專案需要處理的主要檔案所在的目錄
  • -s(system_dirs):可選,配置系統Framework檔案的目錄,一般用於做排除字典,避免替換系統關鍵字
  • -e(exclusive_dirs):可選,用於存放不掃描處理的檔案的目錄,比如Swift檔案目錄
  • -c(clean_dirs):可選,用於存放排除關鍵字的檔案的目錄,例如Pods下的目錄,或者靜態庫(標頭檔案修改後會出錯)
  • -o(output_dir):必須,輸出檔案的目錄,用於輸出關鍵字、日誌以及最後生成的混淆標頭檔案的目錄

例如我的Demo中執行指令碼如下:

python3 Confuse.py \
-i /Users/LennonChin/Desktop/Code-Confuse-Plugin/Demo/Confuse_Demo/Confuse_Demo/ \
-s /Users/LennonChin/Desktop/Code-Confuse-Plugin/Demo/System_Frameworks_iOS11 \
-e /Users/LennonChin/Desktop/Code-Confuse-Plugin/Demo/Confuse_Demo/Confuse_Demo/Swift/ \
-c /Users/LennonChin/Desktop/Code-Confuse-Plugin/Demo/Confuse_Demo/Confuse_Demo/OtherSDK \
-o /Users/LennonChin/Desktop/Code-Confuse-Plugin/Demo/

然後回車執行即可。

注:在本專案中有一份示例程式碼,可以參考。

  1. 執行後會在你指定的輸出目錄下產生一份Confuse.h檔案,內容一般如下:
#define NEED_CONFUSE 1
#if NEED_CONFUSE
// create time at 2018-03-07 11:08:29.482661
#define thisIsATestFunctionWithoutParameters EHIFIFFCDEDBDAEHAHJECHHDJABBEFIE
#define thisIsATestFunctionWithParameter1 FGCCAACHEFDEDEABBEDHDAACEEEFFDDB
#define thisIsAPublicFunctionWithParameter1 BCCAFCBBAAACDACBJAJJGEJHDCAHIFAJ
#define thisIsAPublicFunctionWithoutParameters FBIBCDBBEDJADFIBBBFJIJACCFJIAACE
#endif

這份檔案包含了一堆的巨集定義,將需要替換的方法名都替換為了一些隨機的字串,因為巨集定義是全域性替換,我們只需要將該檔案引入到自己的專案中,並在PCH檔案中進行引入即可。

引入該檔案後,Command+B測試編譯,如果無法避免而產生編譯錯誤則需要手動調整;由於將所有的替換歸集到了標頭檔案中了,所以遇到有錯誤的地方嘗試刪除對應巨集定義替換資訊重新編輯即可。

License

MIT

Copyright (c) 2016-present, LennonChin