使用 Frida 上报数据¶
使用 Frida 上报数据的功能基于持久化功能,您可以通过您编写的 Frida 脚本自动截取方法调用的数据并通过我们的特定方法进行数据上报,数据上报功能可以使您轻松的将脚本截获到的数据直接上传到 redis 或者外部 http 接口,您可以通过 redis 或者 http 接口接收到上报的数据内容。同时为了最大化网络效能,支持数据压缩后上报(zlib)。
Frida Hook 接口导出及数据上报
编写上报脚本¶
第一步,您需要改写您的 Frida 脚本,通常 frida 脚本具备 send
以及 log
等功能可以使您将数据发送到外部,对于 LAMDA,您需要使用特定的方法来将数据发出。以下使我们针对 okhttp 截获的一个模板代码,他是一个演示脚本,您可能并无法正常使用此脚本。
Java.perform(function() {
Java.use("com.android.okhttp.internal.http.HttpEngine").getResponse.implementation = function() {
var res = this.getResponse()
var data = {}
data["url"] = res._request.value._url.value._url.value
data["body"] = res.body().string()
emit("report_data", JSON.stringify(data))
return res
}
})
可以看到,上述脚本与常规脚本并无太多不同之处,唯一的区别是使用了一个 emit
方法,这是 LAMDA 的自带方法,您可通过他将数据提交到外部。共有两个参数 emit(数据名称, 数据内容)
。其中数据名称
代表数据的类型,如果您设置的上报地址为 redis,那么该名称代表 redis 队列名。您需要尽量准确的用英文描述,比如 goods_info
等。数据内容
则代表该数据的内容,可以是字符串也可以是字节数组,但仅限这两种类型的数据。以上示例中我们将其转换成了 JSON 字符串。
注入上报脚本¶
当然,下面的接口您可能看过,只是我们为了分章所以将它们的其他参数用法写到了不同的章节里。您可以通过如下的接口调用将这个上报脚本注入到应用。当截获数据时,数据将会被提交到 redis 的 report_data 队列,在示例里,您的设备需要能直接访问到 192.168.1.10 上的 redis(注意只支持单例模式,不支持 redis 集群)。
app = d.application("com.android.settings")
app.attach_script(script, emit="redis://192.168.1.10/0")
您可以通过如下的命令将上报到了 redis 队列的数据 pop 出来。
redis-cli lpop report_data
您也可以这样设置,这样您的数据将被提交到 http 接口而不是 redis(支持 https)
app = d.application("com.android.settings")
app.attach_script(script, emit="http://192.168.1.10/dataReport")
您需自行编写 /dataReport
接口,接口需从查询参数提取 encode
,name
参数,从 POST
的 body 提取上报内容
。您可能还需要根据 encode
参数判断是否需要对上报数据进行解压。网络传输的数据量可能很大,压缩可以大大提高吞吐性能,您可以加上 encode
参数来启用上报数据压缩。
app = d.application("com.android.settings")
app.attach_script(script, emit="http://192.168.1.10/dataReport", encode=DataEncode.DATA_ENCODE_ZLIB)
您可以通过使用如下的 zlib 解压方法方便的对上报数据进行解压。
zlib.decompress(data)
需要注意的是,如果您选用了 http 接口,您可以通过上报的 encode
查询参数来判断是否需要解压数据,如果您设置的是 redis,您无法获取此参数,所以您需要固定这个参数值。
移除上报脚本¶
移除上报脚本的过程很简单,他和持久化脚本里的用法是一样的,因为他们本就是一家。
app = d.application("com.android.settings")
app.detach_script()
至此您应该已基本了解了如何进行 hook 数据的上报,如果仍然不清楚可以观看我们的视频。