目录

充电学习中...

X

Frida用于生产部署实践

Frida用于生产部署实践----续作(Frida-Inject)

此文为这篇文章的续作,在前文中,生产部署时除了手机外,还要有一台另外的设备用于rpc交互(前文用的是树莓派)。在本文中,我们将使用frida-inject去实现满足生产需要的部署。

一、准备工作

  1. 安卓设备 真机或模拟器都可,需要root权限
  2. frida-inject模块
  3. 用于hook的 js脚本
  4. 目标app

没错,只需要上述资源即可完成,成功部署之后可以完全脱离PC去使用。

二、开始部署

将frida-inject和js脚本推送到手机,例如/data/local/tmp目录中

frida-inject下载地址,注意不要下错了,根据自己设备的cpu架构选择对应的版本,如下图,我的设备是arm64架构的,就是下图圈出来这个。下载完之后先解压,里面的文件才是我们需要的,这一点和frida-server相同,熟悉frida 的朋友应该不会搞错。

image.png

接着给frida-inject和js脚本赋予可执行权限,即:

//frida inject模块
chmod 777 frida-injetmodule
//xxx.js为你的jshook脚本
chmod 777 xxx.js

然后,运行即可

//fi1422-arm64为frida-inject模块 我这里重新命名了
//pkgname为需要hook的目标app包名
//xxx.js为hook脚本
./fi1422-arm64 -f pkgname -s xxx.js

确认启动没有问题后(如有问题查看下文),再使用nohup命令使其在后台运行,代码如下:

nohup ./fi1422-arm64 -f pkgname -s xxx.js --runtime=v8 -e &

三、问题解决

1.启动失败

需要注意的是,部分设备首次执行这条命令会自动重启,属于正常现象,待重启完毕之后再次执行即可。如果出现目标app崩溃且多次重试无效时,尝试修改js代码,延迟启动,如下:

//xxxx为hook代码
//延迟时间根据实际情况调整
setTimeout(xxxx,1000);

如果上述操作之后还是无法使用,则修改命令,在目标app启动之后再attch,将-f 替换成-n即可,如下

./fi1422-arm64 -n pkgname -s xxx.js --runtime=v8 -e

2.原生js功能欠缺

由于去掉了python部分,所以的功能都需要用js去实现,但是原生js对例如http请求的功能支持比较差,而有时我们的确需要这些功能。解决这一问题,有两个笔者认为比较合适的方法:

1).使用frida-compile

使用frida-compile,可以将js代码打包成frida能够执行的样式,同时也支持typescript

安装

npm install frida-compile

打包

frida-compile -o output.js input.js

但是实际使用过程中,由于需要用到网络请求,便引入了axios这个模块,打包完毕后执行报错,而用于加解密的crpyto模块则正常,由此可见frida-compile可能有一些bug,由于本人并非专攻js方向,因此没有继续研究而是采用了其他方法。

2).使用hook方式

以okhttp为例,以下代码既可以简单的发送get、post请求

function sendbyokhttp(url, postdata) {
    try {
        var OkHttpClient = Java.use('okhttp3.OkHttpClient').$new();
        var requestbuild = Java.use('okhttp3.Request$Builder').$new();
        var request;
        if (postdata == undefined || postdata == "" || postdata == null) {
            request = requestbuild.url(url).build();
        } else {
            var body = Java.use('okhttp3.RequestBody').create(Java.use('okhttp3.MediaType').parse('application/json'), postdata);
            request = requestbuild.url(url).post(body).build();
        }
        var response = OkHttpClient.newCall(request).execute();
        var result = response.body().string();
        log("http request:" + url)
        log("http response:" + result)
        return result;
    } catch (error) {
        log(error)
    }
    return "fail";

}

使用这种方式的优点是不需要用js去发送请求,打包的代码体积也大大减少,缺点就是不同的app可能使用的是不同的http请求框架,有的或许也有混淆,导致无法找到正确的hook目标。部分场景可能因为hook位置在主线程而导致发送http请求报错,这时可以使用异步方法,使用frida去注册一个实现Callback的类即可,代码如下:

var MyCallbBack = null;
function sendbyokhttpasync(url, postdata) {
    try {
        if (MyCallbBack == null) {
            //注册callback
            MyCallbBack = Java.registerClass({
                name: 'okhttp3.MyCallbBack ',
                implements: [Java.use('okhttp3.Callback')],
                methods: {
                    onFailure(call, e) {
                        log("请求失败:" + e.getMessage());
                    },
                    onResponse(call, re) {
                        log("请求完毕:" + re.request().url().toString());
                        var re = re.body().string();
                        log("http request:" + re);
                    }
                }
            });
        }


        if (OkHttpClient == "" || OkHttpClient == null) {
            OkHttpClient = Java.use('okhttp3.OkHttpClient').$new();
        }
        var requestbuild = Java.use('okhttp3.Request$Builder').$new();
        var request;
        if (postdata == undefined || postdata == "" || postdata == null) {
            request = requestbuild.url(url).build();
        } else {
            var body = Java.use('okhttp3.RequestBody').create(Java.use('okhttp3.MediaType').parse('application/json'), postdata);
            request = requestbuild.url(url).post(body).build();
        }
        var callbackins = MyCallbBack.$new();

        OkHttpClient.newCall(request).enqueue(callbackins);
    } catch (error) {
        log(error)
    }
    return failmessage;

}

3.外部调用

笔者在做手上的项目时暂时没有此需求,但是有两种思路,1.即是用node模块起一个http服务,使用frida-compile打包之后随hook代码一同注入到目标app中。2.用java实现一个http服务,编译成dex文件,然后用frida去加载这个dex文件来开启http服务。在局域网环境下,设置端口转发即可局域网访问。如果需要外网访问,配置内网穿透即可。

四、总结

frida-inject与上一篇文章中的rpc方法相比,硬件上只需要一台安卓设备,软件上剔除了python模块,删除了rpc通讯,整套系统复杂度降低,稳定性大大提升。


标题:Frida用于生产部署实践
作者:Cubeeeee
地址:http://blog.nps.fuguicun.com/articles/2021/03/26/1616750899787.html