iOS代碼混淆安全加固

  • 最近公司掃描App漏洞,提出要給App做代碼混淆加固,以提高反編譯逆向難度。對於Android應用直接用360安全加固即可;但對於iOS應用,雖然360也提供了免費的加固方法,但前提是項目的enable bitcode必須設置爲YES。但我們項目中引入的很多框架包括百度地圖等並不支持enable bitcode設置爲YES。如果enable bitcode設置爲NO,並且是本地部署的話(企業證書),360安全加固iOS是收費的,收費標準是30萬/年。其他的一些平臺也是收費的。所以只能考慮自己去做了。
  • 360 iOS加固指南

自己創建腳本文件進行代碼混淆

  • 混淆原理 : 代碼編譯階段將符號(方法名、屬性名等)替換成隨機生成的字符串
  • 我們需要創建四個文件如下:
    在這裏插入圖片描述
    其中PrefixHeader.pch宏文件中導入CodeObfuscation.h,這樣項目在編譯的時候就會將CodeObfuscation.h中定義的宏及方法名替換爲對應隨機生成的字符串。
#ifndef PrefixHeader_pch
#define PrefixHeader_pch
#import "CodeObfuscation.h"
#endif /* PrefixHeader_pch */

其中confuse.sh腳本文件是最重要的,是用來在程序編譯的時候將func.list中的方法名替換成隨機生成的字符串,並且保存在CodeObfuscation.h中。其腳本爲:

TABLENAME=symbols
SYMBOL_DB_FILE="$PROJECT_DIR/CodeObfuscation/symbols"
STRING_SYMBOL_FILE="$PROJECT_DIR/CodeObfuscation/func.list"
HEAD_FILE="$PROJECT_DIR/CodeObfuscation/CodeObfuscation.h"
export LC_CTYPE=C

#維護數據庫方便日後作排重
createTable()
{
echo "create table $TABLENAME(src text, des text);" | sqlite3 $SYMBOL_DB_FILE
}

insertValue()
{
echo "insert into $TABLENAME values('$1' ,'$2');" | sqlite3 $SYMBOL_DB_FILE
}

query()
{
echo "select * from $TABLENAME where src='$1';" | sqlite3 $SYMBOL_DB_FILE
}

ramdomString()
{
openssl rand -base64 64 | tr -cd 'a-zA-Z' |head -c 16
}

rm -f $SYMBOL_DB_FILE
rm -f $HEAD_FILE
createTable

touch $HEAD_FILE
echo '#ifndef CodeObfuscation_h
#define CodeObfuscation_h' >> $HEAD_FILE
echo "//confuse string at `date`" >> $HEAD_FILE
cat "$STRING_SYMBOL_FILE" | while read -ra line; do
if [[ ! -z "$line" ]]; then
ramdom=`ramdomString`
echo $line $ramdom
insertValue $line $ramdom
echo "#define $line $ramdom" >> $HEAD_FILE
fi
done
echo "#endif" >> $HEAD_FILE
sqlite3 $SYMBOL_DB_FILE .dump

func.list文件就是用來存放要被混淆的方法和屬性名的。如:
在這裏插入圖片描述
CodeObfuscation.h本身是一個空頭文件,在編譯過後會生成func.list添加屬性和方法對應生成的隨機字符串。下圖是編譯後CodeObfuscation.h的內容:
CodeObfuscation.h
示例:

#import "ViewController.h"
#import "NSArray+Extension.h"

@interface ViewController ()
@property (nonatomic, copy) NSString *title1;
@property (nonatomic, copy) NSString *imgsrc;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title1 = @"";
    self.imgsrc = @"";
    
    NSLog(@"%@",[NSArray getPropertiesFromClass:[self class]]);
    NSLog(@"%@",[NSArray getMethodsFromClass:[self class]]);
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


- (void) test{
    
}
- (void) test1{
    
}
- (void) test2{
    
}
- (void) test3{
    
}
- (void) test4{
    
}

@end

打印出運行時的屬性和方法名:
在這裏插入圖片描述
結果可見,CodeObfuscation.h中的生成的隨機字符串和真正打印出來的並不一致,這是因爲每次運行時,CodeObfuscation.h都會重新生成新的隨機字符串,這時替換屬性和方法名的是上一次生成的隨機字符串。

  • 注意事項:
    1. 屬性方法名需要去重。
    2. 代碼混淆後不能再上架appstore。
    3. 代碼混淆不能對靜態庫進行混淆。
    4. 系統自帶的屬性和方法不能混淆,只能混淆自定義的方法和屬性。
  • 具體步驟可參考:iOS代碼混淆教程

iOS代碼自動混淆

  • 上面的方法會有有一些問題,就是每次創建了新的屬性和方法都得添加到func.list文件中,比較繁瑣,不利於維護。其實我們可以讓方法屬性自動添加func.list中。所以我們要從.m和.h文件中抽取屬性和方法了,但是如何屏蔽系統的屬性和方法名,所以我們要將自己定義的屬性和方法名全部添加一個前綴。
  • confuse.sh中添加新的腳本,修改後的腳本如下:
TABLENAME=symbols
SYMBOL_DB_FILE="symbols"
STRING_SYMBOL_FILE="$PROJECT_DIR/AutoScript/func.list"
CONFUSE_FILE="$PROJECT_DIR/AutoCodeConfusion"  
HEAD_FILE="$PROJECT_DIR/AutoScript/AutocodeObfuscation.h"

export LC_CTYPE=C

#取以.m或.h結尾的文件以+號或-號開頭的行 |去掉所有+號或-號|用空格代替符號|n個空格跟着<號 替換成 <號|開頭不能是IBAction|用空格split字串取第二部分|排序|去重複|刪除空行|刪掉以init開頭的行>寫進func.list
grep -h -r -I  "^[-+]" $CONFUSE_FILE  --include '*.[mh]' |sed "s/[+-]//g"|sed "s/[();,: *\^\/\{]/ /g"|sed "s/[ ]*</</"| sed "/^[ ]*IBAction/d"|awk '{split($0,b," "); print b[2]; }'| sort|uniq |sed "/^$/d"|sed -n "/^hj_/p" >$STRING_SYMBOL_FILE


#維護數據庫方便日後作排重,一下代碼來自念茜的微博
createTable()
{
echo "create table $TABLENAME(src text, des text);" | sqlite3 $SYMBOL_DB_FILE
}

insertValue()
{
echo "insert into $TABLENAME values('$1' ,'$2');" | sqlite3 $SYMBOL_DB_FILE
}

query()
{
echo "select * from $TABLENAME where src='$1';" | sqlite3 $SYMBOL_DB_FILE
}

ramdomString()
{
openssl rand -base64 64 | tr -cd 'a-zA-Z' |head -c 16

}

rm -f $SYMBOL_DB_FILE
rm -f $HEAD_FILE
createTable

touch $HEAD_FILE
echo '#ifndef AutocodeObfuscation_h
#define AutocodeObfuscation_h' >> $HEAD_FILE
echo "//confuse string at `date`" >> $HEAD_FILE
cat "$STRING_SYMBOL_FILE" | while read -ra line; do
if [[ ! -z "$line" ]]; then
ramdom=`ramdomString`
echo $line $ramdom
insertValue $line $ramdom
echo "#define $line $ramdom" >> $HEAD_FILE
fi
done
echo "#endif" >> $HEAD_FILE
sqlite3 $SYMBOL_DB_FILE .dump

在這裏插入圖片描述
添加了收集方法的腳本後,我們不需要再手動的去添加方法到func.list中了。程序編譯後會自動將hj_開頭的方法添加到func.list中。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章