看雪论坛作者ID:血舞长空
本文讨论的重打包,是指“破解版”,运行环境受(普通用户的手机)限制,毕竟你不能要求用户魔改刷机root才能使用“破解版”。另:没有永远的安全,全看cracker的水平有多高。
不管怎样,可以确定的是签名和其中的某些文件会被修改。那么防止重打包的主要目标就是检测这些修改。
在保护之前,先来说说cracker可能会干的几件事:
3、内存补丁。如果方法2不行,那就不脱壳了,根据程序逻辑,可以直接加载自己编写的so打内存补丁跳过检测。
4、hook。这可能是最近几年用得最多的方案了。上面所有方法试了不行(或者懒得试了),就要走上hook这条路了。
2、针对脱壳。上文就说了,很多壳脱出来直接打包是不行的,也有些壳是脱不了的,比如java转c(保护java代码),vmp(保护so),加壳之后原指令彻底消失不见,也就不存在脱壳的说法了。
3、针对内存补丁。这个方法其实很冷门,因为内存补丁对逆向要求较高,有能力读懂ollvm和加壳后的so的逻辑的,基本很难阻止他做事了。
4、针对hook:作为最热门的方法,有必要单独拎出来多说几句。
a)检测hook。方法太多了,各种hook都有或多或少的特征,要注意的是,会有诸如《通过hook绕过hook检测》之类的文章……今天你hook我,明天我检测你,后天你跳过我的检测,大后天我检测你跳过我的检测……对抗永无止境。
b)不被hook。怎样不被hook?自己写函数。用java代码来举个例子,有一个bytes数据要计算它的md5,最简单的MessageDigest.getInstance(“MD5”).digest就完事了,如果调用了公共库,那么就容易被hook住,然后就bytes数据暴露了,计算结果也被修改了。所以多用原生类型自己写函数吧。
1、使用svc指令读取文件。能读取到真实的APK,就能检测APK的完整性。能读取到真实的maps就能检测到各种hook框架的特征。能读取到真实的/proc/下的各种文件,就能检测各种调试器,各种cracker留下的痕迹。
2、保护svc指令。svc指令只能通过inlinehook修改内存实现(内核hook不在本文讨论范围内,本文开头就说明了)。如果cracker在搜索内存时,没有搜索到svc指令,那么我们执行代码时,就不会被hook住。
下面才是真正做的事:
1、对某些关键的逻辑(如果逻辑是用java写的,可以先套java转C壳)加一个壳。
2、这个壳的静态代码中不存在任何svc特征,一旦加载so,先进行完整性校验,当校验需要读取APK时,释放svc代码执行读取操作,这样在内存搜索不到svc,也就无法被hook。如果要校验maps中是否有hook框架也在这里进行。
3、当校验通过,再执行真正的程序逻辑,并且此时原程序逻辑的so是碎片化的(就像java的指令抽取),此时从内存dump出来的so也是不完整的,所以无法脱壳出原so。
以上,实现了防爆破(加壳无法修改),防脱壳(so分解了,无法脱壳),防hook(svc即插即用,无法hook,除非改内核)。然后,就只有内存补丁一条路了,再想想魔改的ollvm规则,算了。
链接: https://pan.baidu.com/s/1nugHGQpuQsl-9sDTt4gIvA 提取码: 6qwh
看雪ID:血舞长空
https://bbs.pediy.com/user-home-113423.htm
# 往期推荐
球分享
球点赞
球在看
点击“阅读原文”,了解更多!
原文始发于微信公众号(看雪学苑):怎样制作一个防止重打包的APK【反脱壳反HOOK】