Play Open
Loading Please wait Loading Please wait Loading Please wait Loading Please wait Loading Please wait Loading Please wait

Frida + Android Hook 完整指南

@

目录Frida 原理与架构环境搭建手机端准备(adb+frida-server)App脱壳Java 层 Hook(最常用)1. 静态分析找目标(jadx)2. 编写 Frida JS 脚本(hook_java.js)3. 运行脚本Native 层 Hook(so 库)1. 场景2. 脚本模板(hook_native.js)常用 Hook 脚本模板1. 打印方法调用栈2. Hook 构造方法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

环境搭建

# 安装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

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推送到模拟器里:

# 推送到手机或模拟器(选择/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文件

# 安装对应的版本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 的类和方法,例如:

package com.example.crypto;

public class MainActivity {

private String encrypt(String data) { ... }

}

类名:com.example.crypto.MainActivity

方法:encrypt(String)

2. 编写 Frida JS 脚本(hook_java.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端口转发到本地

# frida-server 默认端口为 27042

adb forward tcp:27042 tcp:27042

用脚本去frida app

# 方式1:spaw模式注入App(app未启动时注入,自动启动app)

frida -U -f <包名> -l hook_java.js

# 方式2:启动App后并注入

frida -U -p -l hook_java.js

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

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

构造的hook 代码

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

frida -U -f com.example.crypto -l hook_java.js

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

先在模拟器里手动打开 App,让它运行起来

用 frida-ps -U 查看进程 PID

用附加模式注入脚本:

frida -U -p -l hook.js

Native 层 Hook(so 库)

1. 场景

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

2. 脚本模板(hook_native.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. 打印方法调用栈

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 构造方法

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. 枚举所有类 / 方法

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 检测

Copyright © 2088 足球小将世界杯_1999年美国女足世界杯 - omaili.com All Rights Reserved.
友情链接