混淆
众所周知安卓是Java的一个分支,默认情况下Java编译时都会将变量名、方法名都信息全部包含进去,安卓也是同样
与编译型语言(可以)将符号信息全部舍弃,完全依赖地址区分变量不同,解释型语言通常将信息和变量绑定使用,因此无法丢弃符号信息
代码混淆
编译型语言例如C语言,可以在编译时加上去除符号表和重定位信息的选项来减小生成文件的体积,对应的也会使反编译困难许多
解释型语言虽然不能完全去除,但也可以通过重命名,例如使用a, b, c等又短又易重复的变量名来减小生成文件的体积,同样也会使反编译困难许多
甚至可以使用非printable字符作为名称,只要能彼此对应即可
资源混淆
除了变量名、方法名,也可以将resource中的各个资源名重命名为简短而复杂的字符,使得搜索起来极为困难
但由于资源使用时大多通过ID,因此作用见仁见智吧
这方面有微信团队的开源工具
除了增加逆向困难度以外,同样也可以减小生成文件的体积
签名保护
Android中的每个应用都有一个唯一的签名
通常情况下,应用未经签名是不允许安装的
(非通常情况下指的就是安卓作为开源系统可以随意修改23333存在技术人员魔改系统绕过签名验证的可能)
签名的初衷是标识开发者,经常会有一些第三方下载了官方的APK后加入广告甚至去掉付费信息然后重打包发布,从而获取甚至拦截开发者的收入
签名机制下,当新安装的APK与手机内旧的APK包名相同但签名不同时会无法安装(而签名相同时则会作为升级处理)
另一方面,APK内可以通过方法取得签名,来进行自校验对抗重打包。
如果签名不符合,就拒绝执行程序。
然而自校验终究也是代码,重打包时也是可以Patch它的。
因此直白的自校验几乎没有什么作用,为了对抗反编译,开发人员会将它藏在native中、与SMC结合起来使用、签名作为数据使用等等