GameBench FPS获取猜想

2017-01-13 15:18:31来源:http://www.jianshu.com/p/e7cf5a1e9b76作者:Hly_Coder人点击

概述

由手机性能评测--3D场景可以知道,要想获取surfaceflinger中的fps值,要么是SHELL权限,要么就是拥有android.Manifest.permission.DUMP权限的应用(系统应用)。但是作为一个三方app,GameBench却可以获得任意程序的fps值,着实让人觉得不明觉厉。以下是运行时的截图,跑的是Unity3d写的demo。



screenshot_u3d.png
分析

因为只有2条路可以拿到fps值,而DUMP权限那条是根本行不通的,因为三方app是不可能有系统签名的何况还是这么多个系统。所以真相应该只有一个,就是通过shell权限那条路拿到的。


进程分析

一个三方app如何能以shell权限运行呢?答案当然是: 不可能
想要获取进程之间的秘密,还是先让我们来看看启动GameBench后,多了哪些进程吧。
在运行GameBench前,使用命令adb shell ps | tee xxx/xxx/before.pid将所有的进程信息保存到before.pid文件中
然后在打开GameBench,并启动我们的Unity3d demo,当fps显示出来后再使用命令adb shell ps | tee xxx/xxx/after.pid保存所有的进程信息
然后使用对比工具BeyondCompare对比前后2支文件,接下来就是见证奇迹的时刻。
除了多了我们的Unity3d进程外,还多了如下的一个进程


shell     9007  1     18652  3992  ffffffff f74bd9ac S /data/local/tmp/gbhelperdaemon

是不是很激动?让我们来看看这个gbhelperdaemon是什么东西


gbhelperdaemon

从名字看,这应该是一个daemon程序,gb就是gamebench的缩写
我们知道它的位置在/data/local/tmp/ 我们先看看它是什么



首先查看权限
ls -l /data/local/tmp/gbhelperdaemon
输出结果如下


-rwxrwxrwx shell    shell       34276 2016-08-23 15:13 gbhelperdaemon

注意:这里是777的权限,并且owner和group都是shell



先使用如下命令将gbhelperdaemon pull出来


adb pull /data/local/tmp/gbhelperdaemon xxx/xxx/

查看它的格式
file xxx/xxx/gbhelperdaemon

输出结果如下
/home/hly/work/gbhelperdaemon: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), 
dynamically linked (uses shared libs), stripped

可以看出这是一个32位的ELF文件
以文本的方式编辑该文件,给出部分重要截图

gb_efl_screenshot.png


gb_efl_screenshot2.png

这里有4个关键的地方已经用红色对话框标示出来。这个ELF文件应该至少会做3件事,首先开启了一个线程,然后使用了socket或者pipe来进行RPC。RPC传递的数据就是使用的dumpsys surfaceflinger --latency
gen.sh
查看/data/local/tmp/目录 ,你还会发现多了一个文件叫做gen.sh,内容很简单
#!/bin/sh
/data/local/tmp/gbhelperdaemon &


推测

综上所述,gamebench的实现原理应该是这么的


首先将gen.sh和gbhelperdaemon push到手机里面
运行gen.sh脚本来启动daemon程序(或者直接启动daemon程序)
daemon程序会一直运行,并且等待其他socket来连接以便发送数据
当我们运行gamebench这个app的时候,app会和daemon程序建立连接
因为gbhelperdaemon 是拥有shell权限的,所以可以使用dumpsys surfaceflinger --latency来获取数据并计算出fps
建立连接后,daemon程序会将获得的数据发送到我们的app端,app再显示出来。
疑问

那gen.sh和gbhelperdaemon是何时被放入到手机里面的呢?
还记得第一次运行gamebench时,(gamebench setup,看视频需翻墙)会提示让你先运行一个gamebench的桌面程序吗?
那个程序应该就是把脚本和elf文件放进了手机里面,并且启动了daemon程序。


验证
杀掉/data/local/tmp/gbhelperdaemon进程
当正常运行gamebench的时候,杀掉gbhelperdaemon进程后,gamebench的fps一直显示为60。所以app是没办法获得fps数据,只能是daemon进程传递过来的
关掉gamebench app直接运行gen.sh,会得到如下结果

sh_gen.png

可以看出来,daemon是一直在等待connection的
杀掉daemon,打开app
当杀掉damon运行app的时候,会让你把手机连接电脑运行gb的一个桌面程序,才能继续运行。
这个时候直接执行
sh /data/local/tmp/gen.sh

开启deamon程序,就可以不用再运行gb的桌面程序,并且会有如下的一些log输出

sh_gen2.png

总结

gamebench的这种工作方式,不仅仅可以拿到fps还能拿到全部shell权限能访问的信息。运行在界面上的app就只是相当于一个外壳,包装的是shell。




最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台