打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
某音APK破解流程

上上节我们学习了如何破解某手的数据请求加密协议,本节我们来破解某音的数据加密协议,毕竟某音是国内短视频的一哥,使用的防破解机制肯定也比某手多。破解了他的加密协议后,某山,某瓜的短视频协议也基本不攻自破。

逆向分析

版本挑选

首先去豌豆荚下载某音APK,老规矩,不要下载最新的APP,我选择的是1.6.4版本。

抓包分析

分析请求数据的突破口一般都是抓包,不多说,使用fiddler抓取请求数据,这里查看某音的用户详情接口,如下图:

经过多次请求后,发现除user_id每次变化外,还有两个参数as,cp会变化,其他的参数基本跟本地设备有关或者直接写死的。猜想这两个字段肯定是用于请求加密以及跟服务端做校验。

jadx反编译dex

使用jadx反编译抖音的dex文件,直接全局搜索字段'as='的信息:

看到这里构造了as和cp这两个参数,直接点击进入查看方法。

看到逻辑比较简单,利用UserInfo.getUserInfo方法获取字符串后,然后分别赋值给as和cp字段。我们来查看UserInfo.getUserInfo的方法,看看到底是什么逻辑。

果然是native方法,利用so来对加密信息进行加密。那就先利用Xposed先hook住此方法,将参数进行打印,以便自己新建一个android项目来对so进行调试。

运行模块,执行某音的app,查看控制台信息。

三个参数打印的值是:当前时间戳,请求接口的url以及请求参数的数组信息。

新建项目调用SO文件

既然知道调用的参数信息,我们就新建一个Android项目,构造这三个参数,调用他的so文件。jadx中我们全局搜索字符串信息 System.loadLibrary即可:

找到了UserInfo类对应的lib文件,我们反编译apk,找到lib目录下的libuserinfo.so文件,放到我们自己新建的Android项目中。直接上层构造一个跟他UserInfo一样包路径的类即可:

然后将上面我们hook得到的参数信息直接写死到一个类中。

基本上我们构造的工作就完成了,直接打包开始直接运行吧,可惜的是程序闪退了:

应该进行加载so出现问题了,看看UserInfo类中是不是还有一些初始化方法没调用:

这里看到的确有两个方法有点可疑,全局查看这两个方法的调用地方:

看到全局中就一个地方调用了setAppId方法,而且值就是写死的为2,另一个方法initUser就有点麻烦了,不过可以使用万能的hook大法,直接hook这个方法打印他的参数信息即可:

运行模块,查看打印的日志信息:

直接就看到了initUser这个参数的赋值,拷贝出来赋值调用即可:

IDA动态调试

再次打包启动项目,发现还是报错,而且连 result:0这个日志没打印,这就说明setAppId和initUser函数没有调用就退出了,那么就会想到?是不是so中的JNI_OnLoad函数中做了一些判断逻辑呢?直接用IDA打开这个so文件:

先搜索JNI_OnLoad函数,双击过去,按F5查看C代码,发现里面有好几处判断,然后直接exit退出,我们如果调试so,得先过了这些判断。

啥也别说了,在前面某手的破解过程中,已经把android_server文件到设备目录下。

第一步:运行android_server命令

第二步:转发端口和用debug模式打开应用

第三步:启动IDA附加进程

设置本地地址和一些选项:

找到要调试的进程:

双击点开,进入IDA调试界面:

再检查一下是否Debugger选项是否勾选:

第四步:查看调试端口连接调试器

在Eclipse中的DDMS中看到红色小蜘蛛的调试应用端口号是8613,然后连接调试器:

第五步:点击IDA中的运行按钮,或者F9快捷键

这时候发现红色蜘蛛变成绿色了,而且调试对话框也没有了。这时候就进入调试页面了:

因为我们给JNI_OnLoad函数挂起了,而一个应用会加载很多系统的so文件,所以这里一直点击运行或者F9:

当发现加载了libuserinfo.so文件的时候,则正是开始调试工作

我们在右侧栏查找这个so文件:

双击,继续查找他的JNI_OnLoad函数:

点击进入JNI_OnLoad函数处,下个断点:

顺利进入到JNI_Onload函数断点处。

我们在静态分析的时候,找到了他多处exit函数,为了定位哪个地方exit了,我们在所有的exit前面的CMP那边打上断点,慢慢分析:

一处的CMP指令下个断点,然后运行到此处,查看R3寄存器值是否为0:

发现没有问题,直接按F9到下一个断点:

第二处CMP也是0,直接通过:

第三处发现不是0,为了能够继续往下走,就修改R3寄存器值即可,在右侧栏的寄存器中右击R3寄存器,然后点击修改值:

修改成功,继续执行

直接F9到第四处CMP的话,应用直接退出调试了,说明在3和4处判断中间有判断,这里经过多次多次单步调试F7键,定位出现问题的地方了,我们进入这个跳转地址:

然后发现内部还有BL指令,继续查看:

这里有一个GlobalContext类,这个类应该是Java层的,native层应该用反射机制获取全局的Context变量,我们直接去Jadx中搜索这个类:

问题就清楚了,因为我们的demo工程中压根没这个类,所以native中获取全局context变量就失败了,所以就exit失败退出了,解决办法也简单,直接在demo工程中构造这个类,然后在Application中初始化context即可:

构造的时候一定要注意包名一致,然后在demo中的Application类进行设置context即可:

再次运行项目,还是不行,继续调试,方法步骤和上面类似,继续往下走:

看到这个信息,基本可以猜出是获取包的签名;

这里看出是我们的包MD5签名跟so文件中的md5对比:

既然知道是获取包名,直接hook住签名的方法,获取他的签名,再通过反射写死到类中:

通过上面一系列操作,最终获取到某音的包的签名信息,打包运行,发现通过了此判断,继续往下走,会发现在第五个exit判断之后,有一个函数 _Z17be_attached_checkRi出问题了,看名字相信都能猜出来,进入内部查看:

哈哈,弄过调试的同学大致都猜到了,结合静态分析,继续往下走:

直接修改寄存器中的值,成功过了此处的反调试:

加密函数中打个断点,成功到达了加密函数(不过本章节不介绍其加密函数的破解,读者自行研究):

下面就是成功的获取到了加密之后的数据了:


总结

  • 学习到了IDA调试JNI_Onload函数的方式;

  • 在逆向过程中,如果无法知道确切的调用参数,可以通过无敌的Hook大法打印方法的参数和返回值;

  • 学习到某音通过Native反射获取Context变量,防止程序恶意调用;

  • so中进行app的签名校验,反之被调试;

  • 通过/proc/%d/status获取TracerPid来进行反调试校验;

作者申明

本文的意图只有一个,就是通过分析app学习更多的逆向技术,如果有人利用本文知识和技术进行非法操作进行牟利,带来的任何法律责任都将由操作者本人承担,和本文作者无任何关系,最终还是希望大家能够秉着学习的心态阅读此文。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Android逆向之旅
[转]Android逆向之动态调试总结 | 神乎
Android逆向学习
Android JNI开发入门之一
JNI技术与Android应用(0)
JNI与Android VM之间的关系---- 本文摘录自 高焕堂老师 的Android课...
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服