iOS動態(tài)庫探究

靜態(tài)分析可執(zhí)行文件的frameworks

通過以下命令可以查看需要鏈接的動態(tài)庫:

?  ~ otool -L /path/to/YourApp.app/YourApp
/path/to/YourApp.app/YourApp:
    /System/Library/Frameworks/CallKit.framework/CallKit (compatibility version 1.0.0, current version 1.0.0)
    /System/Library/Frameworks/Social.framework/Social (compatibility version 1.0.0, current version 87.0.0)
    /System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 1349.55.0)
    /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
    /usr/lib/libSystem.dylib (compatibility version 1.0.0, current version 1238.50.2)
    /System/Library/Frameworks/UIKit.framework/UIKit (compatibility version 1.0.0, current version 3600.7.47)

注意這兩個目錄:/System/Library/Frameworks/usr/lib/轨香。
通過以下命令查看可執(zhí)行文件的所有load command

?  ~ otool -l /path/to/YourApp.app/YourApp
...
(內容太多潭苞,省去一部分)
Load command 12
          cmd LC_LOAD_WEAK_DYLIB
      cmdsize 80
         name /System/Library/Frameworks/CallKit.framework/CallKit (offset 24)
   time stamp 2 Thu Jan  1 08:00:02 1970
      current version 1.0.0
compatibility version 1.0.0
Load command 13
          cmd LC_LOAD_DYLIB
      cmdsize 80
         name /System/Library/Frameworks/Social.framework/Social (offset 24)
   time stamp 2 Thu Jan  1 08:00:02 1970
      current version 87.0.0
compatibility version 1.0.0

注意到,LC_LOAD_WEAK_DYLIB對應的是optional framework谋竖,LC_LOAD_DYLIB對應的是required framework

修改load command

其實MacOS已經提供了修改load command的工具叫install_name_tool

install_name_tool \
-change /System/Library/Frameworks/CallKit.framework/CallKit /System/Library/Frameworks/NotificationCenter.framework/NotificationCenter \
/path/to/YourApp.app/YourApp

# 用otool來驗證修改成功與否
?  ~ otool -L /path/to/YourApp.app/YourApp
/path/to/YourApp.app/YourApp:
    /System/Library/Frameworks/NotificationCenter.framework/NotificationCenter (compatibility version 1.0.0, current version 1.0.0)
    /System/Library/Frameworks/Social.framework/Social (compatibility version 1.0.0, current version 87.0.0)
    /System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 1349.55.0)
    /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
    /usr/lib/libSystem.dylib (compatibility version 1.0.0, current version 1238.50.2)
    /System/Library/Frameworks/UIKit.framework/UIKit (compatibility version 1.0.0, current version 3600.7.47)

運行時加載動態(tài)庫

添加這樣一個命令到你的~/.lldbinit文件中:
command regex ls 's/(.+)/po @import Foundation; [[NSFileManager defaultManager] contentsOfDirectoryAtPath:@"%1" error:nil]/'
如果你的lldb已經運行,重新加載init文件:
(lldb) command source ~/.lldbinit
體驗下這個命令:

(lldb) image list -d UIKit
[  0] /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks/UIKit.framework
(lldb) ls /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks/
<__NSArrayM 0x610000240270>(
Accelerate.framework,
Accounts.framework,
AddressBook.framework,
AddressBookUI.framework,
AdSupport.framework,
...(此處省略內容)
WatchKit.framework,
WebKit.framework
)

根據列出的framework范咨,嘗試加載Speechframework進來到app的進程空間:

(lldb) process load /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks/Speech.framework/Speech
Loading "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks/Speech.framework/Speech"...ok
Image 0 loaded.

其實很有更酷的刹碾。dyld如果找不到framework會搜索一些目錄燥撞,你不需要指定framework的完整路徑:
(lldb) process load MessageUI.framework/MessageUI
完美!

探索frameworks

逆向的一個基礎是探索動態(tài)庫迷帜。雖然一個動態(tài)庫被編譯成一個位置不相關position independent的可執(zhí)行文件物舒,即使編譯器將debugging symbols去除了你,仍然可以獲取到關于這個動態(tài)庫的大量的信息戏锹。二進制需要位置不相關的代碼是因為當dyld完成它的事情后冠胯,編譯器并不知道代碼會存在內存的哪個位置。

清楚的了解一個應用如何和一個framework交互景用,同樣也會幫助你探究app是如何工作的涵叮。舉個栗子,如果一個stripped了的app(即去除了調試信息)使用了一個UITableView伞插,我們可以在UIKit的特定方法里設置斷點來判斷哪些代碼是與UITableViewDataSource相關的割粮。

添加這樣一個命令到你的~/.lldbinit文件中:
command regex dump_stuff "s/(.+)/image lookup -rn '\+\[\w+(\(\w+\))?\ \w+\]$' %1 /"
它接受一個或多個framework作為輸入,導出所有的沒有參數的oc方法(類方法)
可以嘗試一下:

(lldb) dump_stuff Social
71 matches found in /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks/Social.framework/Social:
        Address: Social[0x00000000000019a4] (Social.__TEXT.__text + 0)
        Summary: Social`+[SLInternalComposeServiceHostContext _extensionAuxiliaryVendorProtocol]        Address: Social[0x0000000000001a10] (Social.__TEXT.__text + 108)
        Summary: Social`+[SLInternalComposeServiceHostContext _extensionAuxiliaryHostProtocol]        Address: Social[0x0000000000001b97] (Social.__TEXT.__text + 499)
        Summary: Social`+[SLInternalComposeServiceVendorContext _extensionAuxiliaryVendorProtocol]        Address: Social[0x0000000000001c03] (Social.__TEXT.__text + 607)
        Summary: Social`+[SLInternalComposeServiceVendorContext _extensionAuxiliaryHostProtocol]        Address: Social[0x0000000000005f85] (Social.__TEXT.__text + 17889)
        Summary: Social`+[SLService allServices]        Address: Social[0x000000000000c4b4] (Social.__TEXT.__text + 43792)
        Summary: Social`+[SLWeiboSession _remoteInterface]        Address: Social[0x000000000000c804] (Social.__TEXT.__text + 44640)
        Summary: Social`+[SLWeiboUserRecord supportsSecureCoding]        Address: Social[0x000000000000c9dc] (Social.__TEXT.__text + 45112)
        Summary: Social`+[SLWeiboServerInterface consumerSecret]        Address: Social[0x000000000000cacf] (Social.__TEXT.__text + 45355)
        Summary: Social`+[SLWeiboServerInterface consumerKey]        Address: Social[0x00000000000106db] (Social.__TEXT.__text + 60727)
        Summary: Social`+[SLFacebookAlbumChooserViewController _blankSurrogateAlbumImage]        Address: Social[0x000000000001685c] (Social.__TEXT.__text + 85688)
        Summary: Social`+[SLComposeViewController _serviceTypeToExtensionIdentifierMap]        Address: Social[0x00000000000174c3] (Social.__TEXT.__text + 88863)
        Summary: Social`+[SLComposeViewController _isMultiUserDevice]        Address: Social[0x000000000001f56c] (Social.__TEXT.__text + 121800)
        Summary: Social`+[SLPlace supportsSecureCoding]        Address: Social[0x000000000002de4c] (Social.__TEXT.__text + 181416)
        ...(此處省略)

這里還有一些有用的工具命令:

# 導出繼承NSObject的實例的所有ivars
command regex ivars 's/(.+)/expression -lobjc -O -- [%1 _ivarDescription]/'
# 導出出繼承NSObject的實例媚污,或NSObject類的所有方法
command regex methods 's/(.+)/expression -lobjc -O -- [%1 _shortMethodDescription]/'
# 遞歸導出繼承NSObject的類的實例的所有方法
command regex lmethods 's/(.+)/expression -lobjc -O -- [%1 _methodDescription]/'

舉個例子舀瓢,你可能需要研究SLFacebookUpload的實例:

(lldb) ivars [SLFacebookUpload new]
<SLFacebookUpload: 0x60000005ddc0>:
in SLFacebookUpload:
    _uploadID (NSString*): nil
    _uploadType (long): 0
    _totalBytes (unsigned long): 0
    _transferredBytes (unsigned long): 0
in NSObject:
    isa (Class): SLFacebookUpload (isa, 0x10612b058)

又或者你可能對這個類實現了哪些方法比較好奇:

(lldb) methods SLFacebookUpload
<SLFacebookUpload: 0x10612b058>:
in SLFacebookUpload:
    Class Methods:
        + (BOOL) supportsSecureCoding; (0x1060b001a)
    Properties:
        @property (retain, nonatomic) NSString* uploadID;  (@synthesize uploadID = _uploadID;)
        @property (nonatomic) long uploadType;  (@synthesize uploadType = _uploadType;)
        @property (nonatomic) unsigned long totalBytes;  (@synthesize totalBytes = _totalBytes;)
        @property (nonatomic) unsigned long transferredBytes;  (@synthesize transferredBytes = _transferredBytes;)
    Instance Methods:
        - (id) uploadID; (0x1060b0022)
        - (void) setUploadID:(id)arg1; (0x1060b0033)
        - (long) uploadType; (0x1060b0047)
        - (void) setUploadType:(long)arg1; (0x1060b0058)
        - (unsigned long) transferredBytes; (0x1060b008b)
        - (void) setTransferredBytes:(unsigned long)arg1; (0x1060b009c)
        - (void) .cxx_destruct; (0x1060b00ad)
        - (void) encodeWithCoder:(id)arg1; (0x1060aff5e)
        - (id) initWithCoder:(id)arg1; (0x1060afe6b)
        - (unsigned long) totalBytes; (0x1060b0069)
        - (void) setTotalBytes:(unsigned long)arg1; (0x1060b007a)
(NSObject ...)

或者獲取這個類和所有父類的所有方法:

lldb) lmethods SLFacebookUpload
<SLFacebookUpload: 0x10612b058>:
in SLFacebookUpload:
    Class Methods:
        + (BOOL) supportsSecureCoding; (0x1060b001a)
    Properties:
        @property (retain, nonatomic) NSString* uploadID;  (@synthesize uploadID = _uploadID;)
        @property (nonatomic) long uploadType;  (@synthesize uploadType = _uploadType;)
        @property (nonatomic) unsigned long totalBytes;  (@synthesize totalBytes = _totalBytes;)
        @property (nonatomic) unsigned long transferredBytes;  (@synthesize transferredBytes = _transferredBytes;)
    Instance Methods:
        - (id) uploadID; (0x1060b0022)
        - (void) setUploadID:(id)arg1; (0x1060b0033)
        - (long) uploadType; (0x1060b0047)
        - (void) setUploadType:(long)arg1; (0x1060b0058)
        - (unsigned long) transferredBytes; (0x1060b008b)
        - (void) setTransferredBytes:(unsigned long)arg1; (0x1060b009c)
        - (void) .cxx_destruct; (0x1060b00ad)
        - (void) encodeWithCoder:(id)arg1; (0x1060aff5e)
        - (id) initWithCoder:(id)arg1; (0x1060afe6b)
        - (unsigned long) totalBytes; (0x1060b0069)
        - (void) setTotalBytes:(unsigned long)arg1; (0x1060b007a)
in NSObject:
    Class Methods:
      ...
    Instance Methods:
      ...

在真機上加載framework

真機上這個過程沒有什么不一樣,唯一區(qū)別是System/Library的位置不一樣耗美。

如果你在模擬器上運行京髓,公開Frameworks目錄在這個地方:

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks/

但注意到上文中我們用otool -L得到的信息是路徑應該是/System/Library/Frameworks航缀。這到底神馬情況?

情況是堰怨,dyld會在一些目錄中查找framework芥玉。對應模擬器有一個dyld_sim
所以备图,這個是在iOS設備上framework所在的正確路徑灿巧。如果你運行在真機上,frameworks們將會在/System/Library/Frameworks/揽涮。
這是有人或許會說抠藕,"不是有沙盒限制么?"

ios內核對不同目錄有著不同的限制。在iOS 10或更早的版本上蒋困,/System/Library目錄對于你的進程是可讀的盾似!這是合理的,因為你的進程在它的進程空間內需要調用一些公開或私有的framework雪标。如果沙盒機制限制了這些目錄的讀取零院,那么app就不能夠加載他們導致啟動失敗。

來嘗試一下:

(lldb) ls /
<__NSArrayM 0x17024ca20>(
.file,
.mb,
Applications,
Developer,
Library,
System,
bin,
cores,
dev,
etc,
private,
sbin,
tmp,
usr,
var
)

(lldb) ls /System/Library/
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末汰聋,一起剝皮案震驚了整個濱河市门粪,隨后出現的幾起案子,更是在濱河造成了極大的恐慌烹困,老刑警劉巖玄妈,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異髓梅,居然都是意外死亡拟蜻,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進店門枯饿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來酝锅,“玉大人,你說我怎么就攤上這事奢方∩Ρ猓” “怎么了?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵蟋字,是天一觀的道長稿蹲。 經常有香客問我,道長鹊奖,這世上最難降的妖魔是什么苛聘? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上设哗,老公的妹妹穿的比我還像新娘唱捣。我一直安慰自己,他們只是感情好网梢,可當我...
    茶點故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布震缭。 她就那樣靜靜地躺著,像睡著了一般澎粟。 火紅的嫁衣襯著肌膚如雪蛀序。 梳的紋絲不亂的頭發(fā)上欢瞪,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天活烙,我揣著相機與錄音,去河邊找鬼遣鼓。 笑死啸盏,一個胖子當著我的面吹牛,可吹牛的內容都是我干的骑祟。 我是一名探鬼主播回懦,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼次企!你這毒婦竟也來了怯晕?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤缸棵,失蹤者是張志新(化名)和其女友劉穎舟茶,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體堵第,經...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡吧凉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了踏志。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片阀捅。...
    茶點故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖针余,靈堂內的尸體忽然破棺而出饲鄙,到底是詐尸還是另有隱情,我是刑警寧澤圆雁,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布忍级,位于F島的核電站,受9級特大地震影響摸柄,放射性物質發(fā)生泄漏颤练。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望嗦玖。 院中可真熱鬧患雇,春花似錦、人聲如沸宇挫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽器瘪。三九已至翠储,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間橡疼,已是汗流浹背援所。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留欣除,地道東北人住拭。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像历帚,于是被迫代替她去往敵國和親滔岳。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,585評論 2 359

推薦閱讀更多精彩內容

  • [轉]淺談LLDB調試器文章來源于:http://www.cocoachina.com/ios/20150126/...
    loveobjc閱讀 2,517評論 2 6
  • 僅以方便自己查閱記錄前言1.靜態(tài)庫和動態(tài)庫有什么異同挽牢?靜態(tài)庫:鏈接時完整地拷貝至可執(zhí)行文件中谱煤,被多次使用就有多份冗...
    190CM閱讀 4,227評論 0 4
  • two Last login: Tue Aug 4 17:09:57 on ttys000 yushengyang...
    aofeilin閱讀 1,042評論 1 9
  • 靜態(tài)庫與動態(tài)庫的區(qū)別 首先來看什么是庫刘离,庫(Library)說白了就是一段編譯好的二進制代碼,加上頭文件就可以供別...
    吃瓜群眾呀閱讀 11,970評論 3 42
  • 隨著Xcode 5的發(fā)布奏赘,LLDB調試器已經取代了GDB寥闪,成為了Xcode工程中默認的調試器。它與LLVM編譯器一...
    隨風飄蕩的小逗逼閱讀 1,406評論 0 0