山寨应用是目前国内Android应用的一大问题,山寨应用主要存在于以下三个场景:
1. 类似于GingerMaster的基于服务器端多态的重新打包的病毒
2. 第三方开发者修改其他正版应用添加广告等
3. Apk破解。
这里所说的山寨应用,大体可以分为两类:
1. Apktool重新打包
2. 假冒应用
目前市面上公开使用的针对这两种山寨应用的检测技术,对重新打包主要采用:
1. App包名、签名等黑白名单对比
2. App包结构比较
而对假冒应用的检测方法就比较乏力,只能主要采用正版审核+盗版申诉的偏人工方法。
本文提到的检测技术是针对“重新打包”的山寨应用。上文提到的针对重新打包的检测方法有两个问题:
1. 滞后性,这是基于文件特征的通病
2. 依赖于对应的正版App,也就是说在库里没有正版App的前提下,基本无法判断某应用是否是重新打包
所以基于这两个限制,国内大部分山寨应用的检测都将检测范围局限在比较流行的应用(如Top 10000)上。
我相信应该能从文件本身出发,寻找出一些正版应用和重新打包的区别。寻找这个区别的入口便是编译过程。
一个正版应用的产生过程:Java->Class->Dex
一个重新打包的应用的产生过程:Smali->Dex
正版应用的编译主要依赖于Android SDK里的dx.jar,而山寨应用的编译则依赖于Apktool.jar和smali.jar
经过对dx.jar和Apktool.jar的分析,发现Apktool在编译过程中大部分逻辑都参考了dx.jar,但是还是被我发现了两个不同点。鉴于公司技术保密,这里就不具体展开细说。
经过测试,结合这两个不同点,可以有90%以上的把握判定某应用是否是Apktool编译生成,这对基于黑白名单的检测技术做了一个很好的补充。
基于编译水印的检测方法存在的一些小问题:
1. 部分正版应用为了Anti反编译,会将自己的App先用Apktool解包,然后加一些Anti tricks,所以最后也是由Apktool编译生成。针对这个问题,需要签名库的帮忙。
2. 不确定该编译水印是否只存在特定版本的Apktool中,所以后续需要持续跟进。
(完)