使用Frida给apk脱壳并穿透加固Hook函数
字数 1728 2025-08-22 12:22:24
使用Frida给APK脱壳并穿透加固Hook函数 - 详尽教学文档
1. 前言与背景
本教程将详细介绍如何使用Frida工具对加固APK进行脱壳和函数Hook操作,特别针对虚拟化加固(如几维安全壳)的应用场景。通过本教程,您将学习到:
- 使用Frida进行内存Dump获取解密后的DEX
- 穿透加固层直接Hook Java层函数
- 分析APK结构定位关键Hook点
- 编写Frida脚本实现VIP功能绕过
2. 工具准备
2.1 所需工具清单
- Frida: 动态二进制插桩框架
- Frida-server: 运行在目标设备上的服务端
- JEB: 反编译工具(版本3.17.1或更高)
- HttpCanary: 抓包工具(可选)
- ADB: Android调试桥
- Python 3: 运行Frida脚本
2.2 安装步骤
-
安装Frida:
pip3 install frida frida-tools -
下载frida-server:
- 访问 Frida releases页面
- 选择与目标设备架构匹配的版本
- 下载后重命名为
frida-server
-
部署frida-server到设备:
adb push frida-server /data/local/tmp/ adb shell "chmod 777 /data/local/tmp/frida-server"
3. 脱壳流程
3.1 启动frida-server
adb shell
cd /data/local/tmp
./frida-server
3.2 使用FRIDA-DEXDump工具
- 下载FRIDA-DEXDump
- 运行脱壳脚本:
python3 ./main.py
原理说明: 该工具通过扫描内存中的dex035魔数头,识别并提取所有DEX文件。由于内存中可能存在多个DEX,需要根据包名判断哪个是目标DEX。
4. 静态分析
4.1 使用JEB分析
- 将脱壳后的DEX拖入JEB
- 分析包层级结构,定位目标包名
- 重点关注以下类型文件:
- 用户信息相关类(如
UserBean) - VIP判断相关类
- 权限声明文件(AndroidManifest.xml)
- 用户信息相关类(如
4.2 关键类分析技巧
- 搜索字符串: 如"VIP"、"isVV"等关键词
- 交叉引用分析: 查看类被哪些地方调用
- 方法名分析: 关注
getLevel、isVIP等方法 - 注解分析: 如
@JSONField可能标识重要字段
5. 穿透加固Hook技术
5.1 基本原理
加固应用通常会自定义ClassLoader加载解密后的DEX。要穿透加固Hook,需要:
- 获取应用自身的ClassLoader
- 通过该ClassLoader定位目标类
- 使用Frida的
classFactory机制进行Hook
5.2 通用Hook模板
if (Java.available) {
Java.perform(function(){
var application = Java.use("android.app.Application");
application.attach.overload('android.content.Context').implementation = function(context) {
var result = this.attach(context); // 先执行原来的attach方法
var classloader = context.getClassLoader(); // 获取classloader
Java.classFactory.loader = classloader;
var Hook_class = Java.classFactory.use("com.xxx.类名");
console.log("Hook_class: " + Hook_class);
// 正常Hook代码
Hook_class.方法名.implementation = function() {
// 要执行的操作
}
return result;
}
});
}
5.3 实际案例Hook代码
针对用户信息类(UserBean)的Hook示例:
if (Java.available) {
Java.perform(function(){
var application = Java.use("android.app.Application");
application.attach.overload('android.content.Context').implementation = function(context) {
var result = this.attach(context);
var classloader = context.getClassLoader();
Java.classFactory.loader = classloader;
var userinfo = Java.classFactory.use("com.xxx.bean.UserBean");
// Hook用户等级方法
userinfo.getLevel.implementation = function(){
return 10; // 设置为10级
}
// Hook VIP状态判断
userinfo.isVV.implementation = function(){
return true; // 始终返回true
}
// Hook VIP等级
userinfo.getVVLevel.implementation = function(){
return "9"; // 设置为9级
}
return result;
}
});
}
6. 脚本注入方法
6.1 Python方式注入
import frida, sys
jscode = """
// 你的JavaScript Hook代码
"""
def on_message(message, data):
if message['type'] == 'send':
print("[*] {0}".format(message['payload']))
else:
print(message)
process = frida.get_usb_device().attach('应用完整包名')
script = process.create_script(jscode)
script.on('message', on_message)
script.load()
sys.stdin.read()
6.2 命令行方式注入
-
设置端口转发(避免使用默认27042端口):
adb forward tcp:1234 tcp:1234 -
启动frida-server指定端口:
adb shell /data/local/tmp/frida-server -l 0.0.0.0:1234 -
注入脚本:
frida -H 127.0.0.1:1234 -f com.xxx -l hook.js -
恢复应用执行:
%resume
7. 常见问题与解决方案
7.1 连接问题
- 问题: 无法连接到frida-server
- 解决:
- 检查adb连接是否正常
- 确认frida-server版本与客户端匹配
- 尝试更换端口(避免使用27042)
7.2 Hook失败
- 问题: Hook代码未生效
- 解决:
- 检查类名和方法名是否正确
- 确认是否穿透了加固层(使用classFactory)
- 添加调试输出确认代码执行路径
7.3 应用崩溃
- 问题: Hook后应用崩溃
- 解决:
- 检查方法签名是否正确(参数数量、类型)
- 确保不修改关键数据结构
- 尝试只Hook读方法而非写方法
8. 高级技巧
8.1 多DEX处理
当应用有多个DEX时:
- 使用
Java.enumerateClassLoaders()列出所有ClassLoader - 尝试每个ClassLoader来定位目标类
8.2 主动调用方法
除了Hook,还可以主动调用方法:
var instance = Hook_class.$new(); // 创建实例
var result = instance.someMethod(); // 调用方法
8.3 修改字段值
直接修改类字段:
Hook_class.字段名.value = 新值;
9. 总结
本教程详细介绍了使用Frida对加固APK进行脱壳和Hook的完整流程,关键点包括:
- 使用FRIDA-DEXDump进行内存Dump脱壳
- 通过JEB静态分析定位关键Hook点
- 穿透加固层Hook的技术原理与实现
- 多种脚本注入方式
- 常见问题排查方法
通过掌握这些技术,您可以有效分析并修改加固APK的行为,特别适用于安全研究、漏洞挖掘和逆向工程等领域。