1. 程式人生 > >探尋不同版本號的SDK對iOS程序的影響

探尋不同版本號的SDK對iOS程序的影響

view order 3.2 一次 ram 替換 pad out 可能

PDF版本號:http://pan.baidu.com/s/1eQ8DVdo

結論:


同樣的代碼。使用不同版本號的SDK來編譯。會影響MachO頭中的值, 從而使程序表現出不同的外觀。

代碼:

- (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;
}



問題:

如上的代碼很easy,沒有不論什麽功能, 分別使用 xcode v4.6.3 與 v5.0.2 編譯。 然後安裝到iOS8的設備上,表現卻不同, 主要就是iOS6與iOS7之間關於狀態條的區別。例如以下圖: 技術分享__________技術分享
代碼都是一樣的。僅僅是使用了不同的SDK進行編譯, 區別詳細在哪裏?

說明:

xcode版本號:4.6.3 VS 5.0.2
設備:iPhone 5s,iOS 8.0 可運行文件名稱: APIDiff-SDK61表示使用iOS SDK 6.1 編譯出的可運行文件 APIDiff-SDK70表示使用iOS SDK 7.0編譯出的可運行文件 IPA文件名稱: APIDiff-SDK61.ipa表示iOS SDK 6.1編譯出的安裝包 APIDiff-SDK70.ipa表示iOS SDK 7.0編譯出的安裝包

分析:



分析一:確認是可運行程序引起

驗證方法:

APIDiff-SDK70.ipa中的可運行程序替換APIDiff-SDK61.ipa中的可運行程序,

然後使用codesign命令又一次簽名,

打包。安裝到手機上後發現狀態條是透明的。

說明區別確實在可運行程序中。


又一次簽名方法:
codesign -f -s "證書名" --resource-rules Payload/*.app/ResourceRules.plist Payload/*.app



分析二:比較二進制區別


既然在可運行文件裏。 首先想到的是使用二進制比較工具來看看二者的區別, 結果例如以下圖:
技術分享

能夠看到區別太大,這樣比較沒什麽意義, 這條路不可行。

分析三:比較代碼區別


既然比較二進制沒什麽意義, 那我們就比較下反匯編代碼, 看看是不是編譯器做了什麽手腳,
技術分享

能夠看到二者的代碼差點兒一樣, 詳細的一點區別, 也是由不同版本號的編譯器造成的, 邏輯是一樣的。因此不是代碼引起的程序外觀不同。 另外,代碼裏沒有讀什麽全局變量, 說明不是由於UIKit中有什麽默認值被編譯到程序中。 從而引起狀態條的外觀不同。

分析四:比較UIKit版本對程序的影響


既然代碼沒有區別,

我們首先會想到是不是因為UIKit版本號不同而引起的程序外觀不同。

盡管程序是動態鏈接的UIKit,

而且設備上僅僅有一個版本號的UIKit庫,

可是我們還是要驗證下。

首先確定二者的區別。例如以下圖:
技術分享


能夠看到二者的版本確實有區別, 可是兼容版本號都是1.0。 理論上講不是由於這個造成程序區別。 理論是理論,我們如今正在使用排除法確定問題原因, 還是要實打實的驗證。

驗證方法:將APIDiff-SDK61中的UIKit版本改成2903.23.0。 改動方法:這個值在二進制文件裏的偏移為:0x6EC, 須要註意下小端問題。 改動後。又一次簽名。打包安裝到手機上, 發現狀態條沒有發生變化。 因此原因不是UIKit版本的區別。

分析五:使用MachOView逐項比較


走到這裏。多少有點兒黔驢技窮了。

問題就在那裏而我們卻找不到原因。

那就上最原始的工具:體力勞動,使用MachOView一項一項的對照。

從"__LINKEDIT"

--->"LC_DYLD_INFO_ONLY"

--->"LC_LOAD_DYLINKER"

--->"LC_VERSION_MIN_IPHONEOS"

"LC_VERSION_MIN_IPHONEOS"中發現了一個保留值的區別:
技術分享

感覺有可能這就是問題的解決辦法。 進行驗證:改動APIDiff-SDK61。偏移地址0x69C, 將值改為00070000, 又一次簽名,打包安裝到手機, 發現狀態條變成透明了。問題就在這裏。

TODO:這樣的區別又是怎樣影響了程序的外觀


這樣的區別又是怎樣影響了程序的外觀,可能的原由於:

1、UIKit中會讀這個屬性。

可能性極小。UIKit僅僅是一個庫,

而如上的區別會首先被載入器獲得,

離UIKit還非常遠。


2、SpringBoard及其相關服務。

可能性大。

①:SpringBoard幾其服務本身就有畫圖的職責;

②:點擊桌面上的圖標,程序是由SpringBoard啟動的。



只是不打算繼續驗證了。到這裏已經滿足了我的探知欲,欲望更強的兄弟能夠繼續分析。^_^


探尋不同版本號的SDK對iOS程序的影響