《51测试天地》—腾讯TMQ移动测试方法集锦
 
   
牛刀小试-Xposed在测试中的小应用
 
  首页 1 尾页
 

  一、开端:
  作为测试人员,想必多有遇到过这样的情景:跟开发G沟通测试发现的问题,尤其是性能问题,有时会被质疑证据不充分--"产品模块那么多,凭啥说是我这块引起的?"。这不,前不久本宝宝就遇到了这么一例:被测产品引入了第三方的SDK,出于对产品的负责,开发G向我们提出了测试需求--评测引入SDK对原产品性能的影响。对比测试发现,引入SDK后,产品Wifi扫描的频次和时长明显增加。这意味着,产品的电量消耗将大幅增长(Wifi扫描、GPS定位等硬件相关的模块,耗起电来,还是蛮吓人的)。跟开发G说明情况后,开发G快速拉了SDK的接口人(简称"Y童鞋",即外部童鞋),一起来定位这个Bug
  本以为证据确凿--引入了SDK才增长的,那不就是SDK的问题嘛!可Y童鞋坚持:SDK的逻辑中不可能有那么多Wifi扫描;自测也没发现SDK有问题;再说了,你们产品本身也有Wifi扫描,凭啥说多出来的一定是SDK中的?唇枪舌战十多个来回,也没能把问题扯清楚。不过,倒是受了Y童鞋的启发--"凭啥说多出来的一定是SDK中的"--若是能把Wifi扫描的代码触发路径找到,到底是谁家的,不就一清二楚,铁证如山了?那,如何寻求证据呢?
  求证思路:
  Android Wifi扫描需调用到系统的android.net.wifi.WifiManager.startScan()方法。通过劫持该方法,在方法被调时打印其调用关系,即可知道最初的调用是在哪块代码。说到方法劫持,就该Xposed出手了。
  二、Xposed简介:
  Xposed是一个针对Android平台的方法劫持开源项目(链接:https://github.com/rovo89/XposedBridge/wiki/Development-tutorial)。它的强大之处在于可以hook方法的调用,改变系统和应用的行为,而不需要对APKs做任何修改。如果是通过反编译APK来修改应用,可以在反编译后代码的任何地方插入或修改内容,但是需要重新编译APK并签名,并且改变仅针对单个APK包。使用Xposed的hook,虽不能改变方法内部的代码(因为在方法内部难以寻址和定义改变的内容),但可以在被hook的方法调用前后注入自己的代码(方法是java中的最小单元,方便寻址)。其基本思路及原理为:
  Android中每个应用进程启动时都由Zygote进程复制(fork)而来,获取Zygote进程的Dalvik虚拟机实例拷贝,并与Zygote共享java运行时库。
  Zygote进程在手机开机时由/init.rc脚本启动,执行/system/bin/app_process(一个二进制文件,负责加载所需类,并触发相关的初始化方法)后进程启动完成,如下:
   
  Xposed的切入点就在app_process:安装Xposed框架后,一个扩展了的app_process文件会替换原有文件,添加额外的XposedBridge.jar到classpath中。这样,通过Zygote复制而来的应用进程也都加载了XposedBridge.jar。
  XposedBridge.jar:位于/data/data/de.robv.android.xposed.installer/bin/目录下。其中的XposedBridge类的main方法在进程启动时会被调用。一些初始化的工作和Xposed模块的加载都在该main方法中执行。
  XposedBridge类的hookMethodNative()方法可以将目标方法(被Hook的方法)的type属性改为"native"(native方法的调用将跳转至方法的地址去执行),并将方法的地址链接到自定义的native通用方法。也就是说,每次目标方法被调用时,都会转而调用自定的通用方法。在自定义的方法中,XposedBridge类的handleHookedMethod()方法被调用,该方法将参数和"this reference"传递给目标方法,并执行已注册的回调函数。回调函数中可以改变传递给目标方法的参数、实例、静态变量,触发其他方法,改变目标方法返回的结果...或者直接跳过--非常灵活。
  简图如下:
   
  关于Xposed的更多信息,可参考:
  "Android Hook Xposed原理与源码分析":
  http://blog.csdn.net/wxyyxc1992/article/details/17320911
  "Xposed开发教程":
  https://github.com/rovo89/XposedBridge/wiki/Development-tutorial
  三、Xposed牛刀小试:
  寻求证据的过程,也即Xposed的使用过程。在Dalvik环境下,Xposed的使用资源包含两大块:Xposed installer和Xposed module。两者都是app的形式。Xposed.installer.apk提供固有的框架,完成app_process的替换、classpath的修改,并提供UI来进行框架、模块的管理和日志的查看。Xposed module为自定义的hook模块,指定需要Hook的方法以及Hook到方法后相应的操作。
  1、Xposed使用步骤
  1)安装xposed.installer.apk;
  2)开发并安装Xposed module;
  3)加载并激活module(by reboot) ;
  4)操作被测应用,即可看到hook到的日志信息。日志路径为/data/data/de.robv.android.xposed.installer/log/error.log。
  2、Xposed module开发
  Xposed module和普通app的差别在于,其AndroidManifest.xml有几个特殊的meta data标签,并且有一个特殊的配置文件xposed_init,用来使Xposed框架识别module。使用Eclipse开发Xposed module,步骤如下:
  Step1、新建android project
  Step2、编辑AndroidManifest.xml
  在AndroidManifest.xml文件中添加3个meta data 节点, (name,value)分别为:(xposedmodule,true)、(xposeddescription,(module的简单描述,自定义))、(xposedminversion,(所使用的XposedBridge.jar的版本))。示例如下:
  Step3、导入XposedBridgeApi.jar
  因为需要使用XposedBridge中的API,所以下载XposedBridgeApi-<version>.jar并将其加入到Build Path。(note: 确保编译APK时,该jar包只是referenced,而不是included,否则会报IllegalAccessError。工程的libs文件夹下的文件编译时默认included,所以不要将该jar包放在libs文件夹,而是放到lib文件夹下。)
  Step4、coding
  Xposed module有几个不同的入口点,可以根据自己的需求,在Android系统启动、apk包加载、或apk资源初始化的时候使用Xposed Hook方法。所有的入口点都是扩展了IXposedMod接口的子接口,分别为:
  IXposedHookZygoteInit
  IXposedHookLoadPackage
  IXposedHookInitPackageResources
  自定义的module模块中,实现上述几个接口中的一个,静态导入de.robv.android.xposed.XposedHelpers.findAndHookMethod方法,hook目标方法,并Override相关的方法,即可。
  3、Xposed使用实例--Wifi扫描的Hook:
  前面说过,Android Wifi扫描需调用到系统的android.net.wifi.WifiManager.startScan()方法。函数原型如下:
......
(下载专刊即可查看全文)
  本文收录于《测试专刊-腾讯TMQ移动测试方法集锦》。
  版权声明:本文出自《测试专刊-腾讯TMQ移动测试方法集锦》。51Testing软件测试网及相关内容提供者腾讯TMQ团队拥有内容的全部版权,未经明确的书面许可,任何人或单位不得对本网站内容复制、转载或进行镜像,否则将追究法律责任。

 
1  
 

 

51Testing软件测试网 | 快捷面板 | 站点地图 | 联系我们 | 广告服务 |

建议使用IE 5.0以上浏览器,800×600以上分辨率,法律顾问:上海瀛东律师事务所 张楠律师
版权所有 上海博为峰软件技术有限公司 Copyright@51testing.com 2003-2016, 沪ICP备05003035号
投诉及意见反馈:webmaster@51testing.com   业务联系:service@51testing.com  021-64471599-8017