背景
模块常用app升级了,开始收费了,用户不干了跳起来了。要求悲剧的猿给解决,于是一个又一个坑。
苦思冥想
历史经验,屏蔽升级无非以下几种情况:
1.屏蔽升级接口,网络检测不到升级就没法升了呗;
2.改版本号,版本号高于目标升级版本号,看你还升级;
3.最后最无奈的一招,屏蔽升级弹出框。
方法1.有两种方案,改hosts或者改iptables,视情况而定。前提条件必须用root权限。
如果是屏蔽整个域名或ip请求,hosts和iptables都可以,当然改hosts最简单。这种情况适合升级接口是单独域名的。echo adb测试 adb push ./hosts /system/etc/hosts
当然如果是屏蔽一个url请求,就只能iptables了。
adb shell iptables -I OUTPUT -p tcp -m string --string "升级接口唯一性字符串" --algo bm -j DROP
PS:这个屏蔽URL请求用处很多啊
方法2.也是有好几种方案,改apk版本号(整包反编译和xml修改),改系统方法获取的版本号,改http请求的版本号。
改aok版本号,这种方案有个弊端,必须重新签名,会导致用户手上的app不能直接升级。整个反编译apk,改apk版本号再重新编译。这种方法有个弊端,如果apk加固过的没法反编译。找找apktools.jar就知道怎么玩,我没用这种方法,网上教程一堆,就不赘述了。
另外一个简单粗暴,耿直高效啊。直接将apk后缀改为zip,取出AndroidManifest.xml。然后用UltraEdit二进制方式打开,找到版本号直接编辑最高位为9。然后把改后的AndroidManifest.xml替换zip包的文件,将zip后缀又改为apk,重新签名即可。即使是加固包也没问题!
要从系统层改改版本号,需要从固件上改,/data/system/package.xml把对应包名的version版本号改大。由于这个文件每次重启都会重新读取,因此需要固件上做控制,差评。
改http请求上传的版本号,hook改吧,也是底层的东西。或者so库实现。
方法3.爱折腾你就去折腾吧!
动手
思路清晰了,当然是动手了。
1.看表现。app升级不是强生,不升级app继续正常服务。(PS:强升,不升不给用就别挣扎了。)
2.既然兼容升级,好嘛分析升级接口(其实我们是尽量不动原生app的)。结果尼玛是http多段mutilate格式的上传格式请求,还是一个请求多层业务校验。升级和业务域名也是同一个。好嘛屏蔽接口宣告此路不通。
3.剩下一条路改版本号,从系统层面改得不偿失,还是该apk吧。于是拿包分析,反编译发现有加固。得,只有一条路了,改AndroidManifest.xml中的版本号。
后记
前后半个小时,搞定收工。至于线上用户升级不兼容问题,挖个坑留着固件的兄弟解决了。