Frida入门笔记
on Blogs
Frida简介
frida是一款基于python + java 的hook框架,可运行在android、ios、linux、win、osx等各平台,主要使用动态二进制插桩技术。
官方网址:Frida
相关教程(自己当时看的)
Hook代码模板
Python模板
Frida中有两种hook模式,spawn和attach模式:
spawn模式:Frida会自行启动并注入到目标App进程中,其hook的时机非常早(即在App启动阶段)
该模式代码:
pid = frida.get_remote_device().spawn(['包名'])
attach模式:Frida会附加到目标App进程中,使用该模式需要App处于启动状态,同时也意味着该模式只能从当前界面往后进行hook
该模式代码:
session = frida.get_remote_device().attach('App名称')
Attention:spawn中使用的是包名,attach中使用的是App名称!!
python框架代码(按照这个模板改就行了,其中一部分需要自定义):
import sys # 导入sys模块
import frida # 导入frida模块
# 该函数为js脚本中执行了send函数后要回调的函数
# 自定义需要执行的功能
def on_message(message, data):
print(message)
'''
spawn模式
'''
# device = frida.get_remote_device()
# pid = device.spawn(['com.demo.jjj'])
# device.resume(pid)
# time.sleep(1)
# session = device.attach(pid)
'''
attach模式
'''
session = frida.get_remote_device().attach('Demo应用')
# 添加执行脚本(js语言)
with open("./frida_script.js") as f:
script = session.create_script(f.read())
script.on('message', on_message) # 加载回调函数
script.load() # 加载脚本
sys.stdin.read()
Js模板
Java.perform(function () {
Java.use('包名.类名').方法名.implementation = function (j) {
var sign = this.getSign(arg);
console.log("参数: " + arg);
console.log("sign: " + sign);
return sign; // 在hook出来内容之后,需要将原本hook的东西再送回进程
// 还有一种是return this.方法名(arg1, arg2, ...);
}
});
当出现函数重载的时候,hook时脚本为:
Java.perform(function () {
Java.use('包名.类名').方法名.overload('参数类型1', '参数类型2', ...).implementation = function (j) {
...
}
});
参数类型对应关系(和smali语法是一样的)
Field Descriptor | Java Language Type |
---|---|
Z | Boolean |
B | Byte |
C | Char |
S | Short |
I | Int |
J | Long |
F | Float |
D | Double |
[ | 一维数组([B为Byte类型的一维数组) |
[[ | 二维数组 |
主动执行代码模板
程序中有一些代码可能难以在路径中执行或者触发,可能需要主动去触发该代码,此时使用这种方式。
Python模板
和上面的Hook差不多,只是最后加载脚本的那一部分需要修改一下。
script.on('message', on_message) # 加载回调函数
script.load() # 加载脚本
# 之后执行相关函数,如果此函数需要一些输入,可以在这里构造。
# 假设需要执行的函数有两个参数,一个是int,一个是string;返回变量为sign
a = 1
b = 'text'
sign = script.exports.getsign(a, b) # 执行相关函数并传入参数,其中getsign是在js脚本中自定义的函数名
print(sign)
Js模板
function sign(s){ // 注意,这里自定义的函数参数需要和目标函数中的参数一致
var result = '';
Java.perform(function() {
result = Java.use.('包名.类名').目标函数(s);
})
return result
}
rpc.exports={
getsign:sign // 设置对外接口为getsign
}