iOS逆向之分析微信導航欄實現

hi_xgb發表於2016-12-18

最近需要實現微信的毛玻璃導航欄效果,嘗試了各種方式後還是有點差別,這在追求完美的設計師眼裡是絕不能忍的,於是只好“看看”原作是怎麼實現的。在逆向分析了微信的實現後,發現微信的實現十分特殊,文末會告訴大家答案:)

環境準備

  • 一臺越獄裝置
  • OpenSSH 外掛
  • Cycript 外掛

盤古支援 9.3.3 以下版本的越獄,越獄過程十分快速方便。越獄完成後還要在 Cydia 裡搜尋安裝 OpenSSH 和 Cycript 外掛。OpenSSH 用以電腦遠端登入 iPhone,Cycript 用來執行時鉤住應用程式。Cycript 允許開發者動態檢視和修改正在執行的應用程式,更多介紹請檢視官網

環境準備完畢後,我們就可以開始逆向了。我手裡的是 iOS 9.2.1 版本的越獄裝置,以下都是用這個裝置進行演示。

越獄有風險,建議使用備用機進行越獄,並且越獄前先備份資料

實際操作

首先開啟電腦的命令列工具,執行 ssh 遠端登入到 iPhone 手機上,預設連線密碼是 alpine,建議連上後修改預設密碼,修改命令是 passwd,連上後的介面如下圖所示,

iOS逆向之分析微信導航欄實現

下面我們可以用 ps 命令檢視微信程式,執行

ps -e|grep WeChat複製程式碼

結果如下圖,

iOS逆向之分析微信導航欄實現

這裡我們能夠獲取到微信的沙盒路徑,進入到這個目錄後我們能看到如下的內容,主要是一些靜態圖片資源,如下圖:

iOS逆向之分析微信導航欄實現

Cycript

前面已經介紹了 Cycript,我們分析導航欄的實現就是需要藉助這個工具,官網裡有更多詳細說明。

首先在越獄手機上開啟微信,然後使用 ps 命令獲取到微信的程式id,然後再輸入

cycript -p xxx複製程式碼

當我們看到命令列介面出現 cy# 就說明我們已成功 hook 住微信程式,這個過程如下圖所示,

iOS逆向之分析微信導航欄實現

上面這張圖裡的資訊很豐富,展示了我是如何一步一步獲取到 ContactsViewController。在最下方我列印出了UINavigationBar的檢視層級關係,我們能看到控制導航欄樣式的檢視有兩個,一個是view1,一個是view2,其中view2應該是系統自帶的毛玻璃效果。

為了驗證這個想法,我們來做一些設定。首先將 view1 的 alpha 設定為0,結果如下圖,

iOS逆向之分析微信導航欄實現

左邊的是 view1.alpha = 0,右邊的是原來的樣式。我們能看到導航欄的顏色變淺了,頁面滑動時的毛玻璃穿透效果很明顯。我在自己的 App 裡也實現了一樣的效果,做法是將 barStyle 設定成 UIBarStyleBlack。

列印出微信的導航欄型別屬性,發現也是 UIBarStyleBlack

iOS逆向之分析微信導航欄實現

至此,我們基本能確定微信就是在系統提供的黑色風格導航欄上做了一些處理。那到底是做了什麼處理呢?我們繼續往下看。

將 view1 的 alpha 還原回去,再將 view2 的 alpha 設定為 0,會看到下圖的樣式,

iOS逆向之分析微信導航欄實現

再把 view2 的實際顯示的圖層列印出來,發現這是一個漸變圖層

iOS逆向之分析微信導航欄實現

至此,我們發現微信導航欄的最終顯示效果是由一個漸變圖層加系統提供的黑色毛玻璃組合顯示而成。

根據這些資訊,我在 App 裡也用相同的做法嘗試了一下,顯示效果終於基本一致了,真是淚流滿面啊。關鍵程式碼如下,

- (UIView *)blurBackView
{
    if (_blurBackView == nil) {
        _blurBackView = [UIView new];
        _blurBackView.frame = CGRectMake(0, -20, SCREEN_WIDTH, 64);
        CAGradientLayer *gradientLayer = [[CAGradientLayer alloc] init];
        gradientLayer.frame = CGRectMake(0, 0, SCREEN_WIDTH, 64);
        gradientLayer.colors = @[(__bridge id)[UIColor colorWithHex:0x040012 alpha:0.76].CGColor,(__bridge id)[UIColor colorWithHex:0x040012 alpha:0.28].CGColor];
        gradientLayer.startPoint = CGPointMake(0, 0);
        gradientLayer.endPoint = CGPointMake(0, 1.0);
        [_blurBackView.layer addSublayer:gradientLayer];
        _blurBackView.userInteractionEnabled = NO;
        _blurBackView.alpha = 0.5;
    }
    return _blurBackView;
}複製程式碼

blurBackView 的作用類似上述例子裡的 view1,插入到 UINavigationBar 檢視裡的最下方。

Cycript 還能執行一些其他操作,例如彈出 Alert 彈框,

iOS逆向之分析微信導航欄實現

結果如下

iOS逆向之分析微信導航欄實現

總結

本文整理了我探究微信導航欄實現的過程,發現微信導航欄的最終顯示效果是由一個漸變圖層加系統提供的黑色毛玻璃組合顯示而成。如果有其他實現方式也可以給我留言,學習一下~

逆向的用法肯定不止這一種場景,結合 class-dump 還能做更深入的分析。如果感興趣也可以自己實際操作體驗一下,enjoy~

轉載請標註出處,有任何疑問都可聯絡我,歡迎探討。


最後做個推廣,歡迎關注公眾號 MrPeakTech,我從這裡學到很多,推薦給大家,共同進步~

iOS逆向之分析微信導航欄實現

相關文章