iOS-代碼混淆加固方案

2020-08-29 閃念基因

對於iOS來說,由於系統是封閉的,APP上架需要通過App Store,安全性來說相當高。但是對於大廠和知名APP而言,別人給的安全保障永遠沒有自己做的來得踏實。所以對於大廠、少部分企業級和金融支付類應用來說加固是相當重要的。
下面是目前幾個專業加固大廠提供的加固策略

  • 網易

  • 網易安全三板斧:
  1. 第一板斧是防靜態分析,這裡包括字符串加密、符號混淆、代碼邏輯混淆和遊戲存檔加密;

2.第二板斧是防動態調試、反調試和通信安全(數據加密);

  1. 第三板斧是外掛檢測、加速掛、內存修改掛和自動任務掛等
  • 愛加密

  • safengine

  • 幾維安全

  • 梆梆安全

本文將針對以上幾點進行實現,對於一些不太容易實現的將會做方向性討論

  • 字符串加密
  • 代碼混淆(方法名,類名,變量名,符號表)
  • 代碼邏輯混淆
  • 反調試

字符串加密

對字符串加密的方式目前我所了解到掌握到的最可靠方式就是用腳本將代碼中的所有標記需要加密的字符串進行異或轉換,這樣代碼中就不存在明文字符串了。當然第三方的字符串加密不可能這麼簡單,具體怎麼做的我也不太清楚。不過為了增加字符串加密的難度複雜性,我們可以先將字符串用加密工具轉換(例如AES、base64等)後的把加字符串放在工程中,並且把解密的鑰匙放在工程中,用異或轉換,把解密鑰匙和加密後的字符串轉換,這樣就有2層保障,增加了複雜度。

  • 首先 我們創建任意一個工程,在工程中寫入下面的代碼,並在每句打上斷點,再選擇Xcode工具欄的Debug --> Debug Workflow --> Always Show Disassembly。這樣你就可以在斷點處進入彙編模式界面,最後運行程序

/* 加密NSString字符串 */ NSString *str = @&34;; NSLog(@&34;,str); /* 加密char*字符串 */ char* cStr = &34;; NSLog(@&34;,cStr);

你會發現,你的字符串內容暴露在了彙編模式中,這會導致別人在逆向分析你的工程時能看見你的字符串內容,我們一般接口、域名、加解密鑰匙串、AppKey、AppId等比較重要的東西會放在客戶端用作字符串,這就很容易暴露出來。

  • 步驟1 首先需要在工程代碼中進行修改,把下面的宏和decryptConfusionCS,decryptConstString函數放入代碼中,用宏包含每個需要轉換的字符串。

/* 字符串混淆解密函數,將char[] 形式字符數組和 aa異或運算揭秘 */extern char* decryptConfusionCS(char* string){ char* origin_string = string; while(*string) { *string ^= 0xAA; string++; } return origin_string;}/* 解密函數,返回的是NSString類型的 */extern NSString* decryptConstString(char* string){ /* 先執行decryptConfusionString函數解密字符串 */ char* str = decryptConfusionCS(string); /* 獲取字符串的長度 */ unsigned long len = strlen(str); NSUInteger length = [[NSString stringWithFormat:@&34;,len] integerValue]; NSString *resultString = [[NSString alloc]initWithBytes:str length:length encoding:NSUTF8StringEncoding]; return resultString;}/* * 使用heyujia_confusion宏控制加密解密 * 當heyujia_confusion宏被定義的時候,執行加密腳本,對字符串進行加密 * 當heyujia_confusion宏被刪除或為定義時,執行解密腳本,對字符串解密 */ifdef heyujia_confusion/* heyujia_confusion 宏被定義,那麼就進行執行解密腳本 *//* confusion_NSSTRING宏的返回結果是NSString 類型的 */define confusion_CSTRING(string) decryptConfusionCS(string)define confusion_NSSTRING(string) @string/* 加密char *類型的 */endif@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. /* 使用confusion_NSSTRING宏包含需要加密的NSString字符串 */ NSString *str = confusion_NSSTRING(&34;); NSLog(@&34;,str); /* 使用confusion_NSSTRING宏包含需要加密的char*字符串 */ char* cStr = confusion_CSTRING(&34;); NSLog(@&34;,cStr); }

  • 步驟2 使用終端cd 到需要加密的工程目錄下 執行 touch confusion.py 和 touch decrypt.py 命令,生產加密和解密腳本文件
  • 步驟3 把下面代碼加入解密腳本confusion.py中

encoding=utf8 author by heyujia 替換所有字符串常量為加密的char數組,形式((char[]){1, 2, 3, 0})import importlibimport osimport reimport sys 當然可以不使用0xAA 使用其他的十六進位也行 例如0XBB、0X22、0X11def replace(match): string = match.group(2) + &39; replaced_string = &39; + &39;.join([&34; % ((ord(c) ^ 0xAA) if c != &39; else 0) for c in list(string)]) + &39; return match.group(1) + replaced_string + match.group(3) 使用replace函數對字符串進行異或轉換def obfuscate(file): with open(file, &39;) as f: code = f.read() f.close() code = re.sub(r&34;(.*?)&39;, replace, code) code = re.sub(r&define ggh_confusion&39;39;, code) with open(file, &39;) as f: f.write(code) f.close() 對每個文件執行obfuscate函數def openSrcFile(path): print(&34;+ path) case 1: print((&34; + parent).encode(&39;)) 34; dirname is:&39;utf-8&case 2 for filename in filenames: extendedName = os.path.splitext(os.path.join(parent,filename)) if (extendedName[1] == &39; or extendedName[1] == &39;): print(&34;+ os.path.join(parent,filename)) obfuscate(os.path.join(parent,filename))39;../daimahunxiao&39;__main__&34;本腳本用於對原始碼中被標記的字符串進行加密&34;請輸入正確的原始碼路徑&!/usr/bin/env python -*- coding: utf-8 -*- 解密腳本34;& 替換((char[]){1, 2, 3, 0})的形式為字符串,同時讓每個數組值與0xAA異或進行解密def replace(match): string = match.group(2) decodeConfusion_string = &34; for numberStr in list(string.split(&39;)): if int(numberStr) != 0: decodeConfusion_string = decodeConfusion_string + &34; % (int(numberStr) ^ 0xAA) replaced_string = &34;&39;\&39; print(&34; + replaced_string) return match.group(1) + replaced_string + match.group(3)39;r&39;(confusion_NSSTRING\(|confusion_CSTRING\()\(\(char \[\]\) \{(.*?)\}\)(\))&39;[/]*39;, &define ggh_confusion&39;w&讀取源碼路徑下的所有.h和.m 文件def openSrcFile(path): print(&34;+ path) case 1: print((&34; + parent).encode(&39;)) 34; dirname is:&39;utf-8&case 2 for filename in filenames: extendedName = os.path.splitext(os.path.join(parent,filename)) 39;.h&39;.m&34;已解密文件:&源碼路徑srcPath = &39;if __name__ == &39;: print(&34;) if len(srcPath) > 0: openSrcFile(srcPath) else: print(&34;) sys.exit()

  • 步驟5 根據自己的需求修改下腳本裡面的代碼 和 文件路徑。
  • 步驟6 把步驟1中的宏heyujia_confusion注釋了,然後執行加密腳本,在終端中輸入 python confusion.py ,
    (1.如果報錯,請查看下自己Mac電腦中的python版本,如果是python3就輸入 python3 confusion.py .
    (2.如果報 Non-ASCII character &39; in file confusion.py on line 2 相關的錯,請確定腳本的前面3行是

encoding=utf8!/bin/sh 代碼混淆腳本 heyujia 2018.03.15識別含有多字節編碼字符時遇到的解析衝突問題export LC_CTYPE=Cexport LANG=C項目路徑,會混淆該路徑下的文件ProjectPath=&34;34;_&34;/Users/xieyujia/Desktop/ios/學習項目/tihuan&34;_&第一個參數為項目路徑if [[ $1 ]]thenif [[ $1 != &34; ]]; thenProjectPath=$1fifi34;_&查找文本中所有要求混淆的屬性\方法\類,只會替換文本中ob_開頭和_fus結尾的字符串(區分大小寫,例如oB_就不會做混淆),如果注釋內容有該類型的字符串,也會進行替換。對於使用 _下劃線訪問的變量屬性,不會有影響,一樣會替換成對應_的混淆內容。resultfiles=`grep &39; -rl $ProjectPath`34;項目沒有需要混淆的代碼&34;開始混淆代碼...&39;BEGIN{srand();k=0;}隨機字符串生成函數function random_string(len) {result=&34;k;alpbetnum=split(&34;, alpbet, &34;);for (i=0; i<len; i++) {result = result&34;alpbet[ random_int(1, alpbetnum) ];}return result;}/ob_[A-Za-z0-9_]*_fus/{x = $0;34;ob_[A-Za-z0-9_]*_fus&判斷是否有之前已經找過的重複字符串for ( i = 0; i < k; i++ ){if (strarr[i] == tempstr){break;}}if(i<k){不是重複字符串,添加到替換數組strarr[k++]=tempstr;}randomstr=random_string(20);printf(&34;, tempstr,randomstr);39; $resultfiles )34;|&34;:&34;原項:&34;:&34;加密項:&替換文件夾中所有文件的內容(支持正則)39;&34;s/${record1}/${record2}/g&34;第&34;項混淆代碼處理完畢&34;recordnum = $recordnum + 1&查找需要混淆的文件名並替換filerecordnum=1while [[ 1 == 1 ]]; dofilerecord=`echo $x|cut -d &34; -f$filerecordnum`if [[ -z $filerecord ]]thenbreakfifilerecord1=`echo $filerecord|cut -d &34; -f1`34;原項:&34;:&echo &34;$filerecord234;*&39;BEGIN{frecord1=&39;&34;&34;;frecord2=&39;&34;&34;;finish=1}{filestr=$0;gsub(frecord1,frecord2,filestr);print &34; $0 &34; filestr&34;finish&34;;finish++;}&34;filerecordnum = $filerecordnum + 1&!/bin/sh 代碼還原腳本 RyoHo 2018.03.15識別含有多字節編碼字符時遇到的解析衝突問題export LC_CTYPE=Cexport LANG=C已經混淆的項目路徑ProjectPath=&34;34;/Users/xieyujia/Desktop/ios/學習項目/tihuan20180315_1456&第一個參數為項目路徑if [[ $1 ]]thenif [[ $1 != &34; ]]; thenProjectPath=$1fifi34;_&內容還原x=`cat $SecretFile`recordnum=1while [[ 1 == 1 ]]; dorecord=`echo $x|cut -d &34; -f$recordnum`if [[ -z $record ]]thenbreakfirecord1=`echo $record|cut -d &34; -f1`echo &34;$record1record2=`echo $record|cut -d &34; -f2`echo &34;$record234;指定的密鑰文件不能還原&替換文件夾中所有文件的內容(支持正則)39;&34;s/${record2}/${record1}/g&34;第&34;項混淆代碼還原完畢&34;recordnum = $recordnum + 1&文件還原filerecordnum=1while [[ 1 == 1 ]]; dofilerecord=`echo $x|cut -d &34; -f$filerecordnum`if [[ -z $filerecord ]]thenbreakfifilerecord1=`echo $filerecord|cut -d &34; -f1`34;原項:&34;:&echo &34;$filerecord234;*&39;BEGIN{frecord1=&39;&34;&34;;frecord2=&39;&34;&34;;finish=1;}{filestr=$0;gsub(frecord2,frecord1,filestr);print &34; $0 &34;filestr &34;finish&34;finish++;}&34;filerecordnum = $filerecordnum + 1"done

應大家需要把腳本源碼:https://github.com/xkftkffz/DMHXDemo 地址 放出來

建議大家看看腳本內容,有利於學習理解。該腳本是有針對性的混淆內容,可以自己修改腳本中的正則表達式來確定混淆的內容。腳本中只會替換文本中ob_開頭和_fus結尾的字符串(區分大小寫,例如oB_就不會做混淆),如果注釋內容有該類型的字符串,也會進行替換。對於使用 _下劃線訪問的變量屬性,不會有影響,一樣會替換成對應_的混淆內容。

相關焦點

  • ios雲端加固平臺上線 國內 IOS應用加固技術實現突破
    放眼當下,做iOS檢測與加固的企業不少,皆有開發相關產品。通過研究發現,多數公司安全團隊或第三方安全服務商普遍採用源碼編譯的方式,在編譯階段對原始碼進行混淆、資源加密和邏輯混淆等安全保護。然而,源碼加固需要用戶配置複雜的開發環境或將源碼提交給第三方加固平臺。
  • 58同城iOS客戶端安全加固原理與實踐
    App 如果不進行安全加固,在越獄環境下猶如裸奔,嚴重者被黑產利用,給公司造成經濟損失。本文主要介紹代碼混淆、反調試防護、籤名信息校驗、異常數據檢測和處理等 iOS 中常見的安全防護技術,以及在 58 同城 iOS 客戶端的實踐應用。
  • 詳解一種端遊遊戲代碼保護方案
    PE代碼保護已逾20多年的歷史,從21世紀初期,PE代碼保護已經有了雛形,且誕生了許多直至今日仍具有不小影響力的加固思路與加密算法,如大名鼎鼎的「UPX」殼,便是利用其最核心的UCL這一效率較高的壓縮算法來實現的。
  • Andorid APK反逆向解決方案:梆梆加固原理探尋
    如何使程序代碼免受盜版篡改就成了開發者面臨的頭等大事,今天我們將分析一個不錯的解決方案——梆梆加固。梆梆加固保護效果分析我們通過逆向分析加固後的app,來看看梆梆加固對app的保護效果。程序代碼的第一執行點是Application對象,首先查看TestApplication類對象。
  • 幾維安全推出Java2C加密方案,完美解決Java代碼反編譯
    為了給用戶提供更為安全的移動應用,有效減少反編譯、二次打包、植入廣告木馬等操作,幾維安全先後推出了多項移動應用加固服務,如代碼混淆產品——《幾維安全編譯器》,代碼虛擬化產品——《KiwiVM虛擬機》《移動APP安全檢測系統》《移動APP安全加密系統》等。面對新的攻擊手段,幾維安全最新推出了全平臺端安全產品——Java2C加密方案。
  • 基於APP安全滲透測試的加固流程分享
    很多公司都有著自己的APP,包括安卓端以及ios端都有屬於自己的APP應用,隨著網際網路的快速發展,APP安全也影響著整個公司的業務發展,前段時間有客戶的APP被攻擊,數據被篡改,支付地址也被修改成攻擊者自己的,損失慘重,通過朋友介紹找到我們SINE安全做APP的安全防護,我們對客戶APP進行滲透測試
  • 幾維安全推出全新Java2C加密方案,完美解決Java代碼反編譯!
    為了給用戶提供更為安全的移動應用,有效減少反編譯、二次打包、植入廣告木馬等操作,幾維安全先後推出了多項移動應用加固服務,如代碼混淆產品——《幾維安全編譯器》,代碼虛擬化產品——《KiwiVM虛擬機》《移動APP安全檢測系統》《移動APP安全加密系統》等。面對新的攻擊手段,幾維安全最新推出了全平臺端安全產品——Java2C加密方案。
  • VMP 加固 PK 第三代加固,誰才能為 APP 保平安?
    目前,App加固技術經歷了以下四代技術發展↓↓↓第一代加固技術——混淆技術;第二代加固技術——加殼技術;第三代加固技術——指令抽離;第四代加固技術——指令轉換,即現在經常被應用的VMP加固技術。修復工具部分代碼見圖1-1圖1-1修復後的效果:如圖1-2。圖1-2反編譯為java源碼文件,代碼邏輯更加清晰,如圖 1-3圖 1-3總結:抽取加固一般可以防住一些基礎手段的攻擊,但網上有很大一部分工具可以破解此類技術的加固,核心代碼保護強度不夠,對網上的工具稍作修改即可破解。
  • 混淆程序:代碼最安全的加密方式
    在2020年底,幾位學者成功找到了一種加密方式,讓計算機用戶無法通過獲取代碼破解程序。 加密程序代碼 首先要對其進行混淆 不可區分混淆(indistinguishability obfuscation,簡稱IO)是一種強大的加密算法,它不僅能隱藏數據集,還能隱藏程序本身,從而實現幾乎所有的加密協議。
  • Android apk資源保護方案研究分析
    齊魯晚報11月10日訊:Android APP以APK文件形式存在,APP中主要包含應用程式代碼和資源文件兩部分,如何有效保護Android應用中的代碼、資源的安全一直是開發者最關心的話題。針對應用程式代碼,目前主要有兩類方案,即代碼混淆和應用加密。
  • 深信服App安全加固解決方案
    銘冠科技的深信服App安全加固解決方案中,管理員將APP直接上傳到「深信服應用封裝雲平臺」,交由平臺注入安全加固程序代碼,實現APP的安全加固。  方案優勢:  1、簡單,無需二次開發,無需開發商配合  2、快速,5分鐘注入,10分鐘發布  3、統一,一套平臺實現PC終端,移動APP安全接入  4、用戶體驗好,
  • 萬萬沒想到:對JS代碼混淆,竟造成這樣的性能損失?
    為了驗證這一問題,本文通過實測的方式尋求真相,揭示JS混淆加密究竟會帶來多少性能影響。準備1、JS代碼混淆加密,使用JShaman代碼保護平臺,這是國內知名的商業JS代碼混淆服務平臺。實驗使用JShaman的通用版保護。
  • Java代碼混淆「Android逆向學習」
    有的時候,我們想分析一個程序的Java層邏輯,進行反編譯後,發現代碼所有的函數名、變量名、類名等都成了一些雜亂無章的名字,沒有任何規律可言,這是怎麼回事呢?其實程序是被混淆了。混淆是什麼?代碼保護的第一步就是混淆,就是對代碼動下手腳,讓反編譯出來的代碼不這麼容易看懂。
  • 友盟、Bugly、360加固保崩潰日誌服務對比分析
    360加固保:加固保以APP加固知名,它推出的崩潰日誌分析服務最大特點是免SDK集成,這是與其他產品最明顯的區別。也就是說不需要任何代碼集成過程,上傳APP進行加固後就可以使用崩潰日誌分析服務(雖然是免SDK集成,但也會增加些包體大小,大概150M左右)。
  • Sodinokibi勒索病毒最新變種,竟通過混淆JavaScript代碼傳播
    近日,亞信安全截獲利用混淆的JS代碼傳播的Sodinokibi勒索病毒變種文件,其通過垃圾郵件附件傳播。由於附件是混淆的JS腳本文件,其可以輕鬆逃避殺毒軟體的檢測,一旦用戶點擊附件,計算機中的文件將會被加密。亞信安全將其命名為TROJ_FR.620727BA。
  • 烈山水平注漿加固施工方案【盛達瑞通】
    烈山水平注漿加固施工方案【盛達瑞通】北京盛達瑞通建設有限公司水平注漿加固,公司專業從事於建築加固、工程加固、碳纖維加固、植筋加固、粘鋼加固、結構補強、地基基礎加固、別墅改造、護坡噴射、鋼結構加層、鋼樓梯製作等建築工程
  • JavaScript 代碼混淆實戰(六):仿obfuscator混淆控制流平坦化
    混淆前:window = {};window.atob = function(r) {
  • 優秀,承重梁加固方案
    承重梁加固方案一般而言,等級級別較高的建築物或者是有特殊要求的建築物需要使用該種抗震方法,和傳統的抗震方法相比,該種抗震方法的抗震級別更高,能夠滿足重要建築物的抗震要求。建築工程加固方面的要求:不同類別、不同使用功能的建築物所使用的加固方法不同,加固方法需要根據建築物的整體布局和內部結構來選擇。
  • VBA代碼如何有效保護?一鍵混淆變成你自己也不認識的樣子
    ,我之前介紹過我的VBA代碼助手專業版本工具可以做到模塊隱藏,設置工程不可查看,但是在高手面前依然可以輕鬆破解得到原始代碼,所以我又開發了VBA代碼混淆功能,客戶或者同事即使拿到代碼,也完全無法修改和維護,這樣就能最大限度的保護我們的勞動成果!
  • 通付盾移動加固實戰系列:Android資源文件加密
    2.res資源則存放在App的res目錄下,該類資源在App打包時大多會被編譯,變成二進位文件,應用層代碼通過resource id對該類資源進行訪問。常見方案及問題目前市場上常見的資源文件保護方案主要有以下兩種思路:資源文件混淆保護,對資源文件的路徑進行混淆,縮短文件夾和文件名,以及替換/刪除某個資源的名稱