jshook 中文文档 下载 App

Java 层 Hook 基础写法——Java.perform + Java.use 入门

基本骨架

Frida 类型脚本 Hook Java 层的标准结构:

Java.perform(function () {
    // 所有 Java 层操作都放在 Java.perform 里
    var TargetClass = Java.use('com.example.app.TargetClass');
    TargetClass.someMethod.implementation = function () {
        // Hook 逻辑:改参数、记日志、改返回值
        console.log('[+] someMethod 被调用了');
        // 调用原方法(记得传参)
        return this.someMethod.apply(this, arguments);
    };
});

逐行拆解

Java.perform

所有与 Java 层相关的操作必须在 Java.perform() 的回调函数里写。它保证 Frida 运行时已准备好,Java 虚拟机已加载。

Java.use

通过全限定类名拿到目标类的包装对象。类名要写完整,包括包名:

// 正确写法
var Activity = Java.use('com.example.app.MainActivity');

// 错误:缺少包名
var Activity = Java.use('MainActivity');

implementation

把目标方法替换成你自己的实现。this 指向方法所属的实例。

常见操作示例

① 记录方法调用

Java.perform(function () {
    var LoginActivity = Java.use('com.example.app.LoginActivity');
    LoginActivity.login.implementation = function (username, password) {
        console.log('[+] login 被调用');
        console.log('    username: ' + username);
        console.log('    password: ' + password);
        return this.login(username, password);
    };
});

② 强制修改返回值

Java.perform(function () {
    var GameManager = Java.use('com.game.GameManager');
    GameManager.isVIP.implementation = function () {
        console.log('[+] isVIP 返回 true');
        return true;   // 不管原逻辑,直接返回 true
    };
});

③ 强制修改参数

Java.perform(function () {
    var ShopActivity = Java.use('com.game.ShopActivity');
    ShopActivity.buyItem.implementation = function (itemId, price) {
        // 把价格改成 0
        price = 0;
        console.log('[+] 购买 item: ' + itemId + ', price 改为 0');
        return this.buyItem(itemId, price);
    };
});

重载方法怎么办

一个方法名可能有多个重载版本(参数类型/数量不同)。Frida 会自动找匹配的,但如果有歧义需要用 .overload() 指定。

详见 重载方法指定。

私有方法和私有类

Java.use 也能拿到私有类,implementation 也能替换私有方法——Frida 不做访问控制检查。Java 层的 public/private 对 Frida 透明。

调用原方法

替换了 implementation 之后,原来的方法就被覆盖了。要让原逻辑继续执行(只是加日志或改参数),需要在你的实现里手动调原方法。

两种方式:

// 方式一:arguments 转发(推荐,不用记参数名)
TargetClass.method.implementation = function () {
    // 你的逻辑
    return this.method.apply(this, arguments);
};

// 方式二:显式传参
TargetClass.method.implementation = function (arg1, arg2) {
    // 你的逻辑
    return this.method(arg1, arg2);
};

用 arguments 转发的好处是方法签名变了也不用改你的 Hook 代码。