iOS逆向-day11:代碼混淆

一、基本概念
  • 1.1、什么是加固?
    加固是為了增加應(yīng)用的安全性,防止應(yīng)用被破解、盜版、二次打包、注入、反編譯等

  • 1.2、常見(jiàn)的加固方式有

    • 數(shù)據(jù)加密(字符串、網(wǎng)絡(luò)數(shù)據(jù)、敏感數(shù)據(jù)等)
    • 應(yīng)用加殼(二進(jìn)制加密)
    • 代碼混淆(類名、方法名、代碼邏輯等)
      ......(不同平臺(tái)還有不同的做法)
  • 1.3、iOS程序可以通過(guò)class-dump、HopperIDA 等獲取類名、方法名、以及分析程序的執(zhí)行邏輯
    如果進(jìn)行代碼混淆,可以加大別人的分析難度

二、代碼混淆的實(shí)戰(zhàn)
  • 2.1、iOS的代碼混淆方案

    • 第一種:源碼的混淆,混淆項(xiàng)目中下面的方面
      • 類名
      • 方法名
      • 協(xié)議名
    • 第二種:LLVM中間代碼IR的混淆(容易產(chǎn)生BUG)
      自己編寫(xiě)Pass
      ollvm:https://github.com/obfuscator-llvm/obfuscator
  • 2.2、源碼的混淆 - 通過(guò)宏定義混淆方法名、類名

    • 我們主要是針對(duì),類名,方法名,屬性名來(lái)進(jìn)行混淆,混淆太多上架會(huì)被拒絕
    • 我們使用宏定義
      源碼的混淆

      打印
      • .h 文件

        #import <Foundation/Foundation.h>
        
        NS_ASSUME_NONNULL_BEGIN
        
        @interface JKPerson : NSObject
        
        - (void)run;
        
        - (void)setName:(NSString *)name age:(int)age;
        
        @end
        
        NS_ASSUME_NONNULL_END
        
      • .m文件

        #import "JKPerson.h"
        
        @interface JKPerson ()
        
        @end
        
        @implementation JKPerson
        
        - (void)run {
            NSLog(@"----%s----",__func__);
        }
        
        - (void)setName:(NSString *)name age:(int)age {
            NSLog(@"----%s----%@----%d",__func__, name, age);
        }
        
        @end
        
      • pch文件

        #ifndef Obfuscation_pch
        #define Obfuscation_pch
        
        // 針對(duì)類名進(jìn)行混淆
        #define JKPerson rererme
        
        // 針對(duì)方法名混淆
        #define run xsdfd
        
        // 針對(duì)方法名進(jìn)行混淆
        #define setName ahshshb
        
        // 針對(duì)方法中的參數(shù)進(jìn)行混淆
        #define age kkjjjo
        
  • 2.3、源碼混淆注意點(diǎn)

    • 注意點(diǎn)

      • 不能混淆系統(tǒng)方法
      • 不能混淆init開(kāi)頭的等初始化方法
      • 混淆屬性時(shí)需要額外注意set方法
      • 如果xib、storyboard中用到了混淆的內(nèi)容,需要手動(dòng)修正
      • 可以考慮把需要混淆的符號(hào)都加上前綴,跟系統(tǒng)自帶的符號(hào)進(jìn)行區(qū)分
      • 混淆過(guò)多可能會(huì)被AppStore拒絕上架,需要說(shuō)明用途
    • 建議
      給需要混淆的符號(hào)加上了一個(gè)特定的前綴

    • 小工具參考
      MJ老師的 MJCodeObfuscation,使用方法MJ老師的 github 有說(shuō)明,掃描源碼

  • 2.4、代碼混淆工具:ios-class-guard

    • 第三方工具 ios-class-guard ,多年不更新了,不建議使用,如果有能力修改源碼,可以使用

      • 它是基于class-dump的擴(kuò)展,掃描可執(zhí)行文件,所有的東西都進(jìn)行混淆
      • 用class-dump掃描出可執(zhí)行文件中的類名、方法名、屬性名等并做替換,會(huì)更新xib和storyboard的名字等等
    • 用法

      // 安裝 ios-class-guard
      brew install ios-class-guard
      // 具體的使用
      ios-class-guard [options] <mach-o-file>
      

      具體的使用如下

      ios-class-guard --sdk-root /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk -X /Users/wangchong/Desktop/代碼混淆/MJ老師的工具混淆/TestObfuscation/TestObfuscation/Base.lproj -O 生成文件的.h文件 symbols.json TestObfuscation
      
      • ios-class-guard --sdk-root 模擬器路徑 -X xib的路徑 -O 生成文件的.h文件 symbols.json 可執(zhí)行文件的路徑

        提示:symbols.json 是映射文件

    • 常用參數(shù)

      • --sdk-root <path>:用于指定SDK路徑,如果是模擬器SDK,一般路徑就是:
        /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk
      • --sdk-ios:相當(dāng)于指定SDK路徑為真機(jī)設(shè)備SDK
      • -X <path>:用于指定xib、storyboard所在目錄,它會(huì)遞歸搜索
      • -O <path>:生成的混淆頭文件路徑
      • -m <path>:符號(hào)映射表(默認(rèn)是symbols.json)
三、字符串加密
  • 3.1、字符串加密的簡(jiǎn)單介紹

    • 很多時(shí)候,可執(zhí)行文件中的字符串信息,對(duì)破解者來(lái)說(shuō),非常關(guān)鍵,是破解的捷徑之一
    • 為了加大破解、逆向難度,可以考慮對(duì)字符串進(jìn)行加密
    • 字符串的加密技術(shù)有很多種,可以根據(jù)自己的需要自行制定算法
    • 這里舉一個(gè)簡(jiǎn)單的例子
      • 對(duì)每個(gè)字符進(jìn)行異或(^)處理
      • 需要使用字符串時(shí),對(duì)異或()過(guò)的字符再進(jìn)行一次異或(),就可以獲得原字符
  • 3、第三方庫(kù) MJCodeObfuscation 對(duì)字符串進(jìn)行加密

    • 1>、我們以下面的字符串為例: NSString *str1 = @"dcfg342";,使用工具加密如下

      /* dcfg342 */
      extern const MJEncryptStringData * const _2309389973;
      
      /* dcfg342 */
      const MJEncryptStringData * const _2309389973 = &(MJEncryptStringData){
         .factor = (char)116,
         .value = (char []){16,23,18,19,71,64,70,0},
         .length = 7
      };
      

      導(dǎo)入 #import "MJEncryptString.h",使用如下

      NSString *str1 = mj_OCString(_2309389973);
      NSLog(@"str1 = %@", str1);
      // 打印如下
      2020-07-15 07:53:41.851045+0800 TestObfuscation[44303:841930] str1 = dcfg342
      
    • 2>、全部掃描項(xiàng)目文件

      全部掃描項(xiàng)目文件


      使用方式也是 1 中的

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

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