首先安装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)