Android frida hook (学习分享)

frida模块

参考:
https://www.52pojie.cn/thread-1823118-1-1.html
https://www.52pojie.cn/thread-1840174-1-1.html
https://www.52pojie.cn/thread-1859820-1-1.html

环境配置

安装tool

pip install frida-tools

下载对应版本服务
https://github.com/frida/frida/releases
开启服务后在命令行输入frida-ps -U显示手机进程

启用以下命令注入hook

frida -U 进程名 -l hook脚本.js

Frida

内部类用 $ 分割
匿名内部类用 $$ 分割

HOOK方法

普通方法
通过overload来区别重载

function hookTest(){
    var demo = Java.use("com.zj.wuaipojie.Demo");
    demo.a.overload("java.lang.String").implementation = function(str){
        var ret = this.a(str);
        console.log("\na_str:" +str);
        console.log("a_ret:" +ret);
        return ret;
    }
}
function main(){
    Java.perform(function(){
        hookTest();
    });
}
setImmediate(main);

构造方法
将函数名换为$init

function hookTest(){
    var demo = Java.use("com.zj.wuaipojie.Demo");
    demo.$init.overload().implementation = function(){
        this.init();
    }
}
function main(){
    Java.perform(function(){
        hookTest();
    });
}
setImmediate(main);
HOOK变量

静态变量

function hookTest(){
    var demo = Java.use("com.zj.wuaipojie.Demo");
    demo.staticField.value = "hook_test";
    console.log(demo.staticField.value);
}
function main(){
    Java.perform(function(){
        hookTest();
    });
}
setImmediate(main);

成员变量(必须先加载类)

function hookTest() {
    var Demo = Java.use("com.zj.wuaipojie.Demo");
    Demo.$init.overload().implementation = function () {
        console.log("Demo.$init()");
        this.$init();
        this.publicInt.value = 9999;
        this.privateInt.value = 8888;
    };
}
function main() {
    Java.perform(function () {
        hookTest();
    });
}
setImmediate(main);

主动调用

静态方法

function hookTest() {
    var Demo = Java.use("com.zj.wuaipojie.Demo");
    Demo.func();
    };
}
function main() {
    Java.perform(function () {
        hookTest();
    });
}
setImmediate(main);

成员方法(必须先加载类)

function hookTest() {
    var Demo = Java.use("com.zj.wuaipojie.Demo");
    Java.choose("com.zj.wuaipojie.Demo", {
        onMatch: function (instance) {
            console.log("onMatch");
            var ret = instance.privateFunc("aaaaaaaa");
        },
        onComplete: function () {
            console.log("onComplete");
        }
    });
}
function main() {
    Java.perform(function () {
        hookTest();
    });
}
setImmediate(main);

HOOK Native

直接查找函数

function hookNative() {
    var vipLevel = Module.findExportByName("lib52pojie.so", "Java_com_zj_wuaipojie_util_SecurityUtil_vipLevel");
    Interceptor.attach(vipLevel, {
        onEnter: function (args) {
            //1读取参数(string)
            var jString = Java.cast(args[2], Java.use('java.lang.String'));
            console.log("参数:", jString.toString());
            //2读取参数(string)
            var JNIEnv = Java.vm.getEnv();
            var str = JNIEnv.getStringUtfChars(args[2], 0).readCString();
            console.log("参数:", str);
        },
        onLeave: function (retval) {
            //修改返回值(string)
            var JNIEnv = Java.vm.getEnv();
            var jstring = JNIEnv.newStringUtf("至尊会员");
            retval.replace(jstring);
        }
    });  
}

基址+偏移

function hookNative() {
    var base = Module.findBaseAddress("lib52pojie.so");
    var diamondNum = base.add(0x01071C);
    Interceptor.attach(diamondNum, {
        onEnter: function (args) {
  
        },
        onLeave: function (retval) {
            retval.replace(9999);
        }
    });
}

Hook_dlopen

function hookNative() {
    var dlopen = Module.findExportByName(null, "dlopen");
    Interceptor.attach(dlopen, {
        onEnter: function (args) {
            var so_name = args[0].readCString();
            if (so_name.indexOf("lib52pojie.so") >= 0) this.call_hook = true;
        }, onLeave: function (retval) {
            if (this.call_hook) hookJava();
        }
    });
    // 高版本Android系统使用android_dlopen_ext
    var android_dlopen_ext = Module.findExportByName(null, "android_dlopen_ext");
    Interceptor.attach(android_dlopen_ext, {
        onEnter: function (args) {
            var so_name = args[0].readCString();
            if (so_name.indexOf("lib52pojie.so") >= 0) this.call_hook = true;
        }, onLeave: function (retval) {
            if (this.call_hook) hookJava();
        }
    });
}

写数据

const filePath = "/data/user/0/com.zj.wuaipojie/test.txt";
try {
	const file = new File(filePath, "w");
	file.write(str);
	file.flush();
	file.close();
	console.log(`[+] 字符串已写入 ${filePath}`);
} catch (e) {
	console.error(`[!] 文件写入失败: ${e.message}`);
}

Inline hook
直接操作寄存器中的值

function inlinehook(){
    var Check = Module.getBaseAddress("lib52pojie.so").add(0x10428);
    Interceptor.attach(Check, {
        onEnter: function (args) {
            console.log("test:", this.context.x22);
            this.context.x22 = ptr(1);
            console.log("test:", this.context.x22);
        },    
        onLeave: function (retval) {
            console.log("Check ret value: " + retval);
        }
    });
}

so函数调用

function callfunc(){
    var aesAdress = Module.getBaseAddress("lib52pojie.so").add(0xE1C0);
    var aesfunc = new NativeFunction(aesAdress, "pointer", ["pointer", "pointer"]);
    var aeskey = Memory.allocUtf8String("wuaipojie0123456");
    var aesFlag = Memory.allocUtf8String("OOmGYpk6s0qPSXEPp4X31g==");
    var aesRet = aesfunc(aesFlag,aeskey);
    console.log("aesRet:" + aesRet.readCString().toString());
}

frida-trace
跟踪so

frida-trace -U "com.zj.wuaipojie" -F -i "libwuaipojie.so"
posted @ 2025-04-08 13:51  ClownLMe  阅读(108)  评论(0)    收藏  举报