Objection 快速逆向、自动分析和主动调用
前言:为什么需要 Objection
在 Android 逆向分析中,Frida 已经成为最强大的动态插桩工具。但实际使用时你会发现,许多操作是重复性的:查看 Activity 列表、搜索特定类名、hook 某个方法查看参数和返回值——每次都需要手写一段 JavaScript 脚本,然后通过 frida -U -f com.app -l hook.js 加载。这种模式虽然灵活,但在快速逆向的场景下效率并不高。
Objection 正是为了解决这个问题而诞生的。它基于 Frida 构建,将常见的逆向操作封装为一组开箱即用的命令,让你在无需编写 JavaScript 的前提下完成大部分逆向分析工作。简单来说:Frida 是底层引擎,Objection 是高级接口。
本文将从工作流、信息收集、类探索、主动调用和实际案例五个维度,系统讲解 Objection 的使用方法。
Objection 快速逆向工作流
Objection 的核心优势在于"零脚本、开箱即用"。一个典型的快速逆向工作流如下:
安装目标 APK → 启动 Objection 注入 → 信息收集 → 定位关键类 → Hook/调用 → 验证结果
安装目标应用(如果你手上有 APK 文件):
# Objection 可以直接安装并启动应用
objection -g com.target.app explore --startup-command "android hooking list classes"
其中关键参数说明:
-g或--gadget:指定目标包名explore:进入交互式 REPL 环境--startup-command:启动时自动执行一条命令(可多次使用)
进入 REPL 后,Objection 会显示 com.target.app on (xxx) [usb] # 提示符,表示已成功注入。
信息收集阶段
Android Manifest 组件信息
AndroidManifest.xml 是逆向分析的第一站。它包含了应用的四大组件声明、权限请求、intent-filter 等关键信息。
# 获取完整 AndroidManifest.xml
android manifest show
# 查看应用声明的权限
android manifest show permissions
执行后会输出解析后的 Manifest 内容,包括所有注册的 Activity、Service、BroadcastReceiver 和 ContentProvider。这在寻找攻击面(如导出组件)时非常有用。
查询导出组件
导出组件(exported=true)是应用暴露给外部调用的接口,也是安全审计的重点目标:
# 列出所有导出 activities
android hooking list activities
# 列出所有导出 services
android hooking list services
# 列出所有导出 receivers
android hooking list receivers
# 查看 intent-filter,找到可通过特定 action 启动的组件
android intents query_activities -a android.intent.action.MAIN
通过这些命令,你可以快速建立应用的组件拓扑图,了解哪些功能入口是可以直接触发的。
导出密钥库
android keystore list
该命令会列出设备中与应用相关的密钥库信息,帮助你在分析签名验证、数据加密等逻辑时获取密钥信息。
类和方法探索
搜索关键字相关类和方法
在逆向分析中,我们通常不知道具体的类名,只知道功能关键词。Objection 提供了强大的搜索能力:
# 搜索类名中包含 "login" 的所有类
android hooking search classes login
# 搜索类名中包含 "vip" 的所有类
android hooking search classes vip
# 查看某个类的所有方法
android hooking list class_methods com.example.app.VipManager
# 查看某个类的所有实例方法
android hooking search methods vip com.example.app
例如,对一个付费应用执行 android hooking search classes vip,可能会返回:
com.example.app.model.VipInfo
com.example.app.manager.VipManager
com.example.app.utils.VipChecker
从类名就能初步判断:VipChecker 很可能包含 VIP 验证逻辑,VipManager 管理会员状态,VipInfo 是会员信息的数据模型。
查看类的继承关系
了解类的继承关系有助于理解框架的设计模式:
# 查看类的完整信息,包括父类和实现的接口
android hooking list class_methods com.example.app.VipChecker
Objection 会在输出中标注哪些方法是继承自父类的,哪些是类自身定义的,以及类实现的接口列表。这对快速建立类的层次结构非常有帮助。
动态分析类加载情况
# 列出所有已加载的类
android hooking list classes
# 配合 grep 过滤(在 shell 中使用)
android hooking list classes | grep -i "pay"
如果你在运行时操作了应用(如点击某个按钮触发了懒加载),再次执行该命令就能看到新加载的类。这可以帮助你追踪动态加载的行为。
主动调用方法
Objection 最强大的功能之一是主动调用(Active Invocation),即在运行时直接调用应用中的 Java 方法。
执行方法调用
# 无参方法调用
android hooking invoke com.example.app.VipManager isVip
# 带参方法调用
android hooking invoke com.example.app.VipManager checkVip java.lang.String user007
android hooking invoke 命令的基本语法为:
android hooking invoke <类全名> <方法名> [参数类型1 参数值1] [参数类型2 参数值2] ...
构造参数并调用
参数类型的指定遵循 Java 的全限定类名规范:
# 传入 int 参数
android hooking invoke com.example.app.PayManager pay int 100
# 传入 boolean 参数
android hooking invoke com.example.app.VipManager setVipStatus boolean true
# 传入 String 参数
android hooking invoke com.example.app.UserManager login java.lang.String admin java.lang.String 123456
# 传入多个不同类型参数
android hooking invoke com.example.app.OrderManager createOrder java.lang.String prod001 int 2 boolean false
与 Frida 的联系:在 Frida 原生脚本中,主动调用需要这样写:
Java.perform(function() {
var VipManager = Java.use("com.example.app.VipManager");
var result = VipManager.isVip();
console.log("VIP Status: " + result);
});
Objection 将这段代码封装为单条命令,省去了编写脚本的步骤。本质上,Objection 底层就是在运行时生成并注入类似的 Frida JavaScript 代码。
获取和设置类属性值
除了方法调用,Objection 还支持直接操作类的属性(字段):
# 设置静态字段值
android hooking set static_field com.example.app.VipInfo isVip boolean true
# 获取静态字段值(通过 invoke 访问 getter 方法)
android hooking invoke com.example.app.VipInfo getIsVip
这在绕过状态检查时非常实用——直接修改内存中的标志位,比 hook 方法更简洁。
实际案例:逆向 VIP 验证逻辑
定位 VIP 检查方法
假设我们面对一个付费视频应用,目标是分析其 VIP 验证机制。首先搜索相关类:
android hooking search classes vip
输出:
com.video.app.member.VipChecker
com.video.app.member.MemberManager
com.video.app.model.MemberInfo
查看 VipChecker 的方法:
android hooking list class_methods com.video.app.member.VipChecker
输出中找到关键方法:
private boolean checkVipStatus(String userId)
public boolean isVipUser()
public int getVipLevel()
public long getVipExpireTime()
修改返回值
Hook checkVipStatus 方法,让它始终返回 true:
# Hook 方法并修改返回值
android hooking set return_value com.video.app.member.VipChecker checkVipStatus true
执行后,每次应用调用 checkVipStatus 都会得到 true,VIP 验证即被绕过。你也可以通过 --include-overloads 参数处理重载方法。
主动调用付费功能方法
找到会员功能的入口方法后,可以直接调用:
# 解锁会员视频
android hooking invoke com.video.app.member.MemberManager unlockPremiumVideo java.lang.String video_12345
# 查看当前 VIP 等级
android hooking invoke com.video.app.member.VipChecker getVipLevel
# 设置会员到期时间(操作属性)
android hooking set static_field com.video.app.model.MemberInfo expireTime long 1893456000000
通过组合主动调用和属性修改,你可以在不修改 APK 的情况下完整验证付费功能的逻辑。
实际案例:使用 wallbreaker 插件 dump 敏感对象
wallbreaker 是 Objection 的一个强大插件,可以在运行时 dump 内存中的 Java 对象实例。
# 加载 wallbreaker 插件
plugin load wallbreaker
# 列出某个类的所有活动实例
android heap search instances com.video.app.model.MemberInfo
# dump 实例的完整字段信息
android heap print_instances com.video.app.model.MemberInfo
执行后会输出该类在内存中所有实例的详细信息,包括每个字段的当前值:
Handle 0x1234:
className: com.video.app.model.MemberInfo
fields:
userId = "user_007"
vipLevel = 0
isVip = false
expireTime = 0
token = "eyJhbGciOiJIUzI1NiJ9..."
这在分析运行时状态、提取敏感数据(如 token、密钥、用户信息)时极为有用。相比 hook 日志输出,wallbreaker 能直接获取对象的完整快照。
Objection 脚本化操作
交互式 REPL 适合探索性分析,但在需要重复执行的场景下,脚本化是更好的选择。
将命令写入文本文件 objection-script.txt:
android hooking search classes vip
android hooking list class_methods com.video.app.member.VipChecker
android hooking set return_value com.video.app.member.VipChecker checkVipStatus true
android hooking invoke com.video.app.member.MemberManager unlockPremiumVideo java.lang.String video_12345
执行脚本:
objection -g com.video.app explore -s objection-script.txt
-s 参数会按顺序执行脚本中的每条命令。这在 CI/CD 自动化测试、批量分析多个应用时非常方便。
你也可以使用 --startup-command 在启动时执行单条命令,结合多个 --startup-command 实现简单的工作流自动化。
Objection 与自定义 Frida 脚本的结合使用
Objection 虽然强大,但终究是封装好的高级命令。当遇到复杂场景(如 trace 函数调用链、修改算法逻辑、处理 native 函数)时,仍然需要自定义 Frida 脚本。
Objection 提供了在 REPL 中加载 Frida 脚本的能力:
# 在 Objection REPL 中加载自定义脚本
import /path/to/custom_hook.js
这等价于在 Frida 中 frida -U -f com.app -l custom_hook.js,但好处是你可以在 Objection 的信息收集结果基础上,有针对性地编写脚本。
典型的结合使用模式:
- 先用 Objection 探索:
android hooking search classes、list class_methods快速定位目标类和方法 - 再用 Frida 精确 hook:根据探索结果编写自定义脚本,实现更复杂的逻辑(如 trace、参数篡改、调用栈打印)
- 用 Objection 验证:通过
invoke和set return_value快速验证 hook 效果
例如,先用 Objection 找到 VipChecker.checkVipStatus 方法,然后编写 Frida 脚本打印其完整的调用栈:
Java.perform(function() {
var VipChecker = Java.use("com.video.app.member.VipChecker");
VipChecker.checkVipStatus.implementation = function(userId) {
console.log("[*] checkVipStatus called with: " + userId);
console.log("[*] Call stack: " + Java.use("android.util.Log")
.getStackTraceString(Java.use("java.lang.Exception").$new()));
return this.checkVipStatus(userId);
};
});
这种"Objection 探索 + Frida 深度分析"的工作模式,是目前 Android 逆向工程师最高效的实践方式。
总结
Objection 将 Frida 的动态插桩能力封装为简洁的命令行接口,大幅降低了逆向分析的使用门槛。核心要点回顾:
| 功能 | 命令 | 用途 |
|---|---|---|
| 信息收集 | android manifest show |
查看组件和权限 |
| 类搜索 | android hooking search classes |
按关键字定位类 |
| 方法查看 | android hooking list class_methods |
列出类的所有方法 |
| 修改返回值 | android hooking set return_value |
绕过检查逻辑 |
| 主动调用 | android hooking invoke |
直接执行方法 |
| 对象 dump | android heap print_instances |
查看运行时对象状态 |
| 脚本执行 | objection -g pkg explore -s file |
批量自动化操作 |
掌握 Objection,意味着你可以在几分钟内完成"安装 → 探索 → 定位 → 验证"的完整逆向流程。它不是 Frida 的替代品,而是 Frida 生态中不可或缺的效率工具。在下一篇文章中,我们将深入 Frida 的综合情景案例,展示如何在真实场景中应对更复杂的逆向挑战。