iOS應(yīng)用程序的脫殼實(shí)現(xiàn)原理淺析

應(yīng)用程序加載過程

對于諸多逆向愛好者來說钠惩,給一個(gè)app脫殼是一項(xiàng)必做的事情揣炕。基于安全性的考慮稠腊,蘋果對上架到appstore的應(yīng)用都會進(jìn)行加密處理,所以如果直接逆向一個(gè)從appstore下載的應(yīng)用程序時(shí)鸣哀,所能看到的“源代碼”將非常的晦澀難懂架忌。為了能看懂應(yīng)用程序的“源代碼”,就必須對應(yīng)用程序進(jìn)行解密我衬,也就是所謂的脫殼叹放。脫殼后的目的是可以分析應(yīng)用程序的一些技術(shù)實(shí)現(xiàn)原理,或者利用一些漏洞進(jìn)行攻擊和測試挠羔。

這篇文章不是一篇介紹如何利用工具去進(jìn)行脫殼的教程井仰,而只是簡單的分析這些常用脫殼工具的實(shí)現(xiàn)原理。要想了解脫殼原理破加,就要先去了解一個(gè)被加密的應(yīng)用程序是如何被運(yùn)行的俱恶。下面一張圖片簡單的介紹了一個(gè)被加殼后的應(yīng)用程序被加載和運(yùn)行的過程:

程序脫殼過程

脫殼原理以及常見的工具

要對一個(gè)殼應(yīng)用進(jìn)行脫殼處理,無非就是采用靜態(tài)脫殼動(dòng)態(tài)脫殼兩種方法:靜態(tài)脫殼就是在已經(jīng)掌握和了解到了殼應(yīng)用的加密算法和邏輯后在不運(yùn)行殼應(yīng)用程序的前提下將殼應(yīng)用程序進(jìn)行解密處理范舀。靜態(tài)脫殼的方法難度大合是,而且加密方發(fā)現(xiàn)應(yīng)用被破解后就可能會改用更加高級和復(fù)雜的加密技術(shù);動(dòng)態(tài)脫殼就是從運(yùn)行在進(jìn)程內(nèi)存空間中的可執(zhí)行程序映像(image)入手锭环,來將內(nèi)存中的內(nèi)容進(jìn)行轉(zhuǎn)儲(dump)處理來實(shí)現(xiàn)脫殼處理聪全。這種方法實(shí)現(xiàn)起來相對簡單,且不必關(guān)心使用的是何種加密技術(shù)辅辩。從上面的殼應(yīng)用程序運(yùn)行的過程就可以看出無論殼程序如何被加密處理难礼,最終運(yùn)行后在進(jìn)程中的代碼映像(image)始終是被解密后的原始程序二進(jìn)制。所以只要一個(gè)進(jìn)程內(nèi)存空間中的代碼映像(image)能被讀取和訪問就可以實(shí)現(xiàn)動(dòng)態(tài)脫殼玫锋。下面要介紹的兩個(gè)工具就是巧妙的運(yùn)用了兩種不同的訪問技巧來實(shí)現(xiàn)動(dòng)態(tài)脫殼的蛾茉。

一、利用動(dòng)態(tài)庫注入來實(shí)現(xiàn)脫殼的dumpdecrypted/frida-ios-dump

dumpdecrypted和frida-ios-dump都是在github上開源的項(xiàng)目景醇,下載地址分別為:https://github.com/stefanesser/dumpdecryptedhttps://github.com/AloneMonkey/frida-ios-dump臀稚。關(guān)于使用這兩個(gè)工具來進(jìn)行脫殼的文檔非常之多。我們知道一個(gè)應(yīng)用除了有一個(gè)可執(zhí)行程序外三痰,還會鏈接非常多的動(dòng)態(tài)庫吧寺。動(dòng)態(tài)庫加載后和可執(zhí)行程序共享相同的進(jìn)程內(nèi)存空間窜管,而且動(dòng)態(tài)庫中的代碼是可以訪問整個(gè)進(jìn)程內(nèi)存空間中的有權(quán)限的區(qū)域的,包括可執(zhí)行程序的image被加載到進(jìn)程中的內(nèi)存區(qū)域稚机。因此只要想辦法讓應(yīng)用程序加載某個(gè)特定的第三方動(dòng)態(tài)庫幕帆,也就是讓這個(gè)第三方動(dòng)態(tài)庫注入到應(yīng)用程序的進(jìn)程中去就可以實(shí)現(xiàn)將被解密過后的可執(zhí)行程序在進(jìn)程內(nèi)存中的image信息轉(zhuǎn)儲到文件中去從而實(shí)現(xiàn)脫殼處理。對于一個(gè)越獄后的設(shè)備來說主要可以通過兩種方法來實(shí)現(xiàn)第三方動(dòng)態(tài)庫的注入:

  1. 設(shè)置環(huán)境變量DYLD_INSERT_LIBRARIES的值指向這個(gè)第三方動(dòng)態(tài)庫的路徑赖条。然后運(yùn)行要脫殼的應(yīng)用程序即可失乾。 DYLD_INSERT_LIBRARIES環(huán)境變量的設(shè)置是一個(gè)操作系統(tǒng)提供的特性,所有運(yùn)行的程序都會加載這個(gè)環(huán)境變量中所指向的動(dòng)態(tài)庫文件纬乍。

  2. 將第三方動(dòng)態(tài)庫文件保存在越獄設(shè)備的/Library/MobileSubstrate/DynamicLibraries/目錄下并編寫對應(yīng)的庫的同名plist文件碱茁,所有plist中指定的可執(zhí)行程序一旦運(yùn)行就會加載對應(yīng)的動(dòng)態(tài)庫(此目錄即Tweak插件所在的目錄)。

還有一種直接修改對應(yīng)mach-o格式的可執(zhí)行文件內(nèi)容來實(shí)現(xiàn)動(dòng)態(tài)庫注入仿贬。

動(dòng)態(tài)庫加載的問題解決后就需要解決動(dòng)態(tài)庫中代碼運(yùn)行的時(shí)機(jī)問題了纽竣。要想讓一個(gè)被加載的動(dòng)態(tài)庫在加載后自動(dòng)運(yùn)行某一段代碼可以有四種方法:

  1. 建立一個(gè)C++全局對象,并在對象所屬類的構(gòu)造函數(shù)中添加特定代碼茧泪。

  2. 建立一個(gè)OC類蜓氨,并在OC類的+load方法中添加特定的代碼。

  3. 生成動(dòng)態(tài)庫時(shí)指定一個(gè)初始化init入口函數(shù)队伟,并在入口函數(shù)中添加特定的代碼穴吹。

  4. 在動(dòng)態(tài)庫中定義一個(gè)帶有_attribute_((constructor))聲明的函數(shù),并在函數(shù)內(nèi)添加特定的代碼嗜侮。

如果你想更進(jìn)一步的了解上述那些方法的加載的原理港令,請參考我的文章:深入解構(gòu)iOS系統(tǒng)下的全局對象和初始化函數(shù)

dumpdecrypted這個(gè)工具就是通過建立一個(gè)名為dumpdecrypted.dylib的動(dòng)態(tài)庫并在庫內(nèi)部定義了一個(gè)

__attribute__((constructor))
void dumptofile(int argc, const char **argv, const char **envp, const char **apple, struct ProgramVars *pvars)

函數(shù)來實(shí)現(xiàn)脫殼的。這個(gè)函數(shù)的大體實(shí)現(xiàn)會在后面繼續(xù)介紹棘钞。

二缠借、利用父子進(jìn)程關(guān)系來實(shí)現(xiàn)脫殼的Clutch

Clutch也是一個(gè)在github上開源的項(xiàng)目,下載地址為:https://github.com/KJCracks/Clutch宜猜。關(guān)于這個(gè)工具的使用教程也非常之多泼返。我們知道在unix系列的操作系統(tǒng)中父進(jìn)程可以通過fork或者posix_spawnp兩個(gè)函數(shù)來運(yùn)行或者建立一個(gè)子進(jìn)程的,這兩個(gè)函數(shù)都會返回對應(yīng)的子進(jìn)程ID(PID)姨拥。iOS系統(tǒng)則可以通過task_for_pid函數(shù)來從進(jìn)程ID獲取進(jìn)程在mach內(nèi)核子系統(tǒng)中的mach port標(biāo)識绅喉。得到mach port 標(biāo)識后,就可以借助mach_vm_read_overwrite函數(shù)來讀取指定進(jìn)程空間中的任意虛擬內(nèi)存區(qū)域中所存儲的內(nèi)容叫乌。因此Clutch內(nèi)部的實(shí)現(xiàn)就是Clutch這個(gè)程序?qū)⒁M(jìn)行脫殼的程序文件路徑調(diào)用posix_spawnp函數(shù)來運(yùn)行從而成為其子進(jìn)程柴罐,然后借助task_for_pid以及mach_vm_read_overwrite函數(shù)來讀取脫殼程序子進(jìn)程在內(nèi)存中已經(jīng)被解密后的可執(zhí)行程序的image所映射的內(nèi)存空間來達(dá)到脫殼的目的的。

一個(gè)思考:可能在實(shí)際中并不一定要求是父子進(jìn)程關(guān)系憨奸,是否只要某個(gè)具有特權(quán)的程序或者運(yùn)行在root用戶上的程序只要拿到了對應(yīng)進(jìn)程的PID就可以通過mach子系統(tǒng)提供的API來讀取其他進(jìn)程內(nèi)存空間中的信息呢革屠?

上述的兩種方法中不管是dumpdecrypted還是Clutch最終都是將被解密后的可執(zhí)行程序的image在內(nèi)存中的映射寫入到一個(gè)文件中去來保存脫殼后的內(nèi)容。參考dumpdecrypted中的dumptofile函數(shù)實(shí)現(xiàn)以及Clutch中的Dumpers目錄下的實(shí)現(xiàn)代碼就可以看出:一個(gè)可執(zhí)行程序image在內(nèi)存中映射的內(nèi)容的結(jié)構(gòu)和mach-o格式的可執(zhí)行文件結(jié)構(gòu)基本上是保持一致的。都是有一個(gè)mach_header結(jié)構(gòu)體頭還有諸多的load_command結(jié)構(gòu)體組成似芝。因此所謂的dump處理就是將內(nèi)存中的這些結(jié)構(gòu)和數(shù)據(jù)原封不動(dòng)的寫入到文件中去即完成了脫殼中的最核心的部分那婉。如果想仔細(xì)的閱讀這部分代碼的實(shí)現(xiàn),建議先了解一下mach-o文件格式的組成党瓮。

后記

當(dāng)你了解了這些內(nèi)部實(shí)現(xiàn)后详炬,也許你會發(fā)覺其實(shí)它的原理很簡單。而且有可能你也能很快的去實(shí)現(xiàn)寞奸∏好眨可問題的關(guān)鍵是為什么這些方法總是別人能想到,而我們卻想不到呢枪萄?這是否和國人的思維以及解決問題的方式相關(guān)呢隐岛?在我們的教育和實(shí)踐體系中更多的是拿來主義和實(shí)用主義,往往很少人會對問題進(jìn)行深入的探索研究以及進(jìn)行問題的關(guān)聯(lián)性思考瓷翻。但愿這種情況在未來能夠得到改進(jìn)礼仗,尤其作為一個(gè)程序員,更加應(yīng)該秉持探索求知的強(qiáng)烈意愿而不是簡單復(fù)制和應(yīng)用就滿足了逻悠。

最后還是要感謝《iOS應(yīng)用逆向與安全》的作者:劉培慶。向他咨詢了逆向相關(guān)的一些知識后才得以寫出這篇文章韭脊。并推薦逆向的愛好者閱讀這本書童谒。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市沪羔,隨后出現(xiàn)的幾起案子饥伊,更是在濱河造成了極大的恐慌,老刑警劉巖蔫饰,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件琅豆,死亡現(xiàn)場離奇詭異,居然都是意外死亡篓吁,警方通過查閱死者的電腦和手機(jī)茫因,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來杖剪,“玉大人冻押,你說我怎么就攤上這事∈⒑伲” “怎么了洛巢?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長次兆。 經(jīng)常有香客問我稿茉,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任漓库,我火速辦了婚禮恃慧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘米苹。我一直安慰自己糕伐,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布蘸嘶。 她就那樣靜靜地躺著良瞧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪训唱。 梳的紋絲不亂的頭發(fā)上褥蚯,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機(jī)與錄音况增,去河邊找鬼赞庶。 笑死,一個(gè)胖子當(dāng)著我的面吹牛澳骤,可吹牛的內(nèi)容都是我干的歧强。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼为肮,長吁一口氣:“原來是場噩夢啊……” “哼摊册!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起颊艳,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤茅特,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后棋枕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體白修,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年重斑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了兵睛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,834評論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡窥浪,死狀恐怖卤恳,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情寒矿,我是刑警寧澤突琳,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站符相,受9級特大地震影響拆融,放射性物質(zhì)發(fā)生泄漏蠢琳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一镜豹、第九天 我趴在偏房一處隱蔽的房頂上張望傲须。 院中可真熱鬧,春花似錦趟脂、人聲如沸泰讽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽已卸。三九已至,卻和暖如春硼一,著一層夾襖步出監(jiān)牢的瞬間累澡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工般贼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留愧哟,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓哼蛆,卻偏偏與公主長得像蕊梧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子腮介,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評論 2 354

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

  • 2016年國慶假期終于把此書過完萤厅,整理筆記和體會于此。 關(guān)于書名 書名源于俄羅斯的演員斯坦尼斯拉夫斯基創(chuàng)作的《演員...
    李劍飛的簡書閱讀 7,241評論 2 65
  • ios 逆向工程 剛進(jìn)一個(gè)新公司靴迫,公司的大牛直接分給一個(gè)課題研究任務(wù)惕味,直接懵逼了,/(ㄒoㄒ)/~~ 想哭玉锌,世界就...
    天下林子閱讀 29,615評論 39 120
  • 一名挥、溫故而知新 1. 內(nèi)存不夠怎么辦 內(nèi)存簡單分配策略的問題地址空間不隔離內(nèi)存使用效率低程序運(yùn)行的地址不確定 關(guān)于...
    SeanCST閱讀 7,808評論 0 27
  • 如果你看完書中的所有例子,你很可能已經(jīng)做完你的實(shí)驗(yàn)和在已經(jīng)越獄的iPhone上的研究主守。因?yàn)楹驮S多人一樣禀倔,幾乎所有的...
    fishmai0閱讀 15,999評論 2 42
  • 事隔多年,突然想寫些東西了参淫,現(xiàn)在的地點(diǎn)卻是海南三亞的天涯海角救湖。 我本是來賣自拍桿的,可是因?yàn)樽约旱难燮るp了好多層突...
    獨(dú)眼貓閱讀 310評論 0 0