使用Frida给apk脱壳并穿透加固Hook函数
首发于先知社区 https://xz.aliyun.com/t/7670
前言
今天拿到了新玩具JEB 3.17.1,想测试一下,顺便学习学习Android逆向,于是找了一个apk准备试试水,看看能不能搞到VIP。
初步分析
拖入jeb查看
嗯。。google一下
几维安全的壳,虚拟化很烦,也没什么好的脱壳工具,于是切换思路
从本质上来说,虚拟化就是自己实现了一套基本的cpu指令,通过自己的解释器解释给机器。因此想要在虚拟化之后仍然能让机器运行,当然还得还原代码给机器,只不过可能在内存中释放,加大了静态分析的难度。
那么直接让apk运行起来,我们去dump虚拟机自解密出来的dex不就好了么。
frida dump dex
frida 是一款基于 python+javascript 的 hook 框架,可运行在 android、ios、linux、win等各个平台,主要使用的动态二进制插桩技术。
总之frida是非常强大的,可以实现很多奇妙操作。
安装
pip3 install frida |
frida-server
https://github.com/frida/frida/releases
到上面链接里找到对应手机架构,与frida版本相同的frida-server
移动frida-server到安卓的/data/local/tmp目录
./adb push frida-server /data/local/tmp |
frida脚本
这里使用了FRIDA-DEXDump https://github.com/hluwa/FRIDA-DEXDump
其原理就是在内存中检索dex035头并获取dex长度,然后提取出来。当然,这样做会将内存中所有的dex包都提取出来,具体哪个才是我们需要的得根据包名判断并静态分析查看。
python3 ./main.py |
这里我成功提取到了无壳dex,包名都比较清晰
抓包分析
既然壳不好脱而且脱下来的又不容易修复,就考虑先看看封包里有没有VIP数据
使用HttpCanary对apk进行抓包
抓到了一个登陆验证包
但响应里没有我们想要的信息,只是一个随时变动的值而已
看来抓包这条路走不通了,我们接下来只能分析拿到的dex。
JEB静态分析
我们使用JEB来分析我们拿到的dex,查看包的层级数,定位到目标apk的包名,这里的命名都很清晰,直接按单词分析即可。
我这次用来当例子的是一个类似抖音快手的app,有视频和直播两个Activity,视频每天只能看十个(最坑的是重复点十次也算),然后就要求充值VIP,用户进入后可以不登录,会自动生成一个ID,且读取系统信息作为认证,所以重复的卸载安装当然是绕不过次数限制的。
所以我们的目标就是通过frida hook函数使我们绕过限制,成为VIP。
查看原apk文件的Manifest
这个权限它就离谱。。。
我们来看Activity的启动顺序
先来了一个开屏广告SplashActivity,然后加载Main和Live顺便走一遍登录注册。
一般判断用户是否是VIP,可能存在多处判断,这样的话我们hook的点会量很大,而且可能存在漏掉的情况,因此去找变量最初赋值的位置来hook是从源头上控制了数据,而且前面封包分析发现用户数据请求发送后给我们的响应不包含VIP确认数据,因此可以说是万无一失。
回到层级目录分析,我们发现video/bean这个包里有我们感兴趣的东西,应该是包含了短视频相关数据。
查看TouseinfoBean这个类
我们发现这里应该包含了用户数据,修改此处就可以了。
但事情没有那么简单,通过交叉引用我们发现这个类根本没有被实例化(可能是写着写着忘了又重新写了一个用户管理模块???)
搜索字符串后并没有什么有用的发现,分析良久才想到从包层级列表搜索方法,豁然开朗(还是太菜)。
嗯。。原来把直播和视频的vip管理合并到一个包了。
com.xxx.bean下有二十多个类,只能一个一个分析了,最后发现了几个有用的类
其中UserBean用来管理用户信息,评论,VIP相关等等,UserLevelBean管理用户经验之类的信息。
UserBean类中以下三个方法是我们的Hook点
"vvLevel") (name = |
编写frida脚本穿透加固 Hook Java层函数
没有加固的apk,一般来说直接改smali重新打包就行,而像我们现在遇到的壳,修复dex打包是一件很费力的事情,在这里frida的强大就体现出来了。
使用frida来hook加固的Android应用的java层 的原理可以看这里,简单来说就是拿到加载应用本身dex的classloader,通过这个classloader去找到被加固的类,通过这个类去Hook需要Hook的方法。
因此要穿透加固 Hook Java层函数的jscode模版如下:
if(Java.available) { |
根据上面对Hook点的分析,我们可以写出以下jscode
if(Java.available) { |
注入frida Hook脚本
frida注入脚本有两种方式,使用python作为载体,直接运行脚本即可。
import frida, sys |
或者使用命令行方式,当然了,还需要安装frida-tools
pip3 install frida-tools |
这里我使用命令行方式(这里有个坑,必须按我给出的顺序,不然会报错无法连接)
先连接adb
./adb kill-server && ./adb server && ./adb shell // mumu模拟器连接方式,其他模拟器自行查询 |
新开一个shell,打开tcp转发,默认为27042端口,但是有些app会检测这个端口,因此我们来自定义一个
./adb forward tcp:1234 tcp:1234 |
回到第一个shell,我们已经连接到了adb,直接输入
./data/local/tmp/frida-server -l 0.0.0.0:1234 |
在第二个shell中执行注入命令
frida -H 127.0.0.1:1234 -f com.xxx -l hook.js |
成功连接后命令行有如下回显
输入 %resume 对应的apk自启,没有报错则成功注入
我这里还加了一些流程和类名的输出
测试apk,已经可以了,其他功能思路差不多,Hook就行。