iOS 應用加固方法

前提

眾所周知,iOS系統安全性非常高,很少出現漏洞,幾乎不會中毒。大家認為蘋果系統的封閉性會使iOS APP安全性比較高,但是實際上iOS應用本身被破解的難度并不高,一旦在越獄設備上,ipa被分析就會變得很容易。對于iOS開發者來說,有必要了解一些APP加固的方法,用以提高破解的難度,特別是針對一些金融、游戲類APP的開發。

iOS代碼保護

在大多數iOS應用中,一些工具,比如Clutch,class-dump,cycript,lldb,theos.對應用程序的結構,代碼邏輯,運行流程,可以做到很容易的分析。然后進行應用的破解,篡改,重簽名??梢詮哪嫦蚍治龅姆绞阶龃a保護的思路:

  • 1.靜態分析:針對這種情況可以把字符串加密,類名方法名混淆,代碼混淆
  • 2.調試 :反調試
  • 3.注入 :反注入
  • 4.中間人攻擊 :https, 證書驗證, 數據加密

一,靜態分析

靜態分析是指用工具對程序結構,代碼邏輯的分析。很大程度上取決關鍵字,通過關鍵字找到敏感代碼,進行破解。所以靜態分析的防護主要是代碼混淆。

1,混淆硬編碼的明文字符串

明文字符串可直接在二進制包搜索到,常常是作為逆向分析的切入口,隱藏明文字符串可有效提升靜態分析的難度。在源代碼中將字符串加密,運行時先解密在使用,如果直接在代碼中寫加密后字符串,代碼的可讀性會變得非常差。網上又一個方法不是很優雅,但有效,私以為不錯:

  • 將源代碼中的字符串通過函數宏手動標記
  • 打包的時候拷貝源代碼副本
  • 執行腳本,將副本代碼中所有標記過的字符串,替換成decrypt("密文")的形式
  • 在適當的位置,插入decrypt函數的實現(或者事先在源代碼中寫好)
  • 編譯

通過函數宏手動標記字符串:


執行加密腳本后:


這里的加密僅僅是和0xAA做了一個簡單的異或運算,解密函數內聯編譯到代碼中。

上圖是未做混淆前的反匯編代碼,可以直接看到明文字符串。
下面是經過混淆的反匯編代碼,已經看不到明文字符串了。

2,objective C代碼混淆

網上方法較多,其中尤以念茜大神的方法為佳。大抵是在編譯前執行混淆腳本,對OC函數(消息)進行混淆。但是又不能全部混淆,有一些是SDK的代理回掉,如tableView的UITableViewDataSource,混淆后將不會調用,如繼承子類的init,混淆后也不會調用。解決辦法有很多,這里介紹兩個匹配的辦法:

  • 1,建立一個索引文件,將需要混淆的函數寫入索引文件,混淆腳本讀取索引文件的函數名進行匹配。
  • 2,在代碼中以前綴或后綴的方式標識需要混淆的函數,混淆腳本通過這些標識進行自動混淆。

匹配函數名后,將混淆過的函數寫入數據庫中記錄下來,以便在后續在分析app Crash的時候找對應的函數,快速定位到對應的問題代碼.
未做混淆的代碼經過class-dump或者直接在hopper中可直接看到函數名,逆向者以此猜測程序功能,快速切入,找到hock點。



混淆腳本設置

混淆后的代碼,無法通過函數名猜測到程序功能,可大大增加逆向難度。

代碼混淆除了函數名的混淆,還有類名,協議名,文件名的混淆等。此外,敏感代碼可以用C函數來實現,可以避免在class-dump等工具中倒出,但是在nm等工具中還是可以看到一些符號表的信息。

小結,靜態分析的防護手段主要是作代碼的混淆,已到達提升逆向的難度。此外還有代碼邏輯的混淆,通過在代碼中加入大量無用的邏輯判斷,增加程序結構的復雜性,以此提升程序在ida,hopper等工具分析中的難度。但是此方法對源代碼的改動性較大,使代碼的可讀性變得極差。

二,動態分析 反調試

逆向者不僅可以靜態分析程序,也可以通過debugserver,lldb等工具動態分析程序,通過在程序中打斷點,修改內存中的變量等方式分析,改變程序的行為。以此達到分析,hock程序的目的。

1,反調試之 ptrace

談到debug,首先會想到的一個系統調用是ptrace,它主要用于實現斷點調試和系統調用跟蹤。 PT_DENY_ATTACH是蘋果增加的一個ptrace選項,用以防止gdb等調試器依附到某進程。代碼如下:

#ifndef PT_DENY_ATTACH
#define PT_DENY_ATTACH 31
#endif

typedef int (*ptrace_ptr_t)(int _request, pid_t _pid, caddr_t _addr, int _data);

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];


    void *handle = dlopen(0, RTLD_GLOBAL | RTLD_NOW);
    ptrace_ptr_t ptrace_ptr = (ptrace_ptr_t)dlsym(handle, "ptrace");
    ptrace_ptr(PT_DENY_ATTACH, 0, 0, 0);

}

手邊沒有越獄機器,直接通過xcode debug,應用會Crash掉,安裝到手機后可正常打開。
針對這種ptrace的反反調試方法其實很簡單,通過下斷點,然后修改ptrace的參數或者用hook函數去掉反調試保護就可以搞定。也可在程序多個處調用來增加crash,提高逆向難度。

2,反調試之 sysctl

思路是通過sysctl查看信息進程里的標記,判斷自己是否正在被調試。sysctl是用以查詢內核狀態的接口,并允許具備相應權限的進程設置內核狀態。其定義如下:

 int sysctl(int *name, u_int namelen, void *old, size_t *oldlen, void *newp, size_t newlen);
 name參數是一個用以指定查詢的信息數組;
 namelen用以指定name數組的元素個數;
 old是用以函數返回的緩沖區;
 oldlen用以指定oldp緩沖區長度;
 newp和newlen在設置時使用;
    當進程被調試器依附時,kinfo_proc結構下有一個kp_proc結構域,kp_proc的p_flag的被調試標識將被設置,即會進行類似如下的設置:
    kinfo_proc. kp_proc. p_flag & P_TRACED
   其中P_TRACED的定義如下:
   #define P_TRACED        0x00000800  /* Debugged process being traced */

我們可以通過sysctl查詢進程相應的kinfo_proc信息,查詢函數的實現可以這樣:

static int is_debugged() __attribute__((always_inline));

@implementation ViewController


- (void)viewDidLoad {
    [super viewDidLoad];

    if (is_debugged() == YES) {
        self.label.text = @"is_debugged ";
        exit(-1);
    }else{
        self.label.text = @"not is_debugged";
    }

}

static int is_debugged(){
    int name[4] = {CTL_KERN,KERN_PROC,KERN_PROC_PID,getpid()};
    struct kinfo_proc Kproc;
    size_t kproc_size = sizeof(Kproc);
    
    memset((void*)&Kproc, 0, kproc_size);
    
    if (sysctl(name, 4, &Kproc, &kproc_size, NULL, 0) == -1) {
        perror("sysctl error \n ");
        exit(-1);
    }
    
    return (Kproc.kp_proc.p_flag & P_TRACED) ? 1 : 0;
}

針對sysctl的反反調試的思路其實很簡單,只需要在函數返回時清除p_flag標識位即可,根據sysctl.h文件中的定義:

#define CTL_KERN    1
#define KERN_PROC 14
#define KERN_PROC_PID 1

以及sysctl的第二個參數為4,對sysctl下條件斷點,在sysctl返回后,根據反編譯二進制文件找到kproc的首地址,接下來找到p_flag相對kproc首地址的偏移,最后修改對應內存地址的值就OK了。

文中混淆腳本 以及Dome地址

動態分析的防護還有很多,如:dylib注入檢測,越獄檢測等。當然,也有相應的反反調試手段,且許多檢測方法涉及到iOS的私有API,存在一定的上架風險。

三,總結

總體來說,iOS系統安全性是很高的,且大多數iOS應用都沒做混淆,反調試等。對于金融類,游戲類的應用防護套路來一點還是能增加逆向破解的難度的。當然,要完全防止程序被調試或者被逆向,理論上來說是不可能的。

參考文章

iOS App的加固保護原理 http://www.cocoachina.com/ios/20170324/18955.html
iOS代碼混淆 http://xelz.info/blog/2016/11/20/ios-code-obfuscation/
阿里 iOS Anti-Debug https://jaq.alibaba.com/blog.htm?id=53
關于反調試&反反調試那些事 http://bbs.iosre.com/t/topic/8179
看雪論壇 iOS加固淺談之字符串加密 http://bbs.pediy.com/thread-217991.htm

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,739評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,634評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,653評論 0 377
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,063評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,835評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,235評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,315評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,459評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,000評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,819評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,004評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,560評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,257評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,676評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,937評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,717評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,003評論 2 374

推薦閱讀更多精彩內容