工具名稱用途區(qū)別備注
成都創(chuàng)新互聯(lián)公司主營(yíng)李滄網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,App定制開(kāi)發(fā),李滄h5成都小程序開(kāi)發(fā)搭建,李滄網(wǎng)站營(yíng)銷推廣歡迎李滄等地區(qū)企業(yè)咨詢
theos、iosOpenDev生成dylib
insert_dylib、optool、yololib向二進(jìn)制文件插入dylib
install_name_tool
修改dylib引用路徑
iResign、sigh resign、codesign等重簽名工具修改后的二進(jìn)制文件是需要重簽名的
二、過(guò)程
1、生成dylib
dylib的生成 可采用theos,也可采用iosOpenDev。
theos是越獄專門(mén)開(kāi)發(fā)用的工具,生成的dylib可直接作用于越獄機(jī)器上。
但theos并不是apple源生支持的工具,它在Mac端編譯生成deb包,安裝進(jìn)IOS系統(tǒng),由IOS系統(tǒng)dpkg安裝成插件模式 并隨之生成dylib。theos在Mac端需要調(diào)用IOS開(kāi)發(fā)SDK,目前無(wú)法調(diào)用9.3以上的SDK,theos工具沒(méi)有更新。
iosOpenDev則是apple官方支持的插件生成工具,可直接由Xcode生成。
這種dylib由兩種 CaptainHookTweak、Logos Tweak.
不過(guò)這兩種沒(méi)什么區(qū)別:Logos Tweak的語(yǔ)法較為簡(jiǎn)單 同theos的一致,CaptainHookTweak較為復(fù)雜。
2、插入dylib
這三種工具 均可向二進(jìn)制文件插入dylib 不過(guò)各有千秋
yololib僅能對(duì)64位的二進(jìn)制文件 插入 32位插入也能成功 但是 出現(xiàn)如下
insert_dylib既可以對(duì)64位 也可以對(duì)32位進(jìn)行插入 同時(shí) 還會(huì)供選擇 是否刪除掉二進(jìn)制文件原有的簽名 即 LC_CODE_SIGNATURE
optool 則功能更強(qiáng)大 可供選擇 是插入哪種LC LIB。本例暫用不上。
3、修改dylib引用
插入dylib后 需要對(duì)它添加cydiaSubstrate dylib的引用。即使用install_name_tool這個(gè)工具
之前就是這個(gè)地方?jīng)]有做 導(dǎo)致簽名后的文件 一直安裝出現(xiàn)閃退 dylib也沒(méi)有調(diào)用
由于目前手頭沒(méi)有越獄手機(jī) 之前沒(méi)有調(diào)出過(guò)cydiaSubstrate dylib 所以這個(gè)步驟暫時(shí)中斷(最主要 每個(gè)越獄版本系統(tǒng)的cydiaSubstrate dylib都是不一樣的 目前沒(méi)有可越獄的系統(tǒng) 也就沒(méi)有對(duì)應(yīng)的dylib)
不過(guò) 可細(xì)想 因?yàn)樵姜z手機(jī)上 是自己存在這個(gè)cydiaSubstrate dylib的 所以 theos插件本身不必再導(dǎo)入這個(gè)dylib,直接對(duì)其添加引用即可。
然而 在非越獄手機(jī)上 就需要自己把這個(gè)cydiaSubstrate dylib放進(jìn)app包里 并手頭添加它的引用路徑了
既然這樣 那apple 源生的iosOpenDev為什么還要出開(kāi)發(fā)dylib的工具呢
那是因?yàn)閍pple 推出iosOpenDev生成dylib 根本不是讓你這樣玩的 ?apple是讓你把這個(gè)dylib添加進(jìn)IOS工程里 在工程里對(duì)其添加引用 如果以后該app有少量的更新 只需要更新這個(gè)dylib即可 而不必更新整個(gè)app。這個(gè)在IOS開(kāi)發(fā)中 叫做 增量更新。
在完全不使用cydia提供的hook接口的基礎(chǔ)上 也可以使用openDev使用的hook接口
操作如下:
a:將 dylib(如需要調(diào)用cydia substrate 的 MSHOOK函數(shù) 則 還需要添加cydia substrate dylib)到app包里;
b:insert工具插入。注意這里有一個(gè)坑 就是凡是復(fù)制到dylib里的包 除了使用install_name_tool對(duì)其添加引用外 插入到Mach-O LOAD COMMANDS里的dylib還需要添加可執(zhí)行路徑
首先需要cd進(jìn)app包里
然后/Users/danchen/desktop/diff_hook/insert_dylib@executable_path/ios_hook.dylibhook_demo hook_demo
c:之后重簽名
對(duì)app包里每一個(gè)修改的添加的文件進(jìn)行簽名
codesign -f -s "iPhone Developer: 694708086@qq.com (T4MM3JZDL2)" hook_demo
codesign -f -s "iPhone Developer: 694708086@qq.com (T4MM3JZDL2)" ios_hook.dylib
再對(duì)整個(gè)app包添加簽名權(quán)限
codesign -f -s "iPhone Developer: 694708086@qq.com (T4MM3JZDL2)" --entitlements entitlements.plist hook_demo.app
直接安裝app包即可,也可以使用xcrun將其打包成ipa 安裝即可
dylib里的內(nèi)容
4、重簽名
完成這些步驟后
首先 要對(duì) 修改過(guò)的二進(jìn)制文件、dylib、cydiaSubstrate dylib進(jìn)行重簽名 即把iPhone Developer: 694708086@qq.com (T4MM3JZDL2) 寫(xiě)入進(jìn)去
然后 使用xcrun將app文件 打包成ipa 使用iResign、sigh resign等工具 對(duì)ipa包重簽名 再安裝進(jìn)系統(tǒng)
重簽名權(quán)限文件entitlements.plist
可使用ldid -e 二進(jìn)制文件查看entitlements文件內(nèi)容生成
三、區(qū)別
theos與iosOpenDev
區(qū)別theosiosOpenDev備注
來(lái)源越獄開(kāi)發(fā)作者appletheos來(lái)自第三方開(kāi)發(fā),iosOpenDev則是apple官方Xcode支持的
UI無(wú)Xcodetheos沒(méi)有開(kāi)發(fā)UI界面,iosOpenDev的開(kāi)發(fā)界面是Xcode
版本支持目前theos僅支持SDK IOS9.3以下都支持兩者調(diào)用SDK,theos僅支持SDK9.3以下,目前theos作者尚未更新工具
hook 語(yǔ)言方式Logos TweakLogos Tweak、CaptainHookTweak
insert_dylib、optool、yololib工具差別
區(qū)別insert_dyliboptoolyololib備注
支持結(jié)構(gòu)64、32位都支持64、32位都支持僅支持64位
四、總結(jié)
這種方式僅能hook app自身進(jìn)程里所調(diào)用的函數(shù) 無(wú)法hook系統(tǒng)級(jí)別的進(jìn)程
由于非越獄上的沙盒機(jī)制,本地app僅能訪問(wèn)本app數(shù)據(jù),無(wú)法訪問(wèn)別的app的數(shù)據(jù),訪問(wèn)系統(tǒng)數(shù)據(jù)(相冊(cè)、地理位置等)也需要向用戶請(qǐng)求權(quán)限。更別說(shuō)去hook系統(tǒng)級(jí)別的進(jìn)程。
當(dāng)然 存在非越獄下 繞過(guò)沙盒機(jī)制的技術(shù):
比如這個(gè)人 非越獄下一個(gè)app卸載另一個(gè)app、一個(gè)app獲取領(lǐng)一個(gè)app里的文件內(nèi)容。但這種漏洞技術(shù)沒(méi)有公開(kāi) 僅存在于越獄團(tuán)隊(duì)內(nèi)部。而且這種漏洞技術(shù)也沒(méi)能hook系統(tǒng)級(jí)進(jìn)程。
理論上來(lái)講 非越獄下hook系統(tǒng)級(jí)別的進(jìn)程 是有可能的 只不過(guò)難度相當(dāng)大(換言之 如果真有這種非越獄下就能hook系統(tǒng)級(jí)別的漏洞和技術(shù)的話 越獄團(tuán)隊(duì)干嘛還費(fèi)那大力氣去越獄呢)
iOS逆向 Reveal FLEXLoader 圖層結(jié)構(gòu)
對(duì)于iOS逆向,在我們拿到解密后的可執(zhí)行文件后,我們研究的突破口其實(shí)就是界面的所在信息,畢竟在沒(méi)有任何的針對(duì)信息的情況下,去在Hopper中看可執(zhí)行文件的數(shù)據(jù),無(wú)異于大海撈針。所以這時(shí)候我們需要針對(duì)的信息,需要我們hook的控制器或是類名,這樣接下來(lái)的研究就會(huì)有自己的方向了。
學(xué)iOS的童鞋都知道這個(gè)神器,不管我們?cè)谡蜻€是逆向開(kāi)發(fā)中都可以用到這個(gè)查看圖層信息的工具,當(dāng)然在兩種情況的使用的方法是不一樣的,這兒我主要介紹Reveal在逆向開(kāi)發(fā)中的使用方法。
在用這個(gè)工具的時(shí)候,其實(shí)是踩了很大的坑的。
利用兩種方式的使用Reveal工具,在打開(kāi)需要逆向的APP后,提示The network connection was lost
至于這兩種方式:
打開(kāi)Reveal ,Reveal菜單-Help-Show Reveal Library in Finder -iOS Library
方式一:
注意,這個(gè)plist文件的格式不能出錯(cuò),不然killall SpringBoard命令后出現(xiàn)白蘋(píng)果,至于他們的bundleid ,直接到APP的目錄下看info.plist文件即可。
方式二:
推薦方式
/Library/RHRevealLoader,在手機(jī)的Library下建立RHRevealLoader文件夾,之后把libReveal.dylib放進(jìn)這個(gè)文件夾下。
在手機(jī)中的設(shè)置中找到Reveal-Enabled Applications-你需要的app
之后將mac和iOS設(shè)備中連接同一個(gè)局域網(wǎng)中,打開(kāi)APP后,在Reveal中查看圖層信息
當(dāng)然如果你也出現(xiàn)了Reveal中無(wú)法顯示問(wèn)題時(shí):
解決方法:這個(gè)是你的libReveal.dylib有問(wèn)題,這時(shí)候你需要換一個(gè)
github下的v2.0中的Reveal.dylib地址
這樣將新的libReveal.dylib在手機(jī)中替換原來(lái)的即可,當(dāng)然還有一種可能就是連接的局域網(wǎng)網(wǎng)速太差了。
我們期待的結(jié)果是:
這個(gè)工具是在怎么安裝Reveal都安裝不了的情況下,去了解的一個(gè)可以看圖層的工具,這個(gè)工具和Reveal不同的是不需要連接Mac電腦,只需要在Cydia中安裝并且在設(shè)置中開(kāi)啟需要的查看的圖層的APP。
可以看到這個(gè)工具可以查看APP的文件目錄,整個(gè)APP的視圖構(gòu)架,當(dāng)前視圖的圖層結(jié)構(gòu),當(dāng)然還有很多功能等著你去發(fā)現(xiàn)。
這個(gè)是我們的目標(biāo)視圖的圖層結(jié)構(gòu)。
這樣通過(guò)圖層工具我們就比較快的找到我們需要研究的對(duì)象了。
[img]我們都知道在windows下可以通過(guò)API輕松的hook很多消息,IOS里面貌似還沒(méi)有現(xiàn)成的API(可能是我還沒(méi)發(fā)現(xiàn)吧),前段時(shí)間碰巧看到Objective-C運(yùn)行時(shí)的一些東西,于是心想著是不是可以嘗試一下實(shí)現(xiàn)hook的功能。
下面先直接上源碼:1//2//TestHookObject.m3//TestHookMessage4//5//Created by mapleCao on 13-2-28.6//Copyright (c) 2013年 mapleCao. All rights reserved.7//89#import"TestHookObject.h"10#importobjc/objc.h11#importobjc/runtime.h1213@implementation
TestHookObject1415//this method will just excute once16+ (void)initialize17{18//獲取到UIWindow中sendEvent對(duì)應(yīng)的method19Method sendEvent = class_getInstanceMethod([UIWindowclass
], @selector(sendEvent:));20Method sendEventMySelf = class_getInstanceMethod([selfclass
], @selector(sendEventHooked:));2122//將目標(biāo)函數(shù)的原實(shí)現(xiàn)綁定到sendEventOriginalImplemention方法上23IMP sendEventImp =
method_getImplementation(sendEvent);24class_addMethod([UIWindowclass
], @selector(sendEventOriginal:), sendEventImp, method_getTypeEncoding(sendEvent));2526//然后用我們自己的函數(shù)的實(shí)現(xiàn),替換目標(biāo)函數(shù)對(duì)應(yīng)的實(shí)現(xiàn)27IMP sendEventMySelfImp =
method_getImplementation(sendEventMySelf);28class_replaceMethod([UIWindowclass
], @selector(sendEvent:), sendEventMySelfImp, method_getTypeEncoding(sendEvent));29}3031/*32* 截獲到window的sendEvent33* 我們可以先處理完以后,再繼續(xù)調(diào)用正常處理流程34*/35- (void)sendEventHooked:(UIEvent *)event36{37//do something what ever you want38NSLog(@"haha, this is my self sendEventMethod!!!!!!!");3940//invoke original implemention41[self performSelector:@selector(sendEventOriginal:) withObject:event];42}4344@end下面我們來(lái)逐行分析一下上面的代碼:
首先我們來(lái)看19行,這一行主要目的是獲取到UIWindow原生的sendEvent的
Method(一個(gè)結(jié)構(gòu)體,用來(lái)對(duì)方法進(jìn)行描述)
,接著第20行是獲取到我們自己定義的類中的sendEvent的Method
(這兩個(gè)方法的簽名必須一樣,否則運(yùn)行時(shí)報(bào)錯(cuò))
。第23行我們通過(guò)UIWindow原生的sendEvent的Method獲取到對(duì)應(yīng)的
IMP(一個(gè)函數(shù)指針)
,第24行使用運(yùn)行時(shí)API Class_addMethod給UIWindow類添加了一個(gè)叫sendEventOriginal的方法,該方法使用UIWindow原生的sendEvent的實(shí)現(xiàn),并且有著相同的方法簽名
(必須相同,否則運(yùn)行時(shí)報(bào)錯(cuò))。
27行是獲取我們自定義類中的sendEventMySelf的IMP,28行是關(guān)鍵的一行,這一行的主要目的是為UIWindow原生的sendEvent指定一個(gè)新的實(shí)現(xiàn),我們看到我們將該實(shí)現(xiàn)指定到了我們自己定義的sendEventMySelf上。到了這兒我們就完成了偷梁換柱,大功告成。
執(zhí)行上面這些行以后,我們就成功的將UIWindow的sendEvent重定向到了我們自己的寫(xiě)的sendEventMySelf的實(shí)現(xiàn),然后將其原本的實(shí)現(xiàn)重定向到了我們給它新添加的方法sendEventOriginal中。而sendEventMySelf中,我們首先可以對(duì)這個(gè)消息進(jìn)行我們想要的處理,然后再通過(guò)41行調(diào)用sendEventOriginal方法轉(zhuǎn)到正常的執(zhí)行流程。
為什么執(zhí)行起來(lái)不報(bào)錯(cuò),而且還會(huì)正常執(zhí)行?因?yàn)閟endEventMySelf是UIWindow的sendEvent重定向過(guò)來(lái)的,所以在運(yùn)行時(shí)該方法中的self代表的就是UIWindow的實(shí)例,而不再是TestHookObject的實(shí)例了。加上sendEventOriginal是我們通過(guò)運(yùn)行時(shí)添加到UIWindow的實(shí)例方法,所以可以正常調(diào)用。當(dāng)然如果直接通過(guò)下面這種方式調(diào)用也是可以的,只不過(guò)編譯器會(huì)提示警告
(編譯器沒(méi)那么智能)
,因此我們采用了performSelector的調(diào)用方式。
[self sendEventOriginal:event];以上就是Hook的實(shí)現(xiàn),使用時(shí)我們只需要讓TestHookObject類執(zhí)行一次初始話操作就可以了,執(zhí)行完以后。UIWindow的sendEvent消息就會(huì)會(huì)hook到我們的sendEventMySelf中了。
下面是調(diào)用代碼:
Install Hook
代碼中我們還專門(mén)添加了一個(gè)button來(lái)驗(yàn)證,hook完以后消息是否正常傳遞。經(jīng)驗(yàn)證消息流轉(zhuǎn)完全正常。
阿里妹導(dǎo)讀:剛剛,阿里巴巴正式對(duì)外開(kāi)源了基于 Apache 2.0 協(xié)議的協(xié)程開(kāi)發(fā)框架 coobjc,開(kāi)發(fā)者們可以在 Github 上自主下載。
coobjc是為iOS平臺(tái)打造的開(kāi)源協(xié)程開(kāi)發(fā)框架,支持Objective-C和Swift,同時(shí)提供了cokit庫(kù)為Foundation和UIKit中的部分API提供了 協(xié)程 化支持,本文將為大家詳細(xì)介紹coobjc的設(shè)計(jì)理念及核心優(yōu)勢(shì)。
從2008年第一個(gè)iOS版本發(fā)布至今的11年時(shí)間里,iOS的異步編程方式發(fā)展緩慢。
基于 Block 的異步編程回調(diào)是目前 iOS 使用最廣泛的異步編程方式,iOS 系統(tǒng)提供的 GCD 庫(kù)讓異步開(kāi)發(fā)變得很簡(jiǎn)單方便,但是基于這種編程方式的缺點(diǎn)也有很多,主要有以下幾點(diǎn):
針對(duì)多線程以及尤其引發(fā)的各種崩潰和性能問(wèn)題,我們制定了很多編程規(guī)范、進(jìn)行了各種新人培訓(xùn),嘗試降低問(wèn)題發(fā)生的概率,但是問(wèn)題依然很?chē)?yán)峻,多線程引發(fā)的問(wèn)題占比并沒(méi)有明顯的下降,異步編程本來(lái)就是很復(fù)雜的事情,單靠規(guī)范和培訓(xùn)是難以從根本上解決問(wèn)題的,需要有更加好的編程方式來(lái)解決。
上述問(wèn)題在很多系統(tǒng)和語(yǔ)言開(kāi)發(fā)中都可能會(huì)碰到,解決問(wèn)題的標(biāo)準(zhǔn)方式就是使用協(xié)程,C#、Kotlin、Python、Javascript 等熱門(mén)語(yǔ)言均支持協(xié)程極其相關(guān)語(yǔ)法,使用這些語(yǔ)言的開(kāi)發(fā)者可以很方便的使用協(xié)程及相關(guān)功能進(jìn)行異步編程。
2017 年的 C++ 標(biāo)準(zhǔn)開(kāi)始支持協(xié)程,Swift5 中也包含了協(xié)程相關(guān)的標(biāo)準(zhǔn),從現(xiàn)在的發(fā)展趨勢(shì)看基于協(xié)程的全新的異步編程方式,是我們解決現(xiàn)有異步編程問(wèn)題的有效的方式,但是蘋(píng)果基本已經(jīng)不會(huì)升級(jí) Objective-C 了,因此使用Objective-C的開(kāi)發(fā)者是無(wú)法使用官方的協(xié)程能力的,而最新 Swift 的發(fā)布和推廣也還需要時(shí)日,為了讓廣大iOS開(kāi)發(fā)者能快速享受到協(xié)程帶來(lái)的編程方式上的改變,手機(jī)淘寶架構(gòu)團(tuán)隊(duì)基于長(zhǎng)期對(duì)系統(tǒng)底層庫(kù)和匯編的研究,通過(guò)匯編和C語(yǔ)言實(shí)現(xiàn)了支持 Objective-C 和 Swift 協(xié)程的完美解決方案 —— coobjc。
核心能力
內(nèi)置系統(tǒng)擴(kuò)展庫(kù)
coobjc設(shè)計(jì)
最底層是協(xié)程內(nèi)核,包含了棧切換的管理、協(xié)程調(diào)度器的實(shí)現(xiàn)、協(xié)程間通信channel的實(shí)現(xiàn)等。
中間層是基于協(xié)程的操作符的包裝,目前支持async/await、Generator、Actor等編程模型。
最上層是對(duì)系統(tǒng)庫(kù)的協(xié)程化擴(kuò)展,目前基本上覆蓋了Foundation和UIKit的所有IO和耗時(shí)方法。
核心實(shí)現(xiàn)原理
協(xié)程的核心思想是控制調(diào)用棧的主動(dòng)讓出和恢復(fù)。一般的協(xié)程實(shí)現(xiàn)都會(huì)提供兩個(gè)重要的操作:
我們基于線程的代碼執(zhí)行時(shí)候,是沒(méi)法做出暫停操作的,我們現(xiàn)在要做的事情就是要代碼執(zhí)行能夠暫停,還能夠再恢復(fù)。 基本上代碼執(zhí)行都是一種基于調(diào)用棧的模型,所以如果我們能把當(dāng)前調(diào)用棧上的狀態(tài)都保存下來(lái),然后再能從緩存中恢復(fù),那我們就能夠?qū)崿F(xiàn)yield和 resume。
實(shí)現(xiàn)這樣操作有幾種方法呢?
上述第三種和第四種只是能過(guò)做到跳轉(zhuǎn),但是沒(méi)法保存調(diào)用棧上的狀態(tài),看起來(lái)基本上不能算是實(shí)現(xiàn)了協(xié)程,只能算做做demo,第五種除非官方支持,否則自行改寫(xiě)編譯器通用性很差。而第一種方案的 ucontext 在iOS上是廢棄了的,不能使用。那么我們使用的是第二種方案,自己用匯編模擬一下 ucontext。
模擬ucontext的核心是通過(guò)getContext和setContext實(shí)現(xiàn)保存和恢復(fù)調(diào)用棧。需要熟悉不同CPU架構(gòu)下的調(diào)用約定(Calling Convention). 匯編實(shí)現(xiàn)就是要針對(duì)不同cpu實(shí)現(xiàn)一套,我們目前實(shí)現(xiàn)了 armv7、arm64、i386、x86_64,支持iPhone真機(jī)和模擬器。
說(shuō)了這么多,還是看看代碼吧,我們從一個(gè)簡(jiǎn)單的網(wǎng)絡(luò)請(qǐng)求加載圖片功能來(lái)看看coobjc到底是如何使用的。
下面是最普通的網(wǎng)絡(luò)請(qǐng)求的寫(xiě)法:
下面是使用coobjc庫(kù)協(xié)程化改造后的代碼:
原本需要20行的代碼,通過(guò)coobjc協(xié)程化改造后,減少了一半,整個(gè)代碼邏輯和可讀性都更加好,這就是coobjc強(qiáng)大的能力,能把原本很復(fù)雜的異步代碼,通過(guò)協(xié)程化改造,轉(zhuǎn)變成邏輯簡(jiǎn)潔的順序調(diào)用。
coobjc還有很多其他強(qiáng)大的能力,本文對(duì)于coobjc的實(shí)際使用就不過(guò)多介紹了,感興趣的朋友可以去官方github倉(cāng)庫(kù)自行下載查看。
我們?cè)趇Phone7 iOS11.4.1的設(shè)備上使用協(xié)程和傳統(tǒng)多線程方式分別模擬高并發(fā)讀取數(shù)據(jù)的場(chǎng)景,下面是兩種方式得到的壓測(cè)數(shù)據(jù)。
從上面的表格我們可以看到使用在并發(fā)量很小的場(chǎng)景,由于多線程可以完全使用設(shè)備的計(jì)算核心,因此coobjc總耗時(shí)要比傳統(tǒng)多線程略高,但是由于整體耗時(shí)都很小,因此差異并不明顯,但是隨著并發(fā)量的增大,coobjc的優(yōu)勢(shì)開(kāi)始逐漸體現(xiàn)出來(lái),當(dāng)并發(fā)量超過(guò)1000以后,傳統(tǒng)多線程開(kāi)始出現(xiàn)線程分配異常,而導(dǎo)致很多并發(fā)任務(wù)并沒(méi)有執(zhí)行,因此在上表中顯示的是大于20秒,實(shí)際是任務(wù)已經(jīng)無(wú)法正常執(zhí)行了,但是coobjc仍然可以正常運(yùn)行。
我們?cè)谑謾C(jī)淘寶這種超級(jí)App中嘗試了協(xié)程化改造,針對(duì)部分性能差的頁(yè)面,我們發(fā)現(xiàn)在滑動(dòng)過(guò)程中存在很多主線程IO調(diào)用、數(shù)據(jù)解析,導(dǎo)致幀率下降嚴(yán)重,通過(guò)引入coobjc,在不改變?cè)袠I(yè)務(wù)代碼的基礎(chǔ)上,通過(guò)全局hook部分IO、數(shù)據(jù)解析方法,即可讓原來(lái)在主線程中同步執(zhí)行的IO方法異步執(zhí)行,并且不影響原有的業(yè)務(wù)邏輯,通過(guò)測(cè)試驗(yàn)證,這樣的改造在低端機(jī)(iPhone6及以下的機(jī)器)上的幀率有20%左右的提升。
簡(jiǎn)明
易用
清晰
性能
程序是寫(xiě)來(lái)給人讀的,只會(huì)偶爾讓機(jī)器執(zhí)行一下?!狝belson and Sussman
基于協(xié)程實(shí)現(xiàn)的編程范式能夠幫助開(kāi)發(fā)者編寫(xiě)出更加優(yōu)美、健壯、可讀性更強(qiáng)的代碼。
協(xié)程可以幫助我們?cè)诰帉?xiě)并發(fā)代碼的過(guò)程中減少線程和鎖的使用,提升應(yīng)用的性能和穩(wěn)定性。
本文作者:淘寶技術(shù)
MachO文件。iOS是由蘋(píng)果公司開(kāi)發(fā)的移動(dòng)操作系統(tǒng)。蘋(píng)果公司最早于2007年1月9日的Macworld大會(huì)上公布這個(gè)系統(tǒng),其中逆向hook文件根據(jù)系統(tǒng)默認(rèn)的設(shè)置儲(chǔ)存在MachO文件中。在JS逆向中,通常把替換原函數(shù)的過(guò)程都稱為hook。
- (instancetype)init {
if ([super init]) {
// 使用 Aspects 進(jìn)行方法的攔截
// AspectOptions 三種方式選擇:在原本方法前執(zhí)行、在原本方法后執(zhí)行、替換原本方法
[UIViewController aspect_hookSelector:@selector(viewWillAppear:) withOptions:AspectPositionAfter usingBlock:^(idaspectinfo aspectInfo, BOOL animated){
UIViewController * vc = [aspectInfo instance];
[self viewWillAppear:animated viewController:vc];
} error:NULL];
}
return self;
}/aspectinfo
這只是簡(jiǎn)單攔截原理