Frida + Android Hook 完整指南

Frida + Android Hook 完整指南

    • [Frida 原理与架构](#Frida 原理与架构)
    • 环境搭建
    • 手机端准备(adb+frida-server)
    • App脱壳
    • [Java 层 Hook(最常用)](#Java 层 Hook(最常用))
      • [1. 静态分析找目标(jadx)](#1. 静态分析找目标(jadx))
      • [2. 编写 Frida JS 脚本(hook_java.js)](#2. 编写 Frida JS 脚本(hook_java.js))
      • [3. 运行脚本](#3. 运行脚本)
    • [Native 层 Hook(so 库)](#Native 层 Hook(so 库))
      • [1. 场景](#1. 场景)
      • [2. 脚本模板(hook_native.js)](#2. 脚本模板(hook_native.js))
    • [常用 Hook 脚本模板](#常用 Hook 脚本模板)
      • [1. 打印方法调用栈](#1. 打印方法调用栈)
      • [2. Hook 构造方法](#2. Hook 构造方法)
      • [3. 枚举所有类 / 方法](#3. 枚举所有类 / 方法)
    • 总结

Frida 原理与架构

包含:环境搭建、Java 层 Hook、Native 层 Hook、常用脚本模板、常见坑与排查。内容偏实操,直接能用

Frida 是动态插桩框架,可以在不修改 APK、不重启设备的情况下,向运行中的 App 注入 JS 脚本,Hook Java 或 Native 函数。

架构:PC 客户端(frida) + 手机端服务端(frida-server)

语言:PC 端 Python,注入脚本 JavaScript

支持:Android、iOS、Windows、macOS、Linux

环境搭建

bash 复制代码
# 安装frida 16.x 稳定兼容版
pip install frida==16.2.1 frida-tools==12.3.0
# 验证:
frida --version
# 列出手机进程
frida-ps -U  

frida-ps -U 之前需启动模拟器

手机端准备(adb+frida-server)

必须 Root(真机或模拟器,推荐雷电 / Genymotion)

如果连 adb.exe 都没有,需要先下载 Android SDK Platform Tools:
adb-SDK下载

把压缩包解压到一个固定目录,比如 D:\platform-tools

把这个目录添加到系统环境变量 Path 里

重启 CMD,输入 adb --version 验证是否成功

进入adb shell 查看架构,根据架构下载对应的firda-server,这里x86_64

bash 复制代码
getprop ro.product.cpu.abi

frida-server下载:https://github.com/frida/frida/releases/

这里的server版本跟之前的frida版本保持一致,防止出错

在 Assets 列表里,往下翻找到 frida-server-16.2.1-android-x86_64.xz

直达地址:https://github.com/frida/frida/releases/download/16.2.1/frida-server-16.2.1-android-x86_64.xz

(注意:不是 frida-core-devkit,文件名里必须有 frida-server)

解压 .xz 文件,得到 frida-server-16.2.1-android-x86_64;

将 frida-server推送到模拟器里:

bash 复制代码
# 推送到手机或模拟器(选择/data/local/tmp 目录,因为其它目录有的不可写,可能会写入失败)
adb push frida-server-17.9.10-android-x86_64 /data/local/tmp/
# 进入adb shell
adb shell
# 管理员
su
# 加执行权限
chmod 755 /data/local/tmp/frida-server-17.9.10-android-x86_64
# 启动server
/data/local/tmp/frida-server-17.9.10-android-x86_64 &


App脱壳

逆向 hook之前先查看app基本信息,是否加壳,如果有安装firda-dexdump进行脱壳导出.dex文件

bash 复制代码
# 安装对应的版本2.0.1
pip install frida-dexdump==2.0.1

frida-dexdump 2.0.1 是 2024 年 4 月发布,实测与 Frida 16.x(含 16.2.1)完全兼容。

它不强制绑定特定 Frida 小版本,只要 Frida ≥12 基本都能用,但16.2.1 + 2.0.1 是最稳组合。

配套的 frida-server 也要用 16.2.1(与客户端一致)

安装完成后进adb shell,启动frida-server,然后运frida-dexdump -U -f com.app.pkgname导出指定包名的应用的dex文件

导出后得到dex包,对他们使用d2j-dex2jar.bat转换为jar包,然后用jadx-gui查看源码

至于未加固的apk可直接拖入jadx-jui中查看

Java 层 Hook(最常用)

1. 静态分析找目标(jadx)

用 jadx-gui 打开 APK(.dex文件),找到要 Hook 的类和方法,例如:

java 复制代码
package com.example.crypto;
public class MainActivity {
    private String encrypt(String data) { ... }
}
  • 类名:com.example.crypto.MainActivity
  • 方法:encrypt(String)

2. 编写 Frida JS 脚本(hook_java.js)

js 复制代码
Java.perform(function () {
    console.log("[*] 开始 Hook Java 方法");

    // 1. 获取目标类
    var MainActivity = Java.use("com.example.crypto.MainActivity");

    // 2. Hook 方法(参数类型要匹配)
    MainActivity.encrypt.implementation = function (data) {
        console.log("[+] 原方法被调用,参数:" + data);

        // 调用原方法
        var result = this.encrypt(data);

        console.log("[+] 原方法返回值:" + result);

        // 可篡改返回值
        // return "fake_data";
        return result;
    };
});

3. 运行脚本

将frida-server端口转发到本地

bash 复制代码
# frida-server 默认端口为 27042
adb forward tcp:27042 tcp:27042

用脚本去frida app

bash 复制代码
# 方式1:spaw模式注入App(app未启动时注入,自动启动app)
frida -U -f <包名> -l hook_java.js

# 方式2:启动App后并注入
frida -U -p <pid> -l hook_java.js

jadx 反编译 APK,定位目标类 / 方法

选中相应的函数复制为frida代码片段

构造的hook 代码

Frida 注入脚本,观察日志 / 篡改返回值

bash 复制代码
frida -U -f com.example.crypto -l hook_java.js

有时候,-f(spawn 模式)会在 App 刚启动时注入,容易触发崩溃,改用附加模式:

  • 先在模拟器里手动打开 App,让它运行起来
  • 用 frida-ps -U 查看进程 PID
  • 用附加模式注入脚本:
bash 复制代码
frida -U -p <pid> -l hook.js

Native 层 Hook(so 库)

1. 场景

App 用 so 库(libxxx.so)做加密 / 校验,需要 Hook JNI 函数或导出函数。

2. 脚本模板(hook_native.js)

js 复制代码
setImmediate(function () {
    Java.perform(function () {
        console.log("[*] 等待 libxxx.so 加载...");
        // 监听 so 加载
        var System = Java.use("java.lang.System");
        System.loadLibrary.implementation = function (libname) {
            this.loadLibrary(libname);
            if (libname === "xxx") { // libxxx.so
                console.log("[+] libxxx.so 已加载,开始 Hook");
                hookNativeFunc();
            }
        };
    });
});

function hookNativeFunc() {
    // 1. 找导出函数地址
    var funcPtr = Module.findExportByName("libxxx.so", "Java_com_example_crypto_MainActivity_nativeEncrypt");
    if (!funcPtr) {
        console.log("[-] 未找到函数");
        return;
    }
    console.log("[*] 函数地址:" + funcPtr);

    // 2. Hook
    Interceptor.attach(funcPtr, {
        onEnter: function (args) {
            console.log("[+] Native 方法进入");
            // args[0] = JNIEnv*, args[1] = jobject, args[2] = 参数1
            // 读取字符串参数
            var data = Java.vm.getEnv().getStringUtfChars(args[2], null);
            console.log("[+] 参数:" + data.readCString());
        },
        onLeave: function (retval) {
            console.log("[+] Native 返回值:" + retval);
            // 篡改返回值
            // retval.replace(0);
        }
    });
}

常用 Hook 脚本模板

1. 打印方法调用栈

js 复制代码
Java.perform(function () {
    var stackTrace = Java.use("android.util.Log").getStackTraceString;
    Java.use("java.lang.Throwable").$init.implementation = function () {
        this.$init();
        console.log("[+] 调用栈:\n" + stackTrace(this));
    };
});

2. Hook 构造方法

js 复制代码
Java.perform(function () {
    var Clazz = Java.use("com.example.crypto.CoinMoney");
    Clazz.$init.overload("java.lang.String", "int").implementation = function (a, b) {
        console.log("[+] 构造方法参数:" + a + ", " + b);
        return this.$init(a, b);
    };
});

3. 枚举所有类 / 方法

javascript 复制代码
Java.perform(function () {
    var classFactory = Java.classFactory;
    var classes = classFactory.enumerateClasses();
    for (var i = 0; i < classes.length; i++) {
        console.log(classes[i].getName());
    }
});

总结

  • 装 Frida PC 端 + 手机端 frida-server
  • adx 反编译 APK,定位目标类 / 方法
  • 写 JS 脚本 Hook Java/Native 方法
  • Frida 注入脚本,观察日志 / 篡改返回值
  • 处理反调试 / Frida 检测
相关推荐
jzlhll1235 小时前
Kotlin 协程高级用法之 NonCancellable
android·开发语言·kotlin
lxysbly5 小时前
2026 年 Android PSV模拟器下载推荐(汉化版)
android
2501_916008895 小时前
Mac 上生成 AppStoreInfo.plist 文件,App Store 上架
android·macos·ios·小程序·uni-app·iphone·webview
JohnnyDeng946 小时前
Paging 3 分页加载架构全解析:从数据源到 UI 的完整链路
android·ui·kotlin
1001101_QIA6 小时前
Flutter 开发报错:Android cmdline-tools 缺失 环境排查与完整修复方案
android·flutter
caron47 小时前
逆向--Android DEX 文件格式与 Smali 语言
android
zb200641207 小时前
Laravel5.x核心特性全解析
android·spring boot·php·laravel
_李小白7 小时前
【android opencv学习笔记】Day 21: 形态学开运算与闭运算
android·opencv·学习