乐于分享
好东西不私藏

安卓逆向系列 04:Frida Java 层 Hook 实战

安卓逆向系列 04:Frida Java 层 Hook 实战

绝大多数 App 的核心业务逻辑都在 Java 层。掌握 Java Hook,你能实时拦截任意方法调用、查看明文数据、修改函数返回值。



一、Java Hook 原理

如图所示,Frida 在目标方法执行前后插入两个回调:

  • onEnter:方法执行前触发,可以读取/修改参数 args[]

  • onLeave:方法执行后触发,可以读取/修改返回值 retval

  • 也可以完全替换整个方法的实现(implementation

所有操作都在 Java.perform() 回调内执行,确保在 Java VM 上下文中运行。


二、Hook 普通方法

Java.perform(function() {varLoginUtil=Java.use("com.example.auth.LoginUtil");LoginUtil.checkPassword.implementation=function(password) {// 打印参数console.log("[*] checkPassword 被调用,密码:"+password);// 调用原始方法,获取返回值varresult=this.checkPassword(password);// 打印返回值console.log("[*] 返回值:"+result);// 可以修改返回值(比如强制返回 true)// return true;returnresult;    };});

三、Hook 重载方法(overload)

当同一方法名有多个重载版本时,必须指定参数类型:

Java.perform(function() {varCrypto=Java.use("com.example.CryptoUtil");// 查看所有重载版本console.log(Crypto.encrypt.overloads);// Hook 特定重载:encrypt(String data, String key)Crypto.encrypt.overload("java.lang.String","java.lang.String"    ).implementation=function(datakey) {console.log("data: "+data);console.log("key:  "+key);returnthis.encrypt(datakey);    };// Hook 另一个重载:encrypt(byte[] data)Crypto.encrypt.overload("[B").implementation=function(data) {varhex=Array.from(data)            .map(b=> ('0'+ (b&0xFF).toString(16)).slice(-2))            .join('');console.log("bytes: "+hex);returnthis.encrypt(data);    };});

四、Hook 构造函数

Java.perform(function() {varRequest=Java.use("com.example.http.Request");// Hook 构造函数用 $initRequest.$init.overload("java.lang.String""java.util.Map")        .implementation=function(urlparams) {console.log("[Request] URL: "+url);console.log("[Request] Params: "+JSON.stringify(params));this.$init(urlparams);  // 调用原始构造函数    };});

五、主动调用方法

不需要等待 App 自然触发,直接在脚本中调用:

Java.perform(function() {// 调用静态方法varSignUtil=Java.use("com.example.SignUtil");varsign=SignUtil.generate("test_body"1713661234);console.log("sign: "+sign);// 调用实例方法(需要先拿到实例)Java.choose("com.example.UserManager", {onMatchfunction(instance) {// 找到内存中已存在的实例varuserId=instance.getCurrentUserId();console.log("当前用户ID: "+userId);        },onCompletefunction() {console.log("扫描完成");        }    });});

六、修改字段值

Java.perform(function() {Java.choose("com.example.UserInfo", {onMatchfunction(instance) {// 读取字段console.log("VIP等级: "+instance.vipLevel.value);// 修改字段值(.value 是 Frida 语法)instance.vipLevel.value=99;instance.isVip.value=true;console.log("修改后: "+instance.vipLevel.value);        },onCompletefunction() {}    });});

七、实战:打印明文登录凭据

Java.perform(function() {// Hook OkHttp Request Builder(常见登录框架)varFormBody=Java.use("okhttp3.FormBody$Builder");FormBody.add.implementation=function(namevalue) {if (name.toString() ==="password"||name.toString() ==="passwd") {console.log("[LOGIN] "+name+" = "+value);        }returnthis.add(namevalue);    };// 同时 Hook 常见加密工具类try {varMD5Util=Java.use("com.example.util.MD5Util");MD5Util.encode.implementation=function(input) {console.log("[MD5 Input] "+input);varresult=this.encode(input);console.log("[MD5 Output] "+result);returnresult;        };    } catch(e) {console.log("MD5Util 未找到: "+e);    }});

八、实战:修改会员等级返回值

Java.perform(function() {varVipService=Java.use("com.example.vip.VipService");// Hook 会员等级查询接口VipService.getUserLevel.implementation=function(userId) {varoriginal=this.getUserLevel(userId);console.log("[VIP] 原始等级: "+original);// 强制返回最高等级return9;    };// Hook 会员权益校验VipService.hasPrivilege.overload("java.lang.String")        .implementation=function(privilegeCode) {console.log("[VIP] 权益查询: "+privilegeCode);returntrue;  // 全部放行    };});

九、完整脚本模板

// template.js —— 复制此模板开始使用"use strict";Java.perform(function() {console.log("[*] 脚本已注入");// ====== 修改这里:目标类和方法 ======varTARGET_CLASS="com.example.TargetClass";varTARGET_METHOD="targetMethod";// =====================================try {varCls=Java.use(TARGET_CLASS);Cls[TARGET_METHOD].overloads.forEach(function(overload) {overload.implementation=function() {varargs=Array.from(arguments).map(String);console.log("[HOOK] "+TARGET_METHOD+"("+args.join(", "+")");varretval=this[TARGET_METHOD].apply(thisarguments);console.log("[HOOK] 返回值: "+retval);returnretval;            };        });console.log("[*] Hook 成功: "+TARGET_CLASS+"."+TARGET_METHOD);    } catch(e) {console.error("[ERROR] "+e.message);    }});

十、常用 Java 类型映射

Java 类型 Frida 中的写法
String "java.lang.String"
int "int"
boolean "boolean"
byte[] "[B"
String[] "[Ljava.lang.String;"
Object "java.lang.Object"
List "java.util.List"
Map "java.util.Map"

下一篇:Frida Native 层 Hook 实战(SO 文件)