消息
在本教程中,我们将展示如何与目标进程之间发送和接收消息。
设置实验
创建一个文件 hello.c
:
#include <stdio.h>
#include <unistd.h>
void
f (int n)
{
printf ("数字: %d\n", n);
}
int
main (int argc,
char * argv[])
{
int i = 0;
printf ("f() 位于 %p\n", f);
while (1)
{
f (i++);
sleep (1);
}
}
编译:
$ gcc -Wall hello.c -o hello
启动程序并记下 f()
的地址(以下示例中为 0x400544
):
f() 位于 0x400544
数字: 0
数字: 1
数字: 2
…
从目标进程发送消息
以下脚本展示了如何将消息发送回Python进程。你可以发送任何可序列化为JSON的JavaScript值。
创建一个文件 send.py
,内容如下:
import frida
import sys
session = frida.attach("hello")
script = session.create_script("send(1337);")
def on_message(message, data):
print(message)
script.on('message', on_message)
script.load()
sys.stdin.read()
当你运行此脚本时:
$ python send.py
它应该会打印以下消息:
{'type': 'send', 'payload': 1337}
这意味着JavaScript代码 send(1337)
已经在 hello
进程内执行。使用 Ctrl-D
终止脚本。
处理JavaScript中的运行时错误
如果JavaScript脚本抛出未捕获的异常,这将从目标进程传播到Python脚本。如果你将 send(1337)
替换为 send(a)
(一个未定义的变量),Python将收到以下消息:
{'type': 'error', 'description': 'ReferenceError: a 未定义', 'lineNumber': 1}
注意 type
字段(error
与 send
)。
在目标进程中接收消息
可以从Python脚本向JavaScript脚本发送消息。创建文件 pingpong.py
:
import frida
import sys
session = frida.attach("hello")
script = session.create_script("""
recv('poke', function onMessage(pokeMessage) { send('pokeBack'); });
""")
def on_message(message, data):
print(message)
script.on('message', on_message)
script.load()
script.post({"type": "poke"})
sys.stdin.read()
运行脚本:
$ python pingpong.py
会产生以下输出:
{'type': 'send', 'payload': 'pokeBack'}
recv() 的机制
recv() 方法本身是异步的(非阻塞的)。注册的回调(onMessage)将只接收一条消息。要接收下一条消息,必须使用recv()重新注册回调。
在目标进程中进行阻塞接收
可以在JavaScript脚本中等待消息到达(阻塞接收)。创建一个脚本 rpc.py
:
import frida
import sys
session = frida.attach("hello")
script = session.create_script("""
Interceptor.attach(ptr("%s"), {
onEnter(args) {
send(args[0].toString());
const op = recv('input', value => {
args[0] = ptr(value.payload);
});
op.wait();
}
});
""" % int(sys.argv[1], 16))
def on_message(message, data):
print(message)
val = int(message['payload'], 16)
script.post({'type': 'input', 'payload': str(val * 2)})
script.on('message', on_message)
script.load()
sys.stdin.read()
程序 hello
应该正在运行,你应该记下它开始时打印的地址(例如 0x400544
)。运行:
$ python rpc.py 0x400544
然后观察运行 hello
的终端中的变化:
数字: 3
数字: 8
数字: 10
数字: 12
数字: 14
数字: 16
数字: 18
数字: 20
数字: 22
数字: 24
数字: 26
数字: 14
hello
程序应该开始写入“加倍”的值,直到你停止Python脚本(Ctrl-D
)。
原文链接:Messages | Frida • A world-class dynamic instrumentation toolkit
翻译来源:DeepSeek