Android逆向:暴力破解APK签名校验,愉快的重新打包微信支付宝APK

Posted encoderlee

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android逆向:暴力破解APK签名校验,愉快的重新打包微信支付宝APK相关的知识,希望对你有一定的参考价值。

回顾

《Android逆向小技巧③:批量注入日志,打印目标程序执行流程》

在上一篇2019年的文章中,我们使用python写了一个简单的文本处理工具:
https://github.com/encoderlee/android_tools

在使用apktool对目标应用的apk解包以后,用这个python写的小工具,分析反编译出来的smali代码,并在每个方法中注入日志,然后对apk重新打包,这样,但APP运行的时候,我们每做一个操作,都可以从日志中看出目标代码的执行流程。

不过这种方式有一个很大的缺点,就是现在很多APP都做了签名校验,重新打包后,APP启动时检查到自身签名不对,发现自己被重新打包了,就罢工不再工作了。

签名校验

以支付宝目前的最新版10.2.50 (2021-12-20) 为例,使用apktool重新打包后,你需要使用apksigner重新签名才能安装:

apksigner sign --ks encoderlee.jks alipay.apk

但是重新签名签的这个名,只能用自己生成的证书去签名,因为你不可能搞到支付宝的证书和私钥。

这个时候如果直接安装运行这个APK,会出现这样的问题:


抱歉,请求参数不合法。

其实这就是因为APP检测到自身签名不对,就拒绝服务的表现,有的APP会表现为闪退。
其实想想也很容易理解,apktool解包,修改,重新打包APP那么简单,没有哪个厂商愿意让自己的APP被随意的玩弄和修改,所以目前绝大多数的APP都做了签名校验。

常规对抗

常规的对抗思路是,既然你在代码中做了签名校验,那么我找到你校验签名的代码,通过修改smali文件或用Xposed干掉它,不久OK了。于是你在网上可以搜到很多如何校验签名的代码:

 public static int verifySignature(Context context) 
        boolean isValidated  = false;
        try 
            //得到签名
            PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(),PackageManager.GET_SIGNATURES);
            Signature[] signs = packageInfo.signatures;

            //将签名文件MD5编码一下
            String signStr = md5(signs[0].toCharsString());

            //将应用现在的签名MD5值和我们正确的MD5值对比
            return signStr.equals("这里写正确的签名的MD5加密后的字符串");
         catch (PackageManager.NameNotFoundException e) 
            e.printStackTrace();
        
        return isValidated;
    

本质上来说这些签名校验的代码,都是调用 PackageManager.getPackageInfo().signatures 去获取自身的签名信息,进行比较判断自己是否被重新打包。

实际上,你在微信和支付宝反编译出的代码中,也能找到这些调用,但当你尝试修改smali或用xposed干掉这些调用的,替换原版的 signatures 数据,就会发现:

并没有什么卵用

想想也不可能那么简单,微信支付宝可是和这帮打包者对抗多年了,实际上在微信支付宝中,还使用了多种手段来校验自身签名,其中就包括在so中使用本机代码来实现校验,这样使得我们解决起来非常麻烦。

当然理论上来说,你完全可以找到它在so中检验签名的代码,干掉它,但是时间成本未免太高,看看微信支付宝的那个JAVA代码量,以及so的数量,想在这些海量代码中分析出关键点来,非常麻烦,就不要在这个思路上浪费时间了。

剑走偏锋

那么,能不能找到一种通用的办法,干掉大多数APP的签名校验呢?

我们先来分析,apksigner对APK签名,本质上是做了什么事情?

我们可以比较apktool重打包后没有签名的APK文件和apksigner签名后的APK文件,发现在APK文件中多了一个【META-INF】目录,里面的文件保存的实际上就是签名和文件校验信息。

那么,我们直接把原版APK中的【META-INF】覆盖到打包后的APK中,不就可以了?这样APK运行后,获取到的signatures 仍然是自己原版的 signatures 。

理想是美好的,但是android的这套签名机制当然不会那么傻,这样简单替换【META-INF】目录后的APK,自然是无法正常安装的,提示【INSTALL_PARSE_FAILED_NO_CERTIFICATES】错误,因为android系统在安装的时候检测到签名和文件摘要信息对不上,自然就不允许安装。

Android签名校验原理可以看这篇文章:《Android 端 V1/V2/V3 签名的原理》

但要知道,Android系统是开源的,我们能不能修改Android系统源代码,让它允许安装签名错误的APK呢?当然是可以的。实际上也不需要这么麻烦,如果我们有root权限或有xposed,一样可以Hook Android系统本身的代码,让Android系统跳过签名校验,安装这个签名错误的APK。

这样的Xposed模块早已有人写好了,就是【幸运破解器「Lucky Patcher」】

https://www.luckypatchers.com/download/

幸运破解器有两种方式来运行,一种是手机已经Root,一种是手机已装好Xposed。

推荐Xposed的方式来运行,装好幸运破解器后,在Xposed中勾选启用该模块,打开幸运破解器APP。

【工具箱】-》【Android核心破解】-》勾选【签名验证始终真实】,勾选【禁用ZIP签名验证】

一番操作后,我们就可以把重新打包后签名不对的APK安装到这个手机上。而且APK里的【META-INF】目录里的文件,都是原封不动的原本APP里的签名文件,即使APP运行起来后,动态检查签名,也不会有什么问题,于是我们就可以正常运行我们重新打包修改过的微信支付宝APP了,当然其它大多数APP都可以这样来搞。

神器【VirtualXposed】

有人说,这种方式也太苛刻了吧,这样一搞,虽然是个通用和万能的方法破解了签名校验,但是要求安装该APP的手机,必须是一个ROOT过的手机,或者装了Xposed的手机呀,现在最新的小米华为手里,想要ROOT和Xposed,实在太麻烦了。而且我修改过的APP,想发布到群里给大家伙使用,不可能大家伙都要去ROOT手机吧?

那就要借助大名鼎鼎的 【VirtualXposed】了!
https://github.com/android-hacker/VirtualXposed

这个神器,可以在没有Root权限的手机上创建一个虚拟环境,然后对该虚拟环境内的APP启用Xposed模块!
这个项目的作者真的是个天才,这个思路都被他想出来并且付诸实现了。

而且 【VirtualXposed】本身实际上已经集成了【幸运破解器「Lucky Patcher」】的【Android核心破解】功能,即允许在【VirtualXposed】中安装签名不对的APK。


我们只需要在【VirtualXposed】的【高级设置】中勾选【允许安装没有签名的应用】
这样就不需要【幸运破解器「Lucky Patcher」】了,绝大多数APK,我们使用apktool重新修改打包后,只需把原APK的签名文件【META-INF】覆盖回去,然后通过这样的方式,安装签名不对的APK文件,就可以暴力绕过APK签名校验,愉快的重新打包和分发各种APP了。

以上是关于Android逆向:暴力破解APK签名校验,愉快的重新打包微信支付宝APK的主要内容,如果未能解决你的问题,请参考以下文章

Android逆向:暴力破解APK签名校验,愉快的重新打包微信支付宝APK

Android逆向:暴力破解APK签名校验,愉快的重新打包微信支付宝APK

安卓逆向,瑞数破解 Frida食药监apk数据抓取,采集逆向,签名

Android逆向之旅---带你爆破一款应用的签名验证问题

Android apk如何加固防止被破解(防止逆向编译)

Android apk如何加固防止被破解(防止逆向编译)