iOS逆向之分析微信导航栏实现
Beu4134
8年前
<p>最近需要实现微信的毛玻璃导航栏效果,尝试了各种方式后还是有点差别,这在追求完美的设计师眼里是绝不能忍的,于是只好“看看”原作是怎么实现的。在逆向分析了微信的实现后,发现微信的实现十分特殊,文末会告诉大家答案:)</p> <h3>环境准备</h3> <ul> <li>一台越狱设备</li> <li>OpenSSH 插件</li> <li>Cycript 插件</li> </ul> <p>盘古支持 9.3.3 以下版本的越狱,越狱过程十分快速方便。越狱完成后还要在 Cydia 里搜索安装 OpenSSH 和 Cycript 插件。OpenSSH 用以电脑远程登录 iPhone,Cycript 用来运行时钩住应用程序。Cycript 允许开发者动态查看和修改正在运行的应用程序,更多介绍请查看 <a href="/misc/goto?guid=4959730229637916901" rel="nofollow,noindex">官网</a> 。</p> <p>环境准备完毕后,我们就可以开始逆向了。我手里的是 iOS 9.2.1 版本的越狱设备,以下都是用这个设备进行演示。</p> <p>越狱有风险,建议使用备用机进行越狱,并且越狱前先备份资料</p> <h3>实际操作</h3> <p>首先打开电脑的命令行工具,执行 ssh 远程登录到 iPhone 手机上,默认连接密码是 alpine,建议连上后修改默认密码,修改命令是 passwd ,连上后的界面如下图所示,</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/b44660fc0ae55ed968ec23b35cc96f26.jpg"></p> <p>下面我们可以用 ps 命令查看微信进程,执行</p> <pre> <code class="language-objectivec">ps -e|grepWeChat </code></pre> <p>结果如下图,</p> <p><img src="https://simg.open-open.com/show/72581e47c835407d5179d56fe27a2312.jpg"> 这里我们能够获取到微信的沙盒路径,进入到这个目录后我们能看到如下的内容,主要是一些静态图片资源,如下图:</p> <p><img src="https://simg.open-open.com/show/29dffb541d777342b1a7fe040615189b.jpg"> Cycript</p> <p>前面已经介绍了 Cycript,我们分析导航栏的实现就是需要借助这个工具, <a href="/misc/goto?guid=4959730229637916901" rel="nofollow,noindex">官网</a> 里有更多详细说明。</p> <p>首先在越狱手机上打开微信,然后使用 ps 命令获取到微信的进程id,然后再输入</p> <pre> <code class="language-objectivec">cycript -p xxx </code></pre> <p>当我们看到命令行界面出现 cy# 就说明我们已成功 hook 住微信进程,这个过程如下图所示,</p> <p><img src="https://simg.open-open.com/show/c2bcc2f88bed5f94c2124f9ee2fe3460.jpg"> 上面这张图里的信息很丰富,展示了我是如何一步一步获取到 ContactsViewController 。在最下方我打印出了 UINavigationBar 的视图层级关系,我们能看到控制导航栏样式的视图有两个,一个是view1,一个是view2,其中view2应该是系统自带的毛玻璃效果。</p> <p>为了验证这个想法,我们来做一些设置。首先将 view1 的 alpha 设置为0,结果如下图,</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/c8c82126a363d4953ab703c5c191d8f7.jpg"></p> <p>左边的是 view1.alpha = 0,右边的是原来的样式。我们能看到导航栏的颜色变浅了,页面滑动时的毛玻璃穿透效果很明显。我在自己的 App 里也实现了一样的效果,做法是将 barStyle 设置成 UIBarStyleBlack。</p> <p>打印出微信的导航栏类型属性,发现也是 UIBarStyleBlack</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/aed886b72425b83ef4c00deade2175ac.jpg"></p> <p>至此,我们基本能确定微信就是在系统提供的黑色风格导航栏上做了一些处理。那到底是做了什么处理呢?我们继续往下看。</p> <p>将 view1 的 alpha 还原回去,再将 view2 的 alpha 设置为 0,会看到下图的样式,</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/0bc7fa5caf405c2b16717f86485d5e50.jpg"></p> <p>再把 view2 的实际显示的图层打印出来,发现这是一个渐变图层</p> <p><img src="https://simg.open-open.com/show/f097d3f12480a475377530bec5061f5e.jpg"></p> <p>至此,我们发现微信导航栏的最终显示效果是 <strong>由一个渐变图层加系统提供的黑色毛玻璃组合显示而成。</strong></p> <p>根据这些信息,我在 App 里也用相同的做法尝试了一下,显示效果终于基本一致了,真是泪流满面啊。关键代码如下,</p> <pre> <code class="language-objectivec">- (UIView *)blurBackView { if (_blurBackView == nil) { _blurBackView = [UIViewnew]; _blurBackView.frame = CGRectMake(0, -20, SCREEN_WIDTH, 64); CAGradientLayer *gradientLayer = [[CAGradientLayeralloc] init]; gradientLayer.frame = CGRectMake(0, 0, SCREEN_WIDTH, 64); gradientLayer.colors = @[(__bridgeid)[UIColorcolorWithHex:0x040012 alpha:0.76].CGColor,(__bridgeid)[UIColorcolorWithHex:0x040012 alpha:0.28].CGColor]; gradientLayer.startPoint = CGPointMake(0, 0); gradientLayer.endPoint = CGPointMake(0, 1.0); [_blurBackView.layeraddSublayer:gradientLayer]; _blurBackView.userInteractionEnabled = NO; _blurBackView.alpha = 0.5; } return _blurBackView; } </code></pre> <p>blurBackView 的作用类似上述例子里的 view1,插入到 UINavigationBar 视图里的最下方。</p> <p>Cycript 还能执行一些其他操作,例如弹出 Alert 弹框,</p> <p><img src="https://simg.open-open.com/show/2291d6888051b37fc542033e02696f59.jpg"></p> <p>结果如下</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/8b9111a4ccdd94c4260cd9c6df4e86ae.jpg"></p> <h3>总结</h3> <p>本文整理了我探究微信导航栏实现的过程,发现微信导航栏的最终显示效果是 <strong>由一个渐变图层加系统提供的黑色毛玻璃组合显示而成。</strong></p> <p> </p> <p> </p> <p>来自:http://ios.jobbole.com/91702/</p> <p> </p>