iOS強(qiáng)度混淆(方法名類名屬性名混淆+字符串加密(Hikari)+其他)

前言

網(wǎng)上有的混淆是為了安全或做馬甲包像屋,是可以上 App Store 的輕度混淆。本篇文章說的是公司需要通過一些渠道的過審奏甫,而做的強(qiáng)度混淆凌受,沒試過上線。

(PS:由于項(xiàng)目老舊龐大挠进,本篇文章記錄遇到問題及解決方式誊册,應(yīng)該是很詳細(xì)的了??解虱。)


強(qiáng)度混淆一般重要的是代碼混淆、字符串加密、其他(例如:防越獄于宙、防截屏、防錄屏等)至会。

一谱俭、逆向工具

逆向的方式有很多昆著,最基礎(chǔ)的就是 class-dump(可以查看所有頭文件),深度的可以用 Hopper煤痕。

參考:# iOS進(jìn)階 # 逆向的了解

可以在開始之前逆向一下看看接谨,混淆后對比一下。

二巷帝、代碼混淆

2.1 宏替換方案

宏替換指的是類名扫夜、方法名历谍、屬性名的混淆,即將這些生成混淆宏印蔬,在預(yù)編譯時(shí)期進(jìn)行替換脱衙。

2.2 STCObfuscator

STCObfuscator 是用來進(jìn)行 Object-C 代碼混淆的工具,在模擬器 DEBUG 環(huán)境下運(yùn)行生成混淆宏退唠,混淆的宏可以在其他環(huán)境下進(jìn)行編譯荤胁,支持 Cocoapod 代碼混淆。

使用方式很簡單垢油,作者步驟很詳細(xì)滩愁。但是我的項(xiàng)目比較復(fù)雜,在使用中遇到些問題硝枉,分享一下妻味。

2.3 篩選需要混淆的類名

/** 不進(jìn)行混淆的類 */
@property (nonatomic, strong) NSArray *unConfuseClassNames;

/** 不進(jìn)行混淆的帶特性前綴的類 */
@property (nonatomic, strong) NSArray *unConfuseClassPrefix;

/** 不進(jìn)行混淆的帶有特定前綴的符號名 */
@property (nonatomic, strong) NSArray *unConfuseMethodPrefix;
  1. 如上,首先工具提供了不進(jìn)行混淆的類或前綴蔑匣,看起來很簡單棕诵,把所有第三方的前綴加進(jìn)去就可以了校套。但是我們的項(xiàng)目很大很舊牧抵,找出所有第三方前綴,實(shí)驗(yàn)了幾次還是很多錯(cuò)誤妹孙,尤其是有些沒有前綴或 .a 根本看不到的一些获枝,總之是錯(cuò)誤很多省店。

  2. 換個(gè)思路,我們來添加需要混淆的類雹舀,當(dāng)然需要改源碼粗俱,改動不大,可以接受签财。如果你的項(xiàng)目結(jié)構(gòu)和代碼足夠好,恭喜你寫上你們的統(tǒng)一前綴就行了模庐。但是如果你和我一樣遇到項(xiàng)目很舊油宜,沒有統(tǒng)一的前綴就需要篩選出所有要進(jìn)行混淆的類名慎冤。

我們采用的方式:

  1. 我們的項(xiàng)目結(jié)構(gòu)目錄結(jié)構(gòu)是整理過的,所以明確的知道哪些是項(xiàng)目代碼(項(xiàng)目目錄整理見之前文章)醉者;
  2. 使用腳本把所有要混淆的類名輸出在.txt文檔中(待補(bǔ)充)披诗。

簡單腳本教程

  1. 新建文件夾 getClassName呈队;
  2. 在改文件夾下新建 job.sh腳本文件;
  3. 腳本文件內(nèi)容為 #!/bin/bash;
  4. 依次執(zhí)行下面的命令:
?  ~ /Users/zhangmaomao/Desktop/getClassName
?  getClassName chmod +x job.sh
?  getClassName ./job.sh
?  getClassName find ./Classes -name "*.h">path.txt
  1. path.txt中得到所有.h文件的路徑名如下:
./Classes/Home/EHIHomeDefines.h
./Classes/Home/Activity/Models/FocusModel.h
./Classes/Home/Activity/ViewControllers/HomeActivityViewController.h
./Classes/Home/Activity/Views/HomeActivityCell.h
...
  1. 刪掉類名前面路徑:
?  getClassName book=/Users/zhangmaomao/Desktop/getClassName/path.txt
?  getClassName while read line
while> do
while> echo ${line##*/} >>result.txt
while> done <$book

2.4 篩選不混淆的model類名

經(jīng)過上面的過程粒竖,混淆后終于運(yùn)行起來了H锩纭(注意該工具是 Debug 下生成 #define 混淆宏沿彭,然后使用宏替換。仔細(xì)看下代碼锅移,直接運(yùn)行的時(shí)候注釋相關(guān)代碼)

但是饱搏,數(shù)據(jù)不正常顯示推沸。排查了以后發(fā)現(xiàn)又是老項(xiàng)目的坑??券坞。排查原因:model 類接收數(shù)據(jù)沒有一次性解析肺素,第二層數(shù)據(jù)獲取問題倍靡。因?yàn)?model 的屬性已經(jīng)混淆了,再去去數(shù)據(jù)自然是沒有的他挎,代碼例如:

self.storeStockResponse = [StoreStockResponse objectWithKeyValues:chauffeurResult.Result];
self.filterTitleList = [[CarFilterType objectArrayWithKeyValuesArray:self.storeStockResponse.CarFilterTypeList] mutableCopy];

現(xiàn)在就需要篩選出不混淆的 model 類名捡需,嗯站辉。。如果你有基類或統(tǒng)一前綴的話就 happy 了殊霞,不幸的是我沒有汰蓉。。。需要的話操作如下:

  1. 腳本找出調(diào)用數(shù)據(jù)解析的類名岩齿,這是必須要篩掉的(待補(bǔ)充)苞俘;
  2. 除了獲取到的數(shù)據(jù)解析吃谣,還會有 model 類轉(zhuǎn) json 數(shù)據(jù)請求接口的情況(代碼例如下),對象調(diào)用的就沒有辦法像上面那樣拿到調(diào)用者肃晚,所以保險(xiǎn)起見我們的情況需要篩選出所有 model 類仔戈;
[contactModel keyValues]
  1. 不幸的是我們也沒有統(tǒng)一的后綴。晋修。墓卦。只能先篩選多數(shù)的 model、Response睁本、Request著榴、Dto 結(jié)尾的類脑又,還有熟悉重要的挑幾個(gè);
  2. 結(jié)合上面腳本篩選出來的往衷,就是一堆不需要篩選的類了严卖。

2.5 特殊字符

還有一點(diǎn)是我篩選掉了failHandler哮笆,因?yàn)楹芏嗟谌嚼锇诖耍煜湍貌坏交卣{(diào)了福铅。

[STCObfuscator obfuscatorManager].unConfuseMethodPrefix = @[@"failHandler"];

2.6 開始混淆

從原來要篩選的文檔中刪除掉不混淆的 model 類名项阴,清空STCDefination.h文件环揽,重新在 Debug 環(huán)境下在模擬器上運(yùn)行。

使用宏替換運(yùn)行汛兜,終于跨扮,程序運(yùn)行正常

(運(yùn)行時(shí)看不出來混淆效果帝嗡,這時(shí)候 class-dump 出來的頭文件已經(jīng)明顯混淆過了)

三哟玷、字符串加密(Hikari)

直到這里是還是不夠的,項(xiàng)目中難免有明文字符串喉脖,比如加密鑰字符串等抑月,敏感字符的混淆是必須的G酢!性锭!

所以又使用了這個(gè)工具:Hikari叫胖。

這個(gè)工具很強(qiáng)大瓮增,有以下幾種配置可以選擇:

-mllvm -enable-bcfobf 啟用偽控制流
-mllvm -enable-cffobf 啟用控制流平坦化
-mllvm -enable-splitobf 啟用基本塊分割
-mllvm -enable-subobf 啟用指令替換
-mllvm -enable-acdobf 啟用反class-dump
-mllvm -enable-indibran 啟用基于寄存器的相對跳轉(zhuǎn)绷跑,配合其他加固可以徹底破壞IDA/Hopper的偽代碼(俗稱F5)
-mllvm -enable-strcry 啟用字符串加密
-mllvm -enable-funcwra 啟用函數(shù)封裝
-mllvm -enable-allobf  依次性啟用上述所有標(biāo)記

-mllvm -enable-strcry是必須的,問題也不大的。如果你的項(xiàng)目很大讳苦,建議不要貪多带膜,加上以后打包會慢,打出來的包先安裝后看一下是不是可以的<否則就白話時(shí)間試這么配置了>鸳谜,你的項(xiàng)目是否可以支持這么多的選項(xiàng)配置膝藕。如果不行的話需要再排查下具體原因了。

四咐扭、其他

其他的就很簡單了芭挽,看你要過的審核具體要求了滑废,大概說幾個(gè)重要的。

4.1 防越獄袜爪、防截屏

SavetyDetectionTool.h

#import <Foundation/Foundation.h>
@interface SavetyDetectionTool : NSObject

+ (instancetype)sharedSavetyDetection;

- (void)detect;
@end

SavetyDetectionTool.m

#import "SavetyDetectionTool.h"
#import <UMMobClick/MobClick.h>
#import <ReplayKit/ReplayKit.h>

static SavetyDetectionTool *savetyDetect = nil;
@implementation SavetyDetectionTool

+ (instancetype)sharedSavetyDetection {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        savetyDetect = [SavetyDetectionTool new];
    });
    return savetyDetect;
}

- (void)detect {
    if ([MobClick isJailbroken]) {
        UIAlertView *aleter = [[UIAlertView alloc] initWithTitle:@"提示" message:@"您的設(shè)配已越獄,請注意保護(hù)隱私安全" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"知道了", nil];
        [aleter show];
    }
  
    //注冊通知
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(userDidTakeScreenshot)
                                                 name:UIApplicationUserDidTakeScreenshotNotification object:nil]; 
    
}
- (void)userDidTakeScreenshot {
    
    UIAlertView *aleter = [[UIAlertView alloc] initWithTitle:@"提示" message:@"監(jiān)測到設(shè)備正在截屏辛馆,請注意安全防護(hù)" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"知道了", nil];
    [aleter show];
}
@end

使用俺陋,AppDelegate.m

[[SavetyDetectionTool sharedSavetyDetection] detect];

4.2 防錄屏

基類UIViewController.m

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:YES];

    // 監(jiān)測當(dāng)前設(shè)備是否處于錄屏狀態(tài)
    UIScreen *screen = [UIScreen mainScreen];
    if (@available(iOS 11.0, *)) {
        if (screen.isCaptured) {
            [self screenshots];
        }
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(screenshots) name:UIScreenCapturedDidChangeNotification object:nil];
    }
}

- (void)screenshots {
    UIAlertView *aleter = [[UIAlertView alloc] initWithTitle:@"提示" message:@"監(jiān)測到設(shè)備正在錄屏,請注意安全防護(hù)" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"知道了", nil];
    [aleter show];
}

- (void)dealloc {
    if (@available(iOS 11.0, *)) {
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIScreenCapturedDidChangeNotification object:nil];
    }
}

4.3 只保留驗(yàn)證碼登錄方式

看審核需求昙篙。

五腊状、總結(jié)

最后有大佬幫忙逆向了下,這次的混淆還是不錯(cuò)的苔可,但愿順利過審缴挖。后面可以再研究下更好的加密方式,但是焚辅,更重要的是我們必須優(yōu)化好我們的項(xiàng)目映屋!

根據(jù)這次的混淆,大概總結(jié)重點(diǎn)注意一下幾點(diǎn):

5.1 統(tǒng)一前綴

組件庫:SEED法焰;

自駕:EHI秧荆;
專車:EHIC
國際租車:EHII埃仪;
出租車:EHIT;

之后改動統(tǒng)一修改乙濒。

5.2 統(tǒng)一類名規(guī)范

UIViewController:以ViewController結(jié)尾;
ViewModel:以ViewModel結(jié)尾(ViewModel 的擴(kuò)展類名稱不用再加EHI)卵蛉;
UIView:以View結(jié)尾颁股;
Model:以Model結(jié)尾;

工具類擴(kuò)展傻丝,除大功能外甘有,主功能用+EHICategory格式。例如:

NSString+EHICategory
NSString+EHIAES

5.3 統(tǒng)一數(shù)據(jù)解析方式

統(tǒng)一使用EHIModel.h葡缰。

5.4 統(tǒng)一圖片加載方式

統(tǒng)一使用EHIWebImage.h亏掀。

5.5 統(tǒng)一目錄結(jié)構(gòu)、第三方的使用

無論是自己寫的泛释,還是第三方放進(jìn)去的滤愕,明確文件的位置,具體參考之前的目錄規(guī)范怜校。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末间影,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子茄茁,更是在濱河造成了極大的恐慌魂贬,老刑警劉巖巩割,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異付燥,居然都是意外死亡宣谈,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進(jìn)店門机蔗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蒲祈,“玉大人,你說我怎么就攤上這事萝嘁“鸬В” “怎么了?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵牙言,是天一觀的道長酸钦。 經(jīng)常有香客問我,道長咱枉,這世上最難降的妖魔是什么卑硫? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮蚕断,結(jié)果婚禮上欢伏,老公的妹妹穿的比我還像新娘。我一直安慰自己亿乳,他們只是感情好硝拧,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著葛假,像睡著了一般障陶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上聊训,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天抱究,我揣著相機(jī)與錄音,去河邊找鬼带斑。 笑死鼓寺,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的勋磕。 我是一名探鬼主播侄刽,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼朋凉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起醋安,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤杂彭,失蹤者是張志新(化名)和其女友劉穎墓毒,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體亲怠,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡所计,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了团秽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片主胧。...
    茶點(diǎn)故事閱讀 38,814評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖习勤,靈堂內(nèi)的尸體忽然破棺而出踪栋,到底是詐尸還是另有隱情,我是刑警寧澤图毕,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布夷都,位于F島的核電站,受9級特大地震影響予颤,放射性物質(zhì)發(fā)生泄漏囤官。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一蛤虐、第九天 我趴在偏房一處隱蔽的房頂上張望党饮。 院中可真熱鬧,春花似錦驳庭、人聲如沸刑顺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽捏检。三九已至,卻和暖如春不皆,著一層夾襖步出監(jiān)牢的瞬間贯城,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工霹娄, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留能犯,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓犬耻,卻偏偏與公主長得像踩晶,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子枕磁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,094評論 1 32
  • 目錄 一、為什么要加固 二茸苇、加固的幾種方法 三排苍、基于念茜如何加固 四、其他人的加固方法 前言 APP加固之代碼混淆...
    dvlproad閱讀 19,341評論 7 42
  • 靜靜的光影里 是靜靜的你 我遙想著許多年前 你的絕代芳華 黃葉飄零落滿地 你的美 如驚鴻一瞥 如妃子的霓裳醉了 天...
    林墨言閱讀 209評論 1 2
  • 約:12:12-26 序論:成為被神大大使用的器皿。蒙受神的大應(yīng)允腻暮。
    EstherD閱讀 307評論 0 0
  • 狼彤守,饑腸轆轆,立于孤峰哭靖,昂頭低嚎具垫;美人,風(fēng)髻露鬢款青,皓膚似玉做修,齒白唇紅,不點(diǎn)而赤抡草,軟玉似削蔥饰及,若隱于香...
    愛化妝的糙漢子閱讀 668評論 0 1