白乐天

道阻且长,行则将至。

frida_rpc

枚举所有进程及其进程ID

1
2
3
4
5
6
7
8
9
import frida

device = frida.get_usb_device()
print("Connected to device")

processes = device.enumerate_processes()
print("Listing all processes:")
for process in processes:
print(f"{process.name} (PID: {process.pid})")
1
2
3
4
5
6
import frida

device = frida.get_remote_device()
processes = device.enumerate_processes()
for process in processes:
print(process)

注入进程

附加进程注入

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

process = frida.get_usb_device().attach(ProcessName/PID)

jsCode = """
console.log("frida hooked!")
"""

script = process.create_script(jsCode)
script.load()

spawn方式注入

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

device = frida.get_usb_device()
pid = device.spawn([PackageName])
process = device.attach(pid)

jsCode = """
console.log("frida hooked!");
"""
script = process.create_script(jsCode)
script.load()

device.resume(pid) # 恢复进程
print("Script loaded")

非标准端口注入

需要进行端口转发

1
adb forword tcp:27042 tcp:27042
1
2
3
import subprocess
subprocess.getoutput("adb forward tcp:27042 tcp:27042")
subprocess.getoutput("adb forward tcp:7777 tcp:7777")

attach

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

device = frida.get_device_manager().add_remote_device("127.0.0.1:7788") # 指定IP地址
process = device.attach(ProcessName/PID)

jsCode = """
console.log("frida hooked!");
"""
script = process.create_script(jsCode)
script.load()
print("Script loaded")

spawn

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

device = frida.get_device_manager().add_remote_device("127.0.0.1:7788") # 指定IP地址
pid = device.spawn(PackageName)
process = device.attach(pid)

jsCode = """
console.log("frida hooked!");
"""
script = process.create_script(jsCode)
script.load()

device.resume(pid)
print("Script loaded")

send

send 是用于在 Frida 脚本和主机 Python 程序之间通信的函数。

JS端

send 是 Frida 的全局函数,用于向Python程序发送字符串、对象或其他序列化数据。

1
send("Hello from Frida!");

Python端

通过 script.on("message", callback) 监听 JavaScript 脚本发送的消息。

1
2
3
4
def on_message(message, data):
print(f"Received message: {message}")

script.on("message", on_message) # 注册消息回调

示例

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
import frida

device = frida.get_device_manager().add_remote_device("127.0.0.1:7788")
pid = device.spawn(PackageName)
process = device.attach(pid)

jsCode = """
console.log("frida hooked!");
send("Hello from Frida!");
"""
script = process.create_script(jsCode)

def on_message(message,data):
if message["type"] == "send":
print(f"Received from JavaScript: {message}")

script.on("message",on_message)

script.load()
print("Script loaded")

>>>
frida hooked!
Received from JavaScript: {'type': 'send', 'payload': 'Hello from Frida!'}
Script loaded

双向通信

JS端

通过``send发送,recv`来接收。

1
2
3
4
5
6
send("Requesting data from Python");

// 接收来自 Python 的消息
recv(function (message) {
console.log("Received from Python:", message.payload);
}).wait();

Python端

1
2
3
4
5
6
7
def on_message(message, data):
if message["type"] == "send":
print(f"Received from JavaScript: {message['payload']}")
# 回复消息给 JavaScript
script.post({"response": "Data received!"})

script.on("message", on_message)

示例

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

device = frida.get_device_manager().add_remote_device("127.0.0.1:7788")
pid = device.spawn(PackageName)
process = device.attach(pid)

jsCode = """
console.log("frida hooked!");
send("Hello from Frida!");

recv(function (message){
console.log("Received from Python:", message)
}).wait();
"""
script = process.create_script(jsCode)

def on_message(message,data):
if message["type"] == "send":
print(f"Received from JavaScript: {message}")
script.post("message from Python")

script.on("message",on_message)
script.load()
print("Script loaded")

>>>
frida hooked!
Received from JavaScript: {'type': 'send', 'payload': 'Hello from Frida!'}
Received from Python: message from Python
Script loaded

rpc

JS端定义rpc函数

1
2
3
4
5
6
7
8
9
rpc.exports = {
hello: function () {
return "Hello from Frida!";
},

add: function (a, b) {
return a + b;
}
};

rpc.exports 是一个对象,暴露的函数作为其属性。

Python端调用rpc方法

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
import frida

# 连接到目标设备和应用
device = frida.get_usb_device()
pid = device.spawn(["com.example.app"])
session = device.attach(pid)

# 加载 JavaScript 脚本
js_code = """
rpc.exports = {
hello: function () {
return "Hello from Frida!";
},
add: function (a, b) {
return a + b;
}
};
"""
script = session.create_script(js_code)
script.load()
device.resume(pid)

# 调用 RPC 方法
print(script.exports.hello()) # 输出: Hello from Frida!
print(script.exports.add(3, 5)) # 输出: 8

API详解

frida.get_device()

1
(function) def get_device(id: str | None,timeout: int = 0) -> Device

通过设备ID获取指定的设备对象。

1
2
3
import frida
device = frida.get_device("xxxxxx")
print(device)

frida.get_local_device()

1
(function) def get_local_device() -> Device

获取本地设备(即运行 Frida 的当前机器)的设备对象。

1
2
3
import frida
device = frida.get_local_device()
print(device)

frida.get_remote_device()

1
(function) def get_remote_device() -> Device

获取远程设备对象。

1
2
3
import frida
device = frida.get_remote_device()
print(device)

frida.get_usb_device()

1
(function) def get_usb_device(timeout: int = 0) -> Device

获取通过 USB 连接的设备对象。

1
2
3
import frida
device = frida.get_usb_device()
print(device)

device.enumerate_processes(…)

1
(method) def enumerate_processes(...) -> List[Process]

枚举设备上正在运行的进程。这个方法返回一个包含进程信息的列表,每个进程信息包括进程名称、进程 ID(PID)等。

1
2
3
4
5
import frida
device = frida.get_usb_device()
processes = device.enumerate_processes()
for process in processes:
print(process)

device.attach(…)

1
(method) def attach(...) -> Session

附加到设备上的指定进程,参数可以是进程的PID,也可以是进程的名字。

1
2
3
4
5
import frida
device = frida.get_usb_device()
# 附加到指定 PID 的进程
pid = 1234
session = device.attach(pid)
1
2
3
4
import frida
device = frida.get_usb_device()
process_name = "com.example.app" # 替换为目标进程的名称
session = device.attach(process_name)

device.spawn()

1
(method) def spawn(...) -> int

用于在设备上启动一个新的进程,返回进程ID。

1
2
3
4
5
6
7
8
import frida
# 获取 USB 设备
device = frida.get_usb_device()
# 启动 Android 应用(通过包名)
package_name = "com.example.app"
pid = device.spawn(package_name)
# 附加到新启动的进程
session = device.attach(pid)

session.create_script(…)

1
(method) def create_script(...) -> Script

创建一个 Frida 脚本并将其与目标进程关联。

1
2
3
4
5
6
7
8
9
import frida
# 获取 USB 设备
device = frida.get_usb_device()
# 附加到目标进程
session = device.attach("com.example.app")
# 创建并加载脚本
script = session.create_script("""
console.log("Hello from Frida!");
""")

script.load()

1
(method) def load(...) -> None

将脚本加载到目标进程中并开始执行。

1
2
3
4
5
6
7
8
9
10
import frida
# 获取 USB 设备
device = frida.get_usb_device()
# 附加到目标进程
session = device.attach("com.example.app")
# 创建并加载脚本
script = session.create_script("""
console.log("Hello from Frida!");
""")
script.load()