Objection 常用技巧 (Objection Snippets)

Objection 常用技巧 (Objection Snippets)

📚 前置知识

本配方涉及以下核心技术,建议先阅读相关章节:

Objection 是一个基于 Frida 开发的运行时移动端探索工具包。它提供了类似于 shell 的交互式命令行,无需编写 JavaScript 代码即可完成大部分常见的逆向任务。


Objection 简介与安装

什么是 Objection

Objection 是由 @sensepost 开发的开源工具,对 Frida 做了一层高级封装。它的核心优势在于:

特性说明
零代码 Hook无需编写 JavaScript,输入命令即可 Hook 任意类/方法
交互式 Shell类似终端的命令行界面,支持 Tab 补全和历史记录
一键绕过内置 SSL Pinning、Root 检测等常用绕过方案
跨平台同时支持 Android 和 iOS
可扩展支持导入自定义 Frida 脚本,灵活扩展功能

安装

1
2
3
4
5
6
7
8
# 基础安装
pip3 install objection

# 升级到最新版
pip3 install --upgrade objection

# 验证安装
objection version

注意: Objection 依赖 Frida,安装时会自动拉取对应版本的 frida-tools。请确保本机 Frida 版本与设备上 frida-server 版本一致。

连接设备

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 标准方式:附加到正在运行的应用
objection -g com.example.app explore

# 以 Spawn 模式启动(推荐,可在应用启动前注入)
objection -g com.example.app explore --startup-command "android sslpinning disable"

# 指定设备(多台设备连接时)
objection -S <device_id> -g com.example.app explore

# 通过网络连接远程 frida-server
objection -N -h 192.168.1.100 -p 27042 -g com.example.app explore

连接成功后会进入交互式 Shell,提示符类似:

1
com.example.app on (google: 13) [usb] #

基础命令大全

以下按功能分类整理了 Objection 中最常用的命令。

环境信息

命令说明
env显示应用的沙箱路径(data/cache/外部存储等)
android hooking get current_activity获取当前前台 Activity
android hooking list activities列出 AndroidManifest 中声明的所有 Activity
android hooking list services列出所有已注册的 Service
android hooking list receivers列出所有已注册的 BroadcastReceiver

类与方法搜索

命令说明
android hooking search classes <keyword>模糊搜索已加载的类
android hooking search methods <keyword>模糊搜索方法名
android hooking list classes列出所有已加载的类(输出量巨大,建议重定向)
android hooking list class_methods <class>列出指定类的全部方法

Hook 操作

命令说明
android hooking watch class <class>Hook 整个类的所有方法
android hooking watch class_method <method> --dump-args --dump-return --dump-backtraceHook 指定方法,打印参数、返回值和调用栈
android hooking set return_value <method> <value>强制设置方法的返回值

安全绕过

命令说明
android sslpinning disable禁用 SSL Pinning
android root disable绕过 Root 检测
android root simulate模拟非 Root 环境

文件系统

命令说明
ls [path]列出目录内容
cd <path>切换目录
pwd显示当前工作目录
cat <file>查看文件内容
file download <remote> [local]下载文件到本机
file upload <local> <remote>上传文件到设备

内存操作

命令说明
memory list modules列出所有已加载的 SO 库
memory list exports <module>列出指定模块的导出函数
memory dump all <local_file>Dump 整个进程内存
memory dump from_base <addr> <size> <file>从指定地址 Dump 指定大小的内存
memory search "<pattern>"在内存中搜索字符串或 hex 模式

堆操作

命令说明
android heap search instances <class>在堆中搜索指定类的实例
android heap execute <hashcode> <method>调用实例的方法
android heap evaluate <hashcode>进入 JavaScript 交互模式操作实例

其他实用命令

命令说明
import <script.js>导入自定义 Frida 脚本
jobs list列出当前运行的后台任务(如 Hook)
jobs kill <job_id>停止指定的后台任务
exit退出 Objection
reconnect重新连接到应用

SSL Pinning 绕过

一键禁用

1
android sslpinning disable

执行后 Objection 会自动 Hook 以下常见的 SSL Pinning 实现:

Hook 目标说明
TrustManagerFactory替换系统默认的信任管理器
X509TrustManager.checkServerTrusted()使证书校验直接通过
OkHttp CertificatePinner绕过 OkHttp 的证书锁定
SSLContext.init()注入自定义 TrustManager
WebViewClient.onReceivedSslError()WebView 中忽略 SSL 错误

工作原理

Objection 底层会注入一段 Frida 脚本,将所有证书校验相关的方法替换为空实现(直接返回成功)。等效于手动编写以下 Frida 代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// Objection 底层做的事情(简化版)
Java.perform(function() {
    var TrustManager = Java.registerClass({
        name: 'com.sensepost.BypassTrustManager',
        implements: [Java.use('javax.net.ssl.X509TrustManager')],
        methods: {
            checkClientTrusted: function(chain, authType) { },
            checkServerTrusted: function(chain, authType) { },
            getAcceptedIssuers: function() { return []; }
        }
    });
});

配合 Burp Suite 抓包

1
2
3
4
5
6
7
# 1. 在设备上设置代理
adb shell settings put global http_proxy 192.168.1.100:8080

# 2. 以 Spawn 模式启动并自动禁用 SSL Pinning
objection -g com.example.app explore --startup-command "android sslpinning disable"

# 3. 操作 App,在 Burp 中观察流量

常见问题排查

问题解决方案
禁用后仍然无法抓包检查代理设置是否正确;确认 Burp 证书已安装为系统级证书
应用使用自定义 SSL 库需要手动定位并 Hook 自定义校验函数
Flutter 应用抓不到包Flutter 使用 BoringSSL,需要专用脚本 Hook ssl_verify_peer_cert
应用使用 Network Security ConfigAndroid 7+ 需将 Burp CA 证书安装到系统证书目录
Hook 生效但请求超时检查设备和代理主机是否在同一网络,防火墙是否放行

Root 检测绕过

基本命令

1
2
3
4
5
# 禁用常见的 Root 检测
android root disable

# 模拟非 Root 环境
android root simulate

Root 检测常见手段

应用通常通过以下方式检测 Root,Objection 会逐一进行绕过:

检测方式说明Objection 绕过原理
检查 su 二进制文件查找 /system/bin/su 等路径Hook File.exists() 对 su 路径返回 false
检查 Build.TAGS检查是否包含 test-keysHook 返回 release-keys
检查包管理器检测 Magisk/SuperSU 等包名Hook PackageManager.getPackageInfo() 抛出 NameNotFoundException
检查可写系统分区尝试写入 /systemHook 文件操作相关方法
执行 which su通过 Runtime.exec 执行命令Hook Runtime.exec() 过滤敏感命令

应对自定义 Root 检测

当内置绕过不够用时,可以手动定位检测函数:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 搜索可能的 Root 检测类
android hooking search classes root
android hooking search classes RootDetect
android hooking search classes SafetyNet
android hooking search classes integrity

# 搜索相关方法
android hooking search methods isRooted
android hooking search methods checkRoot
android hooking search methods isDeviceRooted

# 找到目标后直接修改返回值
android hooking set return_value com.example.app.Security.isRooted false
android hooking set return_value com.example.app.Security.checkRoot false

SafetyNet / Play Integrity 绕过

1
2
3
4
5
6
# 搜索 SafetyNet 相关类
android hooking search classes SafetyNet
android hooking search classes PlayIntegrity

# Hook SafetyNet 回调,观察返回结果
android hooking watch class_method com.google.android.gms.safetynet.SafetyNetClient.attest --dump-args --dump-return

注意: SafetyNet/Play Integrity 涉及服务端验证,单纯 Hook 客户端可能不够。生产级绕过通常需要配合 Magisk + 自定义模块。


文件系统探索

基本导航

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 查看应用沙箱环境变量
env

# 输出示例:
# Name                    Path
# ----                    ----
# filesDirectory          /data/data/com.example.app/files
# cacheDirectory          /data/data/com.example.app/cache
# externalCacheDirectory  /storage/emulated/0/Android/data/com.example.app/cache
# codeCacheDirectory      /data/data/com.example.app/code_cache

# 导航到应用数据目录
cd /data/data/com.example.app
ls

关键目录与文件

路径内容常见敏感信息
shared_prefs/SharedPreferences XML 文件Token、用户配置、加密密钥
databases/SQLite 数据库文件用户数据、聊天记录、缓存数据
files/应用自定义文件日志、配置、下载内容
cache/缓存目录网络响应缓存、图片缓存
lib/Native SO 库加密算法实现、核心逻辑
code_cache/DEX 缓存动态加载的 DEX 文件
app_webview/WebView 数据Cookies、Local Storage

实用操作

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 浏览 SharedPreferences
ls shared_prefs/
cat shared_prefs/app_config.xml

# 下载数据库到本机分析
file download /data/data/com.example.app/databases/app.db ./app.db

# 下载整个 SharedPreferences 目录
file download /data/data/com.example.app/shared_prefs/ ./shared_prefs/

# 上传修改后的配置文件
file upload ./modified_config.xml /data/data/com.example.app/shared_prefs/config.xml

# 查看外部存储
ls /storage/emulated/0/Android/data/com.example.app/

自动化文件收集脚本

启动 Objection 时可以用 --startup-command 批量执行:

1
2
3
objection -g com.example.app explore \
  --startup-command "ls /data/data/com.example.app/shared_prefs/" \
  --startup-command "ls /data/data/com.example.app/databases/"

内存操作

列出已加载模块

1
2
3
4
5
6
7
8
# 列出所有加载的 SO 库
memory list modules

# 输出示例:
# Name                        Base          Size     Path
# --------------------------  ----------    ------   ---------------------------------
# libnative-lib.so            0x7b12345000  0x50000  /data/app/.../lib/arm64/libnative-lib.so
# libssl.so                   0x7b23456000  0x80000  /system/lib64/libssl.so
1
2
3
4
5
6
7
8
# 列出指定模块的导出函数
memory list exports libnative-lib.so

# 输出示例:
# Type      Name                          Address
# --------  ----------------------------  -----------
# function  Java_com_example_encrypt      0x7b12347a00
# function  Java_com_example_decrypt      0x7b12347e00

内存 Dump

1
2
3
4
5
# 从指定基址 Dump 内存
memory dump from_base 0x7b12345000 0x50000 /tmp/libnative-lib.so

# Dump 整个进程内存(文件会很大)
memory dump all /tmp/full_dump.bin

用途: Dump 出的 SO 文件可以用 IDA Pro 或 Ghidra 进行静态分析。对于加壳应用,运行时 Dump 可以获取脱壳后的 DEX/SO。

内存搜索

1
2
3
4
5
6
7
8
# 搜索字符串
memory search "password"
memory search "api_key"
memory search "token"

# 搜索十六进制模式
memory search "50 4b 03 04"  # ZIP 文件头
memory search "64 65 78 0a"  # DEX 文件头

堆分析

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# 搜索堆中的对象实例
android heap search instances com.example.app.model.User

# 输出示例:
# Hashcode    Class                          toString()
# ----------  ----------------------------   ------------------
# 123456      com.example.app.model.User     User{name=admin}
# 789012      com.example.app.model.User     User{name=guest}

# 调用实例方法
android heap execute 123456 getToken

# 进入交互模式操作实例
android heap evaluate 123456
# 进入编辑器后输入 JavaScript:
# console.log(clazz.username.value)
# console.log(clazz.password.value)
# console.log(clazz.getToken())

Activity / Service 操作

列出组件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 列出所有 Activity
android hooking list activities

# 输出示例:
# com.example.app.MainActivity
# com.example.app.LoginActivity
# com.example.app.SettingsActivity
# com.example.app.debug.DebugActivity    <-- 可能是隐藏的调试页面

# 列出所有 Service
android hooking list services

# 列出所有 BroadcastReceiver
android hooking list receivers

获取当前 Activity

1
2
3
4
5
android hooking get current_activity

# 输出示例:
# Activity: com.example.app.MainActivity
# Fragment: HomeFragment

启动 Activity

1
2
3
4
5
# 直接启动指定 Activity(绕过正常导航流程)
android intent launch_activity com.example.app.debug.DebugActivity

# 启动需要 Extra 参数的 Activity
android intent launch_activity com.example.app.DetailActivity

实战技巧: 有些应用会在 AndroidManifest 中声明调试用的 Activity(如 DebugActivityTestActivity),但在正常流程中不会展示。通过 list activities 找到它们后直接启动,往往能发现隐藏功能。

Hook Activity 生命周期

1
2
3
4
5
6
# 监控 Activity 的生命周期方法
android hooking watch class_method android.app.Activity.onCreate --dump-args
android hooking watch class_method android.app.Activity.onResume --dump-args

# 监控特定 Activity
android hooking watch class com.example.app.LoginActivity

Service 操作

1
2
3
4
5
# Hook Service 的关键方法
android hooking watch class_method android.app.Service.onStartCommand --dump-args --dump-return

# 监控特定 Service
android hooking watch class com.example.app.SyncService

Keystore 操作

Android Keystore 是应用存储加密密钥的安全容器。Objection 可以列出和提取其中的内容。

列出 Keystore 条目

1
2
3
4
5
6
7
8
9
# 列出 Android Keystore 中的所有密钥别名
android keystore list

# 输出示例:
# Alias               Type
# ------------------  ----------------
# my_rsa_key          PrivateKeyEntry
# encryption_key      SecretKeyEntry
# signing_cert        TrustedCertificateEntry

监控 Keystore 操作

1
2
3
4
5
6
7
8
9
# Hook KeyStore 类,观察应用如何使用密钥
android hooking watch class java.security.KeyStore --dump-args --dump-return

# Hook Cipher 类,观察加解密操作
android hooking watch class javax.crypto.Cipher --dump-args --dump-return

# 监控密钥生成
android hooking watch class_method javax.crypto.KeyGenerator.generateKey --dump-return
android hooking watch class_method java.security.KeyPairGenerator.generateKeyPair --dump-return

证书提取

1
2
3
4
5
# Hook 证书加载过程
android hooking watch class_method java.security.KeyStore.getCertificate --dump-args --dump-return

# 监控证书链
android hooking watch class_method java.security.KeyStore.getCertificateChain --dump-args --dump-return

实战:提取应用加密密钥

💡 思路一句话: objection 一行命令 hook Cipher/SecretKeySpec/Mac 等加密类 → 自动打印算法名称、密钥、IV、明文/密文 → 无需手写 Frida 脚本,适合快速获取加密参数。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 1. 搜索加密相关的类
android hooking search classes Crypto
android hooking search classes Cipher
android hooking search classes SecretKey

# 2. 监控 Cipher.init(),获取密钥和 IV
android hooking watch class_method javax.crypto.Cipher.init --dump-args --dump-backtrace

# 3. 监控 SecretKeySpec 构造函数,获取原始密钥字节
android hooking watch class_method javax.crypto.spec.SecretKeySpec.$init --dump-args

# 4. 监控 IvParameterSpec,获取 IV
android hooking watch class_method javax.crypto.spec.IvParameterSpec.$init --dump-args

Hook 功能

Watch 命令详解

android hooking watch 是 Objection 最核心的命令,支持多种选项:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 基本用法:Hook 整个类
android hooking watch class com.example.app.CryptoUtil

# Hook 单个方法
android hooking watch class_method com.example.app.CryptoUtil.encrypt

# 完整选项:打印参数 + 返回值 + 调用栈
android hooking watch class_method com.example.app.CryptoUtil.encrypt \
  --dump-args \
  --dump-return \
  --dump-backtrace

各选项说明:

选项说明
--dump-args打印方法被调用时的所有参数
--dump-return打印方法的返回值
--dump-backtrace打印调用栈,显示是谁调用了这个方法

修改返回值

1
2
3
4
5
6
7
8
# 让方法始终返回 true
android hooking set return_value com.example.app.Security.isVPN true

# 让方法始终返回 false
android hooking set return_value com.example.app.Security.isRooted false

# 返回字符串
android hooking set return_value com.example.app.Config.getApiUrl "https://my-proxy.com"

列出已加载的类

1
2
3
4
5
6
7
8
9
# 列出所有类(输出量非常大)
android hooking list classes

# 建议结合搜索使用
android hooking search classes com.example
android hooking search classes encrypt
android hooking search classes certificate
android hooking search classes token
android hooking search classes auth

管理 Hook 任务

每个 watch 命令会创建一个后台任务:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 查看所有活跃的 Hook 任务
jobs list

# 输出示例:
# Job ID  Hooks  Type
# ------  -----  -----
# 1       12     watch-class
# 2       1      watch-method

# 停止某个 Hook 任务
jobs kill 1

数据库操作

列出数据库

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 列出应用的所有 SQLite 数据库
android hooking search classes SQLiteDatabase

# 或者直接浏览数据库目录
ls /data/data/com.example.app/databases/

# 输出示例:
# Type   Size      Name
# -----  --------  ---------------
# File   2.1 MB    app.db
# File   32.0 KB   app.db-journal
# File   512.0 KB  analytics.db

连接并查询数据库

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 连接数据库
sqlite connect /data/data/com.example.app/databases/app.db

# 查看所有表
sqlite execute query "SELECT name FROM sqlite_master WHERE type='table';"

# 查询表结构
sqlite execute query "PRAGMA table_info(users);"

# 查询数据
sqlite execute query "SELECT * FROM users;"
sqlite execute query "SELECT username, token FROM users WHERE id=1;"

# 断开连接
sqlite disconnect

下载数据库到本机分析

1
2
3
4
5
6
7
8
# 下载到本机
file download /data/data/com.example.app/databases/app.db ./app.db

# 在本机使用 sqlite3 打开
# sqlite3 ./app.db
# .tables
# .schema users
# SELECT * FROM users;

监控数据库操作

1
2
3
4
5
6
# Hook SQLiteDatabase 的 query 方法,观察应用执行了哪些 SQL
android hooking watch class_method android.database.sqlite.SQLiteDatabase.rawQuery --dump-args
android hooking watch class_method android.database.sqlite.SQLiteDatabase.execSQL --dump-args

# Hook ContentProvider
android hooking watch class_method android.content.ContentResolver.query --dump-args --dump-backtrace

实战组合技

💡 思路一句话: objection 的强大在于「组合使用」— SSL pinning bypass + 内存搜索 + 加密类 hook + 文件监控,四合一覆盖大部分逆向场景,一个工具搞定 80% 的工作。

场景一:分析登录流程

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# 第 1 步:禁用 SSL Pinning 以便抓包
android sslpinning disable

# 第 2 步:找到登录相关的类
android hooking search classes Login
android hooking search classes Auth
android hooking search classes Credential

# 第 3 步:列出目标类的方法
android hooking list class_methods com.example.app.LoginManager

# 第 4 步:Hook 登录方法,观察参数
android hooking watch class_method com.example.app.LoginManager.login \
  --dump-args --dump-return --dump-backtrace

# 第 5 步:Hook 加密方法,看密码如何被加密
android hooking watch class_method com.example.app.CryptoUtil.encrypt \
  --dump-args --dump-return

# 第 6 步:在 App 中执行登录操作,观察输出

场景二:提取应用 Token

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 方法一:从 SharedPreferences 中直接读取
cat /data/data/com.example.app/shared_prefs/auth.xml

# 方法二:从堆中搜索 Token 对象
android heap search instances com.example.app.model.AuthToken
android heap execute <hashcode> getAccessToken

# 方法三:Hook 网络请求,从 Header 中获取
android hooking watch class_method okhttp3.Request.header --dump-args --dump-return
android hooking watch class_method okhttp3.Request$Builder.addHeader --dump-args

场景三:绕过多重保护分析加密

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# 第 1 步:绕过安全检测
android root disable
android sslpinning disable

# 第 2 步:搜索加密相关类
android hooking search classes Cipher
android hooking search classes AES
android hooking search classes encrypt

# 第 3 步:Hook 加密入口
android hooking watch class_method javax.crypto.Cipher.doFinal --dump-args --dump-return
android hooking watch class_method javax.crypto.Cipher.init --dump-args --dump-backtrace

# 第 4 步:Hook 密钥生成
android hooking watch class_method javax.crypto.spec.SecretKeySpec.$init --dump-args

# 第 5 步:操作应用触发加密流程,从输出中收集:
#   - 加密算法(AES/DES/RSA)
#   - 密钥字节
#   - IV 向量
#   - 明文和密文

场景四:快速信息收集

1
2
3
4
5
6
7
# 一次性执行多条命令快速了解应用
objection -g com.example.app explore \
  --startup-command "android hooking list activities" \
  --startup-command "android hooking list services" \
  --startup-command "android hooking list receivers" \
  --startup-command "android keystore list" \
  --startup-command "env"

Objection vs Frida CLI

什么时候用 Objection

场景推荐工具原因
快速禁用 SSL PinningObjection一条命令搞定
搜索类和方法Objection内置搜索命令,无需写代码
浏览文件系统Objection交互式 Shell 体验更好
简单的方法 HookObjectionwatch 命令即可
修改方法返回值Objectionset return_value 一行搞定
复杂的参数构造/修改Frida CLI需要 JavaScript 灵活处理
批量 Hook + 自定义逻辑Frida CLI脚本更灵活,可以写循环和条件判断
Native 层 Hook (Interceptor)Frida CLIObjection 对 Native Hook 支持有限
自动化测试脚本Frida CLIPython 绑定更适合自动化
RPC 远程调用Frida CLI需要 frida.get_remote_device() 等 API

组合使用

Objection 和 Frida 并不是二选一的关系,最高效的方式是组合使用:

1
2
3
4
5
6
7
8
# 1. 用 Objection 快速侦察
objection -g com.example.app explore
# > android hooking search classes Encrypt
# > android hooking list class_methods com.example.app.EncryptUtil
# > android hooking watch class_method com.example.app.EncryptUtil.encrypt --dump-args

# 2. 发现目标后,导入自定义 Frida 脚本进行精细操作
import /path/to/custom_hook.js

在 Objection Shell 中导入自定义脚本:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 导入脚本
import /path/to/my_script.js

# 脚本示例(my_script.js):
# Java.perform(function() {
#     var EncryptUtil = Java.use("com.example.app.EncryptUtil");
#     EncryptUtil.encrypt.overload("java.lang.String").implementation = function(input) {
#         console.log("[*] encrypt 输入: " + input);
#         var result = this.encrypt(input);
#         console.log("[*] encrypt 输出: " + result);
#         // 可以在这里修改参数或返回值
#         return result;
#     };
# });

总结

1
2
3
4
5
6
7
初步侦察 / 快速验证  -->  Objection(零代码,交互式)
     |
     v
深入分析 / 自动化     -->  Frida CLI(脚本灵活,可编程)
     |
     v
生产级方案            -->  Frida Python 绑定 + 自定义 Agent

Objection 是逆向分析的"瑞士军刀",适合快速上手和初步侦察。当需要更复杂的逻辑时,再切换到原生 Frida 脚本。两者配合使用,可以显著提升逆向效率。


相关内容

如果这篇文章对你有帮助,请我喝杯咖啡吧~
+5 支付宝支付宝
+5 微信微信