快速入门指南
如果你不想等待,下面是如何使用Frida进行函数追踪的步骤:
~ $ pip install frida-tools
~ $ frida-trace -i "recv*" -i "read*" twitter
recv: 自动生成的处理程序:…/recv.js
# (省略)
recvfrom: 自动生成的处理程序:…/recvfrom.js
开始追踪21个函数。按Ctrl+C停止。
39 ms recv()
112 ms recvfrom()
128 ms recvfrom()
129 ms recvfrom()
如你所见,Frida已经注入到Twitter中,列出了加载的共享库,并挂钩了所有以recv
或read
开头的函数。它还自动生成了一些脚本,用于处理函数调用并实时检查它们。这些脚本是模板,你可以根据需要进行编辑,文件更改后会自动重新加载。默认情况下,它们只会打印函数名,如上所示的输出。
接下来,我们来看一下生成的recvfrom.js
文件:
/*
* 由Frida自动生成。请根据recvfrom的签名修改。
*
* 这个模板比较简单,未来版本的Frida
* 可能会根据操作系统API文档、手册等自动生成(欢迎提交PR!)。
*
* 完整的API参考,请见:
* https://frida.re/docs/javascript-api/
*/
{
/**
* 在调用recvfrom之前同步调用。
*
* @this {object} - 允许你存储状态的对象,用于onLeave。
* @param {function} log - 使用此函数记录信息并显示给用户。
* @param {array} args - 函数参数,表示为NativePointer对象数组。
* 例如,如果第一个参数是指向UTF-8编码C字符串的指针,可以使用args[0].readUtf8String()。
* 也可以通过为数组元素赋值NativePointer对象来修改参数。
* @param {object} state - 允许你跨函数调用保持状态的对象。
* 只有一个JavaScript函数会同时执行,所以不必担心竞态条件。
* 然而,不要使用此存储onEnter/onLeave之间的函数参数,而应使用"this"来存储本地状态。
*/
onEnter(log, args, state) {
log("recvfrom()");
},
/**
* 在从recvfrom返回之前同步调用。
*
* 参见onEnter了解更多细节。
*
* @this {object} - 允许你访问在onEnter中存储的状态。
* @param {function} log - 使用此函数记录信息并显示给用户。
* @param {NativePointer} retval - 返回值,表示为NativePointer对象。
* @param {object} state - 允许你跨函数调用保持状态的对象。
*/
onLeave(log, retval, state) {
}
}
现在,将log()
行替换为以下内容:
log("recvfrom(socket=" + args[0].toInt32()
+ ", buffer=" + args[1]
+ ", length=" + args[2].toInt32()
+ ", flags=" + args[3]
+ ", address=" + args[4]
+ ", address_len=" + args[5].readPointer().toInt32()
+ ")");
保存文件后(它会自动重新加载),在Twitter应用中执行一些操作以触发网络活动。你应该能看到类似下面的输出:
8098 ms recvfrom(socket=70,
buffer=0x32cc018, length=65536,
flags=0x0,
address=0xb0420bd8, address_len=16)
这只是开始,真正的魔力来自于使用Python API构建自己的工具,frida-trace 就是基于这个API开发的。
原文链接:Quick-start guide | Frida • A world-class dynamic instrumentation toolkit
翻译来源:ChatGPT