一、软件工作原理
- 软件和后台使用API进行交互,在早期版本中API没有鉴权导致可以通过伪造请求来完成跑步,但是后期API迭代了好几个版本,目前认为现在的请求需要间隔一个合理的时间差(跑步时间),而且需要计算一个token用来鉴权,避免了伪造请求。
- 跑步开始和跑步完成时,会记录时间、设备序列号、IMEI等敏感信息,上传服务器。此操作用来记录手机设备唯一性,用来检测频繁换手机,一台设备上登陆不同账号的代跑行为。
- 使用百度地图API,通过GPS和由百度提供的LBS服务进行定位,软件中的配速,通过定位速度来计算。
- 软件中用来评价跑步是否合格的步频,通过加速度传感器和计步器来获取数据。(后期发现计步器部分的代码完全没有发挥作用)
- 软件检测Root但不会影响跑步,目前软件通过检测Xposed Installer来检测Xposed框架,当检测到存在时,会禁止开始跑步。
二、解决方案
Xposed框架操作简单,模块写起来也简单得多,通过Hook系统传感器和GPS就可以达到模拟步频和定位的效果,但是软件目前会检测Xposed,所以需要反编译应用,把检测方法干掉。
三、反编译应用
我前后反编译了软件的两个版本,1.x和2.x功能变化不大,只是UI有一部分变化。通过EDEX对代码进行解包,发现应用套了壳。1.x版本使用360加固,2.x版本使用网易云盾(原网易云加固)对应用进行了加密。
通过查找相关资料,我在看雪论坛发现了一篇文章,文章说的很简略,其实原理很简单,是Dalvik虚拟机模式下基于Android运行时的内存dex文件的dump。
于是通过Hook Android系统的类加载DexClassLoader,获取到了应用真实的dex。然后转换为jar拆包查看需要Hook的函数。通过搜索功能,很容易就能看到检测Xposed框架的方法。
四、编写Xposed模块
主要的目的主要有两个,一个是干掉检测Xposed的代码,另一个是Hook系统加速度传感器的数据,模拟跑步时的数据波动。至于模拟GPS,选择了使用MockLocation的权限来做。
五、主要代码
为了更好地帮助大家更好的自主开发,贴出主要代码
if (loadPackageParam.packageName.equals("com.zjwh.android_wh_physicalfitness")) {
XposedBridge.log("找到目标应用");
XposedHelpers.findAndHookMethod("com.stub.StubApp", loadPac