探尋不同版本號的SDK對iOS程序的影響
阿新 • • 發佈:2017-08-08
view order 3.2 一次 ram 替換 pad out 可能
同樣的代碼。使用不同版本號的SDK來編譯。會影響MachO頭中的值, 從而使程序表現出不同的外觀。
代碼都是一樣的。僅僅是使用了不同的SDK進行編譯, 區別詳細在哪裏?
又一次簽名方法:
既然在可運行文件裏。 首先想到的是使用二進制比較工具來看看二者的區別, 結果例如以下圖:
能夠看到區別太大,這樣比較沒什麽意義, 這條路不可行。
既然比較二進制沒什麽意義, 那我們就比較下反匯編代碼, 看看是不是編譯器做了什麽手腳,
能夠看到二者的代碼差點兒一樣, 詳細的一點區別, 也是由不同版本號的編譯器造成的, 邏輯是一樣的。因此不是代碼引起的程序外觀不同。 另外,代碼裏沒有讀什麽全局變量, 說明不是由於UIKit中有什麽默認值被編譯到程序中。 從而引起狀態條的外觀不同。
能夠看到二者的版本確實有區別, 可是兼容版本號都是1.0。 理論上講不是由於這個造成程序區別。 理論是理論,我們如今正在使用排除法確定問題原因, 還是要實打實的驗證。 驗證方法:將APIDiff-SDK61中的UIKit版本改成2903.23.0。 改動方法:這個值在二進制文件裏的偏移為:0x6EC, 須要註意下小端問題。 改動後。又一次簽名。打包安裝到手機上, 發現狀態條沒有發生變化。 因此原因不是UIKit版本的區別。
感覺有可能這就是問題的解決辦法。 進行驗證:改動APIDiff-SDK61。偏移地址0x69C, 將值改為00070000, 又一次簽名,打包安裝到手機, 發現狀態條變成透明了。問題就在這裏。
這樣的區別又是怎樣影響了程序的外觀,可能的原由於:
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程序的影響