Frida使用NativeFunction主动调用so中的函数

function printJavaStack(name) {
    Java.perform(function () {
        var Exception = Java.use("java.lang.Exception");
        var ins = Exception.$new("Exception");
        var straces = ins.getStackTrace();
        if (straces != undefined && straces != null) {
            var strace = straces.toString();
            var replaceStr = strace.replace(/,/g, " \n ");
            LogPrint("=============================" + name + " Stack strat=======================");
            LogPrint(replaceStr);
            LogPrint("=============================" + name + " Stack end======================= \n ");
            Exception.$dispose();
        }
    });
}

function LogPrint(log) {
    var theDate = new Date();
    var hour = theDate.getHours();
    var minute = theDate.getMinutes();
    var second = theDate.getSeconds();
    var mSecond = theDate.getMilliseconds();

    hour < 10 ? hour = "0" + hour : hour;
    minute < 10 ? minute = "0" + minute : minute;
    second < 10 ? second = "0" + second : second;
    mSecond < 10 ? mSecond = "00" + mSecond : mSecond < 100 ? mSecond = "0" + mSecond : mSecond;

    var time = hour + ":" + minute + ":" + second + ":" + mSecond;
    var threadid = Process.getCurrentThreadId();
    console.log("[" + time + "]" + "->threadid:" + threadid + "--" + log);

}

function hookCipher() {
    if (Java.available) {
        Java.perform(function () {
                Java.use('javax.crypto.Cipher').getInstance.overload('java.lang.String').implementation = function (arg0) {
                    console.log('javax.crypto.Cipher.getInstance is called!', arg0);

                    if (arg0.indexOf("") != -1) {
                        printJavaStack("Cipher.getInstance() is called");
                    }
                    var result = this.getInstance(arg0);
                    return result;
                };
                //.init(Cipher.ENCRYPT_MODE, getRawKey(key), iv);
                Java.use('javax.crypto.Cipher').init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec').implementation = function (arg0, arg1, arg2) {
                    //console.log('javax.crypto.Cipher.init is called!', arg0, arg1, arg2);
                    var mode = arg0;
                    var key = arg1;
                    var iv = arg2;
                    var KeyClass = Java.use('java.security.Key');

                    var keyobj = Java.cast(key, KeyClass);
                    var key_bytes = keyobj.getEncoded();
                    var StringClass = Java.use("java.lang.String");
                    var key_string = StringClass.$new(key_bytes);
                    console.log("key:", key_string);
                    var IVClass = Java.use('javax.crypto.spec.IvParameterSpec');
                    var ivobj = Java.cast(iv, IVClass);
                    var iv_bytes = ivobj.getIV();
                    var iv_string = StringClass.$new(iv_bytes);
                    console.log("iv:", iv_string);
                    console.log('javax.crypto.Cipher.init is called!', mode, JSON.stringify(key_bytes), JSON.stringify(iv_bytes));
                    var result = this.init(arg0, arg1, arg2);
                    return result;
                };
                Java.use('javax.crypto.Cipher').doFinal.overload('[B').implementation = function (arg0) {
                    console.log('javax.crypto.Cipher.doFinal is called!', JSON.stringify(arg0));
                    var data = arg0;
                    var StringClass = Java.use("java.lang.String");
                    var data_string = StringClass.$new(data);
                    console.log("data:", data_string);
                    var result = this.doFinal(arg0);
                    console.log('javax.crypto.Cipher.doFinal is called!', JSON.stringify(data));
                    console.log('\n ----------------\n ', "encrypt:", JSON.stringify(result), '\n ----------------\n ');
                    return result;
                };
                //doFinal
            }
        )
    }
}

var sub_9744=null;
function hookso() {
    var nativelibmodul = Process.getModuleByName("libnative-lib.so");
    var sub_9744_addr = nativelibmodul.base.add(0x9745);
    console.log("sub_9744:",sub_9744_addr);
    sub_9744=new NativeFunction(sub_9744_addr, 'pointer', ['pointer','pointer','pointer']);
    Interceptor.attach(sub_9744_addr, {
        onEnter: function (args) {
            console.log("sub_9744_addr arg0:", hexdump(args[0]));
            console.log("sub_9744_addr arg1:", hexdump(args[1]));
            console.log("sub_9744_addr arg2:", hexdump(args[2]));

        }, onLeave: function (retval) {
            console.log("sub_9744_addr retval:", hexdump(ptr(retval)));
        }
    })
}
function activecallsub_9744() {

    var arg0=Memory.alloc(21);
    ptr(arg0).writeUtf8String('qazwsxedcrfvtgbyhnujm');
    var arg1=Memory.alloc(21);
    ptr(arg1).writeUtf8String('0123456789abcdef');
    var arg2=Memory.alloc(21);
    ptr(arg2).writeUtf8String('0123456789abcdef');
    var retval=sub_9744(arg0,arg1,arg2);
    console.log("activecallsub_9744",hexdump(ptr(retval)));

}
function main() {
    if (Java.available) {
        Java.perform(function () {
            Java.use('java.lang.Runtime').loadLibrary0.implementation = function (arg0,arg1) {
                console.log("Runtime.loadLibrary0->", arg1);
                var result = this.loadLibrary0(arg0,arg1);
                if (arg1.indexOf('native-lib') != -1) {
                    hookso();
                }

                return result;


            }

        })
    }
}

setImmediate(main);
function activite_invoke() {
    if (Java.available) {
        Java.perform(function () {
            Java.choose("com.example.demoso1.MainActivity", {
                onMatch: function (instance) {
                    console.log("MainActivity instance!");
                    instance.init();
                }, onComplete: function () {
                    console.log("search MainActivity complete!")
                }
            })

        })
    }
}

function pthread_create_hook() {
    var pthread_create_addr = Module.findExportByName("libc.so", "pthread_create");
    console.log("pthread_create_addr =>", pthread_create_addr);
    var time_addr = Module.findExportByName("libc.so", "time");
    var pthread_create = new NativePointer(pthread_create_addr, 'int', ['pointer', 'pointer', 'pointer', 'pointer']);
    Interceptor.attach(pthread_create_addr, {
        onEnter: function (args) {
            console.log('pthread_create onEnter =>', args[0], args[1], args[2], args[3]);
            var natvie_lib_addr = Module.findBaseAddress("libnative-lib.so");
            if (natvie_lib_addr != null) {
                console.log("native-lib =>", natvie_lib_addr);
                console.log("loop function offset =>", args[2] - natvie_lib_addr);
                if (args[2] - natvie_lib_addr === 64944) {
                    args[2] = time_addr;
                }

            }
        }, onLeave: function (retvale) {
            console.log("pthread_create onLeave =>", retvale);

        }
    })

}

function pthread_replace() {
    var pthread_create_addr = Module.findExportByName("libc.so", "pthread_create");
    console.log("pthread_create_addr =>", pthread_create_addr);
    var pthread_create = new NativeFunction(pthread_create_addr, 'int', ['pointer', 'pointer', 'pointer', 'pointer']);
    // Interceptor.replace(pthread_create_addr, new NativeCallback(function (parg0, parg1, parg2, parg3) {
    //     var native_lib_addr = Module.findBaseAddress("libnative-lib.so");
    //     if (native_lib_addr != null) {
    //         var addrss = parg2 - native_lib_addr;
    //         if (addrss ==64900) {
    //             return null;
    //         }
    //     }
    //     return pthread_create(parg0, parg1, parg2, parg3)
    Interceptor.replace(pthread_create_addr, new NativeCallback(function (parg1, parg2, parg3, parg4) {
        console.log(parg1, parg2, parg3, parg4)
        var libnativebaseaddress = Module.findBaseAddress("libnative-lib.so")
        if (libnativebaseaddress != null) {
            console.log("libnativebaseaddress=>", libnativebaseaddress);
            if (parg3 - libnativebaseaddress == 64944) {
                return null;
            }
        }
        return pthread_create(parg1, parg2, parg3, parg4)
    }, "int", ["pointer", "pointer", "pointer", "pointer"]))

}

function replace_pthread() {
    var pthread_create_addr = Module.findExportByName("libc.so", "pthread_create");
    console.log("pthread_create_addr=>", pthread_create_addr)
    var pthread_create = new NativeFunction(pthread_create_addr, "int", ["pointer", "pointer", "pointer", "pointer"])
    Interceptor.replace(pthread_create_addr, new NativeCallback(function (parg1, parg2, parg3, parg4) {
        console.log(parg1, parg2, parg3, parg4)
        var libnativebaseaddress = Module.findBaseAddress("libnative-lib.so")
        if (libnativebaseaddress != null) {
            console.log("libnativebaseaddress=>", libnativebaseaddress);
            if (parg3 - libnativebaseaddress == 64944) {
                return 0;
            }
        }
        return pthread_create(parg1, parg2, parg3, parg4)
    }, "int", ["pointer", "pointer", "pointer", "pointer"]))
}

function write_something(path, content) {
    var fopen_addr = Module.findExportByName('libc.so', 'fopen');
    var fputs_addr = Module.findExportByName('libc.so', 'fputs');
    var fclose_addr = Module.findExportByName('libc.so', 'fclose');

    console.log('fopen_addr=>', fopen_addr, 'fputs_addr=>', fputs_addr, 'fclose_addr=>', fclose_addr)

    var fopen = new NativeFunction(fopen_addr, 'pointer', ['pointer', 'pointer'])
    var fputs = new NativeFunction(fputs_addr, 'int', ['pointer', 'pointer'])
    var fclose = new NativeFunction(fclose_addr, 'int', ['pointer'])

    var file_name = Memory.allocUtf8String(path)
    var mode = Memory.allocUtf8String('a+')

    var fp = fopen(file_name, mode)
    var content = Memory.allocUtf8String(content)
    fputs(content, fp)
    fclose(fp)
}

function enumerate_all_exports() {

    var modules = Process.enumerateModules()
    for (var i = 0; i < modules.length; i++) {
        var module = modules[i];
        var module_name = module.name
        var exports = module.enumerateExports()
        // console.log('module.name=>', module_name, "module.enumerateExports=>", JSON.stringify(exports))
        for (var m = 0; m < exports.length; m++) {
            // console.log('m=>', m)
            write_something('/sdcard/data/' + module_name + '.txt', 'type:' + exports[m].type + ' name:' + exports[m].name + '\n')
        }
    }

}

function main() {
    // pthread_create_hook()
    // pthread_replace();
    // replace_pthread();
    // write_something()
    enumerate_all_exports()

}


setImmediate(main)




function EnumerateAllExports(){
    var modules = Process.enumerateModules();
    //console.log("Process.enumerateModules => ",JSON.stringify(modules))
    for(var i=0;i<modules.length;i++){
        var module = modules[i];
        var module_name = modules[i].name;
        var exports = module.enumerateExports();
        console.log("module_name=>",module_name,"  module.enumerateExports = > ",JSON.stringify(exports))
    }
}

function hook_JNI(){

    var GetStringUTFChars_addr = null;
    var symbols = Process.findModuleByName("libart.so").enumerateSymbols()
    //console.log(JSON.stringify(symbols))
    for(var i = 0;i<symbols.length;i++){
        var symbol = symbols[i].name;
        if((symbol.indexOf("CheckJNI")==-1)&&(symbol.indexOf("JNI")>=0)){
            if(symbol.indexOf("GetStringUTFChars")>=0){
                console.log("finally found GetStringUTFChars name :",symbol);
                GetStringUTFChars_addr =symbols[i].address ;
                console.log("finally found GetStringUTFChars address :",GetStringUTFChars_addr);
            }
        }
    }
    Interceptor.attach(GetStringUTFChars_addr,{
        onEnter:function(args){
            console.log("art::JNI::GetStringUTFChars(_JNIEnv*, _jstring*, unsigned char*)=>",args[0],Java.vm.getEnv().getStringUtfChars( args[1],null).readCString(),args[2]);
            // console.log('CCCryptorCreate called from:\n' +
            // Thread.backtrace(this.context, Backtracer.ACCURATE)
            // .map(DebugSymbol.fromAddress).join('\n') + '\n');
        },onLeave:function(retval){
            console.log("retval is => ",retval.readCString());
        }
    })
}

function replace_JNI(){
    var NewStringUTF_addr = null;
    var symbols = Process.findModuleByName("libart.so").enumerateSymbols()
    //console.log(JSON.stringify(symbols))
    for(var i = 0;i<symbols.length;i++){
        var symbol = symbols[i].name;
        if((symbol.indexOf("CheckJNI")==-1)&&(symbol.indexOf("JNI")>=0)){
            if(symbol.indexOf("NewStringUTF")>=0){
                console.log("finally found NewStringUTF_name :",symbol);
                NewStringUTF_addr =symbols[i].address ;
                console.log("finally found NewStringUTF_addr :",NewStringUTF_addr);
            }
        }
    }
    var NewStringUTF = new NativeFunction(NewStringUTF_addr,"pointer",["pointer","pointer"])
    Interceptor.replace(NewStringUTF_addr,
        new NativeCallback(function(parg1,parg2){
            console.log("parg1,parg2=>",parg1,parg2.readCString());
            // console.log('CCCryptorCreate called from:\n' +
            //  Thread.backtrace(this.context, Backtracer.ACCURATE)
            //  .map(DebugSymbol.fromAddress).join('\n') + '\n');
            var newPARG2 = Memory.allocUtf8String("newPARG2")
            var result = NewStringUTF(parg1,newPARG2);
            return result;
        },"pointer",
        ["pointer","pointer"]))
}

function hook_RegisterNatives(){
    var RegisterNatives_addr = null;
    var symbols = Process.findModuleByName("libart.so").enumerateSymbols()
    //console.log(JSON.stringify(symbols))
    for(var i = 0;i<symbols.length;i++){
        var symbol = symbols[i].name;
        if((symbol.indexOf("CheckJNI")==-1)&&(symbol.indexOf("JNI")>=0)){
            if(symbol.indexOf("RegisterNatives")>=0){
                console.log("finally found RegisterNatives_name :",symbol);
                RegisterNatives_addr =symbols[i].address ;
                console.log("finally found RegisterNatives_addr :",RegisterNatives_addr);
            }
        }
    }

    if(RegisterNatives_addr!=null){
        Interceptor.attach(RegisterNatives_addr,{
            onEnter:function(args){
                console.log("[RegisterNatives]method counts :",args[3]);
                var env = args[0];
                var jclass = args[1];
                var class_name = Java.vm.tryGetEnv().getClassName(jclass);
                var methods_ptr = ptr(args[2]);
                var method_count = parseInt(args[3]);
                for (var i = 0; i < method_count; i++) {
                    var name_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3));
                    var sig_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize));
                    var fnPtr_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize * 2));
                    var name = Memory.readCString(name_ptr);
                    var sig = Memory.readCString(sig_ptr);
                    var find_module = Process.findModuleByAddress(fnPtr_ptr);
                    console.log("[RegisterNatives] java_class:", class_name, "name:", name, "sig:", sig, "fnPtr:", fnPtr_ptr, "module_name:", find_module.name, "module_base:", find_module.base, "offset:", ptr(fnPtr_ptr).sub(find_module.base));
                }
            },onLeave:function(retval){
            }
        })

    }else{
        console.log("didn`t found RegisterNatives address")
    }

}

setImmediate(hook_RegisterNatives);

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Frida是一款功能强大的动态插桩框架,可以用于实时分析、修改和控制Android、iOS和Windows应用程序。它运行在主机上并与目标应用程序进行通信,可以访问和操作应用程序的内部数据和行为。 Frida主动调用是指通过Frida框架的一些API函数,应用程序可以主动调用一些指定的函数或方法。通过主动调用,我们可以在运行时动态修改应用程序的行为,即在代码执行过程注入自己的代码,并对应用程序进行操作。 使用Frida进行主动调用通常需要以下步骤: 1. 在主机上安装Frida,并获取目标应用程序的进程ID或进程名称。 2. 编写一个Frida脚本,通过Frida的API函数创建一个会话,并连接到目标应用程序。 3. 在会话使用Frida的API函数定位到要调用函数或方法,并设置好参数。 4. 使用Frida的API函数发起主动调用,并接收返回结果。 5. 处理返回结果,并根据需要进行进一步操作。 例如,在Android应用程序,我们可以使用FridaJava API函数来定位到某个对象的方法,并通过主动调用来触发该方法的执行。这样可以绕过应用程序的某些限制或修改某些功能的行为。 总的来说,Frida主动调用功能为开发者提供了一种在目标应用程序主动操作和控制的方式,通过注入自己的代码,可以实现一些特定需求或调试目的。无论是动态修改应用程序行为还是进行逆向分析,Frida主动调用功能都是非常有用的工具之一。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值