探尋不同版本的SDK對iOS程序的影響
來源:程序員人生 發(fā)布時間:2014-10-19 08:00:00 閱讀次數(shù):2125次
PDF版本:http://pan.baidu.com/s/1eQ8DVdo
結(jié)論:
相同的代碼,使用不同版本的SDK來編譯,會影響MachO頭中的值,
從而使程序表現(xiàn)出不同的外觀。
代碼:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIScreen *mainScreen = [UIScreen mainScreen];
CGRect frm = [mainScreen bounds];
UIWindow *win = [[UIWindow alloc] initWithFrame:frm];
win.backgroundColor = [UIColor blueColor];
self.window = win;
[win release];
[self.window makeKeyAndVisible];
return YES;
}
問題:
如上的代碼非常簡單,沒有任何功能,
分別使用 xcode v4.6.3 與 v5.0.2 編譯,
然后安裝到iOS8的設(shè)備上,表現(xiàn)卻不同,
主要就是iOS6與iOS7之間關(guān)于狀態(tài)條的差別,如下圖:
__________
代碼都是一樣的,只是使用了不同的SDK進(jìn)行編譯,
差別具體在哪里?
說明:
xcode版本:4.6.3 VS 5.0.2
設(shè)備:iPhone 5s,iOS 8.0
可執(zhí)行文件名:
APIDiff-SDK61表示使用iOS SDK 6.1 編譯出的可執(zhí)行文件
APIDiff-SDK70表示使用iOS SDK 7.0編譯出的可執(zhí)行文件
IPA文件名:
APIDiff-SDK61.ipa表示iOS SDK 6.1編譯出的安裝包
APIDiff-SDK70.ipa表示iOS SDK 7.0編譯出的安裝包
分析:
分析一:確認(rèn)是可執(zhí)行程序引起
驗證方法:
用APIDiff-SDK70.ipa中的可執(zhí)行程序替換APIDiff-SDK61.ipa中的可執(zhí)行程序,
然后使用codesign命令重新簽名,
打包,安裝到手機(jī)上后發(fā)現(xiàn)狀態(tài)條是透明的,
說明差別確實在可執(zhí)行程序中。
重新簽名方法:
codesign -f -s "證書名" --resource-rules Payload/*.app/ResourceRules.plist Payload/*.app
分析二:比較二進(jìn)制差別
既然在可執(zhí)行文件中,
首先想到的是使用二進(jìn)制比較工具來看看二者的差別,
結(jié)果如下圖:
可以看到差別太大,這樣比較沒什么意義,
這條路不可行。
分析三:比較代碼差別
既然比較二進(jìn)制沒什么意義,
那我們就比較下反匯編代碼,
看看是不是編譯器做了什么手腳,
可以看到二者的代碼幾乎一樣,
具體的一點差別,
也是由不同版本的編譯器造成的,
邏輯是一樣的,因此不是代碼引起的程序外觀不同。
另外,代碼里沒有讀什么全局變量,
說明不是因為UIKit中有什么默認(rèn)值被編譯到程序中,
從而引起狀態(tài)條的外觀不同。
分析四:比較UIKit版本號對程序的影響
既然代碼沒有差別,
我們首先會想到是不是由于UIKit版本不同而引起的程序外觀不同。
雖然程序是動態(tài)鏈接的UIKit,
并且設(shè)備上只有一個版本的UIKit庫,
但是我們還是要驗證下。
首先確定二者的差別,如下圖:
可以看到二者的版本號確實有差別,
但是兼容版本都是1.0,
理論上講不是因為這個造成程序差別。
理論是理論,我們現(xiàn)在正在使用排除法確定問題原因,
還是要實打?qū)嵉尿炞C。
驗證方法:將APIDiff-SDK61中的UIKit版本號改成2903.23.0。
修改方法:這個值在二進(jìn)制文件中的偏移為:0x6EC,
需要注意下小端問題。
修改后,重新簽名,打包安裝到手機(jī)上,
發(fā)現(xiàn)狀態(tài)條沒有發(fā)生變化,
因此原因不是UIKit版本號的差別。
分析五:使用MachOView逐項比較
走到這里,多少有點兒黔驢技窮了,
問題就在那里而我們卻找不到原因。
那就上最原始的工具:體力勞動,使用MachOView一項一項的對比。
從"__LINKEDIT"
--->"LC_DYLD_INFO_ONLY"
--->"LC_LOAD_DYLINKER"
--->"LC_VERSION_MIN_IPHONEOS"
在"LC_VERSION_MIN_IPHONEOS"中發(fā)現(xiàn)了一個保留值的差別:
感覺有可能這就是問題的原因,
進(jìn)行驗證:修改APIDiff-SDK61,偏移地址0x69C,
將值改為00070000,
重新簽名,打包安裝到手機(jī),
發(fā)現(xiàn)狀態(tài)條變成透明了,問題就在這里!
TODO:這種差別又是如何影響了程序的外觀
這種差別又是如何影響了程序的外觀,可能的原因為:
1、UIKit中會讀這個屬性。
可能性極小,UIKit只是一個庫,
而如上的差別會首先被加載器獲得,
離UIKit還很遠(yuǎn)。
2、SpringBoard及其相關(guān)服務(wù)。
可能性大,
①:SpringBoard幾其服務(wù)本身就有繪圖的職責(zé);
②:點擊桌面上的圖標(biāo),程序是由SpringBoard啟動的。
不過不打算繼續(xù)驗證了,到這里已經(jīng)滿足了我的探知欲,欲望更強的兄弟可以繼續(xù)分析。^_^
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈