Python中frida库使用

启动frida服务

包名附加

1
2
3
4
5
6
7
8
9
10
11
import frida
import sys

jscode = '''

'''
device = frida.get_usb_device()# 获取usb连接的测试机
process = device.attach("设置")# 包名附加进程,可通过frida-ps -U查看
script = process.create_script(jscode)#创建注入脚本
script.load()#注入脚本
sys.stdin.read()# 加这个才能回显log输出

PID附加

由于有的应用是多进程,这个时候使用包名附加就会冲突,因此可以使用PID附加。PID附加同样使用attach()方法。

1
frida.get_usb_device().attach(pid)#pid附加进程,可通过frida-ps -U查看pid

spawn方式启动

1
2
3
4
5
6
7
8
9
10
11
12
13
import frida
import sys

jscode = '''

'''
device = frida.get_usb_device()# 获取usb连接的测试机
pid = device.spawn(['com.android.settings'])#以挂起方式创建进程
process = device.attach(pid)#然后再附加进程
script = process.create_script(jscode)#创建脚本
script.load()#注入脚本
device.resume(pid)#恢复进程运行
sys.stdin.read()# 回显log输出

因为是以挂起的方式启动进程(相当于动调时的附加),程序处于暂停状态,所以需要resume()恢复进程运行

非标准端口启动frida-server的连接

如果使用非标准端口启动手机端frida-server时,

1
./frida-server -l 0.0.0.0:port

则python中的设备获取的代码如下:

1
device = frida.get_device_manager().add_remote_device("ip:port")

连接多个设备

通过frida.get_device_manager().add_remote_device()依次添加。

js与python的交互

数据从js到python

在js代码中,我们经常使用console.log()打印我们想要知道的值,但是这个值并不能交给python使用,因此在js代码中需要用到send(message[, data])方法将值传递给python处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import frida
import sys

jscode = '''
function main(){
Java.perform(function(){
console.log("nihao123")
send(11111111)
})
}
setImmediate(main)
'''

# 需要自定义方法,处理js传过来的值
def onMessage(message, data):
print(f'message = {message}')
if message['type'] == 'send':
print(f"value = {message['payload']}")

device = frida.get_usb_device()
process = device.attach('设置')
script = process.create_script(jscode)#创建注入脚本
script.on("message", onMessage)#注册消息处理函数
script.load()#注入脚本
sys.stdin.read()# 回显log输出
"""
nihao123
message = {'type': 'send', 'payload': 11111111}
value = 11111111
"""

数据从python到js

python要向js发送数据则需要使用script.post()方法,js中则使用recv([type, ]callback)来接收。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import frida
import sys

jscode = '''
function main(){
Java.perform(function(){
recv(function(obj){
console.log(obj.data)
}).wait()
})
}
setImmediate(main)
'''

device = frida.get_usb_device()
process = device.attach('设置')
script = process.create_script(jscode)#创建注入脚本
script.load()#注入脚本
script.post({"data": "111111"})
sys.stdin.read()# 回显log输出

rcp转发

js 端使用rpc.exports = { key: value}导出函数供python使用,其中键指定方法名称,值是导出的函数。

python端调用script.exports_sync.func()执行js中的函数。

注: 如果 js 导出函数中包含驼峰命名,则 python 需要将大写替换成_小写,如 getUser => get_user

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import frida
import sys

jscode = '''
function add(a, b){
return a + b;
}
function sub(a, b){
return a - b;
}
rpc.exports = {
add: add,
sub: sub
}
'''

device = frida.get_usb_device()
process = device.attach('设置')
script = process.create_script(jscode)#创建注入脚本
script.load()#注入脚本
# result = script.exports.add(3, 5)报错
# DeprecationWarning: Script.exports will become asynchronous in the future, use the explicit Script.exports_sync instead
result = script.exports_sync.add(3, 5)
print(result)

使用 fastapi 搭建服务端接口

超全面整理fastAPI(从入门到运用),进来看十秒钟再走不迟-CSDN博客

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import frida
import sys
import fastapi
import uvicorn

jscode = '''
function getUserData(uid){
return {"username": "gal2xy", "uid": uid, token: "asldhoinzponpnasdf"}
}
rpc.exports = {
getUserData: getUserData
}
'''

app = fastapi.FastAPI()
# 构造api:请求方式(路径),请求方式:get、delete、post、put
@app.get("/getUserData")
async def getUserData(uid):
result = script.exports_sync.get_user_data(uid)
return result
uvicorn.run(app, port=8080)# 启动服务端

device = frida.get_usb_device()
process = device.attach('设置')
script = process.create_script(jscode)#创建注入脚本
script.load()#注入脚本

在本地访问127.0.0.1:8080/getUserData?uid=123就可以得到userdata。


参考:

Frida Python库使用 | 愧怍的小站 (kuizuo.cn)

超全面整理fastAPI(从入门到运用),进来看十秒钟再走不迟-CSDN博客


Python中frida库使用
http://example.com/2023/12/18/Android安全/Python中frida库使用/
作者
gla2xy
发布于
2023年12月18日
许可协议