💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
首先安装python环境,安装好python环境后。使用以下命令进行frida的安装: **`pip install frida`** **`pip install frida-tools`** **下载运行在目标机上的frida-sever端,官方下载地址:[https://github.com/frida/frida/releases](https://github.com/frida/frida/releases),下载时要选择对应的版本下载,例如我的机器为arm32为架构,就选择`frida-server-12.8.14-android-arm.xz`下载。(可以在adb使用命令`cat /proc/cpuinfo`查询)** ![](https://img.kancloud.cn/de/4b/de4b04625b2bd33933f390442bcefde9_701x374.png) ![](https://img.kancloud.cn/7a/e4/7ae4f039298c008ae10aa3726137f3cc_693x479.png) ![](https://img.kancloud.cn/f5/83/f5834fae10489e3056f92526f888aca3_704x364.png) ![](https://img.kancloud.cn/35/fb/35fbf68ab97cedb811b4d2a2f3c49965_709x454.png) 前提说明:app名称“fridafirst”,包名“com.feng.frida”。结论:attach后名称以frida-ps -U命令中显示为准,不一定是包名,可能是应用名称。过程:网上看了很多frida教程,process = frida.get_usb_device().attach('com.feng.frida') ,attach()后面大都写的进程的包名,自己进行尝试,一直提示找不的对应进程,换为应用名称后,attach成功。 python脚本: ``` import frida#导入frida模块 import sys #导入sys模块 jscode = """  #从此处开始定义用来Hook的javascript代码     Java.perform(function(){           var MainActivity = Java.use('com.example.testfrida.MainActivity'); //获得MainActivity类         MainActivity.testFrida.implementation = function(){ //Hook testFrida函数,用js自己实现             send('Statr! Hook!'); //发送信息,用于回调python中的函数             return 'Change String!' //劫持返回值,修改为我们想要返回的字符串         }     }); """ def on\_message(message,data): #js中执行send函数后要回调的函数 print(message) process = frida.get\_remote\_device().attach('com.example.testfrida') #得到设备并劫持进程com.example.testfrida(该开始用get\_usb\_device函数用来获取设备,但是一直报错找不到设备,改用get\_remote\_device函数即可解决这个问题) script = process.create\_script(jscode) #创建js脚本 script.on('message',on\_message) #加载回调函数,也就是js中执行send函数规定要执行的python函数 script.load() #加载脚本 sys.stdin.read() ``` **  4、现在python脚本编写完毕,我们来执行该脚本,首先手机端执行frida,然后通过命令`adb forward tcp:27043 tcp:27043`和`adb forward tcp:27042 tcp:27042`来转发这两个端口,接着在手机上运行该应用程序,在命令行中执行脚本,最后点击应用的按钮,即可看到字符串已经被替换成我们要替换的了!!!** ![](https://img.kancloud.cn/46/17/4617bc217c2b236b09ca105fa31d31d6_700x764.png) ``` import frida import sys jscode = """ Java.perform(function(){     //下面这一句代码是指定要Hook的so文件名和要Hook的函数名,函数名就是上面IDA导出表中显示的那个函数名     Interceptor.attach(Module.findExportByName("libfridaso.so","Java\_com\_example\_fridaso\_FridaSoDefine\_FridaSo"),{         //onEnter: function(args)顾名思义就是进入该函数前要执行的代码,其中args是传入的参数,一般so层函数第一个参数都是JniEnv,第二个参数是jclass,从第三个参数开始才是我们java层传入的参数         onEnter: function(args) {             send("Hook start");             send("args\[2\]=" + args\[2\]); //打印我们java层第一个传入的参数             send("args\[3\]=" + args\[3\]); //打印我们java层传入的第二个参数         },         onLeave: function(retval){ //onLeave: function(retval)是该函数执行结束要执行的代码,其中retval参数即是返回值             send("return:"+retval); //打印返回值             retval.replace(0); //替换返回值为0         }     }); }); """ def printMessage(message,data): if message\['type'\] == 'send':         print(' {0}'.format(message\['payload'\])) else:         print(message) process = frida.get\_remote\_device().attach('com.example.fridaso') script = process.create\_script(jscode) script.on('message',printMessage) script.load() sys.stdin.read() ``` ``` * import frida import sys jscode = """ Java.perform(function(){     Interceptor.attach(Module.findExportByName("libfridaso.so","Java\_com\_example\_fridasostring\_fridaSoString\_FridaSo"),{         onEnter: function(args) {             send("Hook start");             send("args\[2\]=" + args\[2\]);         },         onLeave: function(retval){             send("return:"+retval);             var env = Java.vm.getEnv(); //获取env对象,也就是native函数的第一个参数             var jstrings = env.newStringUtf("tamper"); //因为返回的是字符串指针,使用我们需要构造一个newStringUtf对象,用来代替这个指针             retval.replace(jstrings); //替换返回值         }     }); }); """ def printMessage(message,data): if message\['type'\] == 'send':         print(' {0}'.format(message\['payload'\])) else:         print(message) process = frida.get\_remote\_device().attach('com.example.fridasostring') script = process.create\_script(jscode) script.on('message',printMessage) script.load() sys.stdin.read() ``` 调用参数打印输出: ``` import frida #导入frida模块 import sys #导入sys模块 jscode = """ rpc.exports = { getsig:function(){ var ciphertext = ""; Java.perform(function(){ var MainActivity = Java.use('com.maihan.tredian.util.TreUtil'); ciphertext = MainActivity.sign('123456') }) return ciphertext } } """ def printMessage(message,data): if message['type'] == 'send': print('[*] {0}'.format(message['payload'])) else: print(message) process = frida.get_remote_device().attach('com.maihan.tredian:pushservice') #得到设备并劫持进程com.example.testfrida(该开始用get_usb_device函数用来获取设备,但是一直报错找不到设备,改用get_remote_device函数即可解决这个问题) script = process.create_script(jscode) #创建js脚本 script.on('message',printMessage) #加载回调函数,也就是js中执行send函数规定要执行的python函数 script.load() #加载脚本 # sys.stdin.read() ll = script.exports.getsig() print(ll) ``` 调用map: ``` // Call Sign 函数 function callsign() { Java.perform(function () { var ClassName = "com.bilibili.nativelibrary.LibBili"; var Bilibili = Java.use(ClassName); var targetMethod = "s"; var TreeMap = Java.use("java.util.TreeMap"); var map = TreeMap.$new(); map.put("ad_extra", "E1133C23F36571A3F1FDE6B325B17419AAD45287455E5292A19CF51300EAF0F2664C808E2C407FBD9E50BD48F8ED17334F4E2D3A07153630BF62F10DC5E53C42E32274C6076A5593C23EE6587F453F57B8457654CB3DCE90FAE943E2AF5FFAE78E574D02B8BBDFE640AE98B8F0247EC0970D2FD46D84B958E877628A8E90F7181CC16DD22A41AE9E1C2B9CB993F33B65E0B287312E8351ADC4A9515123966ACF8031FF4440EC4C472C78C8B0C6C8D5EA9AB9E579966AD4B9D23F65C40661A73958130E4D71F564B27C4533C14335EA64DD6E28C29CD92D5A8037DCD04C8CCEAEBECCE10EAAE0FAC91C788ECD424D8473CAA67D424450431467491B34A1450A781F341ABB8073C68DBCCC9863F829457C74DBD89C7A867C8B619EBB21F313D3021007D23D3776DA083A7E09CBA5A9875944C745BB691971BFE943BD468138BD727BF861869A68EA274719D66276BD2C3BB57867F45B11D6B1A778E7051B317967F8A5EAF132607242B12C9020328C80A1BBBF28E2E228C8C7CDACD1F6CC7500A08BA24C4B9E4BC9B69E039216AA8B0566B0C50A07F65255CE38F92124CB91D1C1C39A3C5F7D50E57DCD25C6684A57E1F56489AE39BDBC5CFE13C540CA025C42A3F0F3DA9882F2A1D0B5B1B36F020935FD64D58A47EF83213949130B956F12DB92B0546DADC1B605D9A3ED242C8D7EF02433A6C8E3C402C669447A7F151866E66383172A8A846CE49ACE61AD00C1E42223"); map.put("appkey", "1d8b6e7d45233436"); map.put("autoplay_card","11"); map.put("banner_hash","10687342131252771522"); map.put("build","6180500"); map.put("c_locale","zh_CN"); map.put("channel","shenma117"); map.put("column","2"); map.put("device_name","MIX2S"); map.put("device_type","0"); map.put("flush","6"); map.put("ts","1612693177"); var result = Bilibili.s(map); // 打印结果,不需要做什么额外处理,这儿会隐式调用toString。 console.log("\n返回结果:",result); return result; }); } ``` 调用so: ``` import frida import sys jscode = """ Java.perform(function(){ var str_name_so = "libjnitest.so"; //需要hook的so名 var n_addr_func_offset = 0x00000680; //需要hook的函数的偏移 var n_addr_so = Module.findBaseAddress(str_name_so); //加载到内存后 函数地址 = so地址 + 函数偏移 var n_addr_func = parseInt(n_addr_so, 16) + n_addr_func_offset; var ptr_func = new NativePointer(n_addr_func); //var ptr_func = Module.findExportByName("libjnitest.so","test_add") //对函数名hook Interceptor.attach(ptr_func,{ //onEnter: 进入该函数前要执行的代码,其中args是传入的参数,一般so层函数第一个参数都是JniEnv,第二个参数是jclass,从第三个参数开始是我们java层传入的参数 onEnter: function(args) { send("Hook start"); send("args[2]=" + args[2]); //第一个传入的参数 send("args[3]=" + args[3]); //第二个参数 }, onLeave: function(retval){ //onLeave: 该函数执行结束要执行的代码,其中retval参数即是返回值 send("return:"+retval); //返回值 retval.replace(100); //替换返回值为100 } }); }); """ def printMessage(message,data): if message['type'] == 'send': print('[*] {0}'.format(message['payload'])) else: print(message) process = frida.get_remote_device().attach('com.example.testso') #进程名 script = process.create_script(jscode) script.on('message',printMessage) script.load() sys.stdin.read() ``` ![](https://img.kancloud.cn/9f/31/9f31347392b32fb1113af2d5b4cd1da8_817x361.png)