• AndroidHook之frida学习1-起步

    背景

    想必,能翻开我的这篇文章的人都和我一样,想学习有关android平台的hook技术,但事实上,在安卓平台上有很多hook的技术,比如很早之前的xposed框架,还有很多同类型的其它框架,但是,这里,我要和大家一起学习frida的hook框架,因为这个框架能在多平台下hook,由于它的一些特性,使我选择首先学习frida,比如,它的脚本支持python,互交采用javascript都是它不错的特性。

    安装

    在此之前,必须确保电脑上已经拥有了python环境。然后接下来就可以通过pip安装frida了

    安装frida

    1
    pip3 install frida

    安装frida-tools

    1
    pip3 install frida-tools

    当然了,这些语句在linux平台下也适用。

    检测安装的frida版本,以便下载frida-srver

    1
    frida --version

    由于,我们是对android进行hook所以,在android上必须安装frida-server,也就是说,这个安卓设备需要root,可以是su也可以是其它的比如magisk等,一般模拟器会默认提供root权限,可手动开启。frida-server需要手动到github下载安卓对应版本的frida-server,由于安卓的架构不同,有的是x86,arm,arm64等,需要对应平台下载。

    先查询安卓的架构,通过安卓adb工具查询

    1
    adb shell getprop ro.product.cpu.abi

    比如,我使用的雷电模拟器,对应查询的结果是x86,根据frida版本和安卓架构,在https://github.com/frida/frida/releases 下载frida-server

    image-20220622151653972

    下载后,解压里面的文件,并将其命名为frida-server方便操作。然后可以将这个frida-server放在/data/local/tmp/目录下,并给与其可执行的权限。

    1
    adb push frida-server /data/local/tmp

    给予权限

    1
    2
    adb shell
    chmod +x /data/local/tmp/frida-server

    这样,frida-server就安装好了,下面可以验证一下。先启动frida-server

    1
    adb shell /data/local/tmp/frida-server

    然后新启动一个terminal窗口,执行

    1
    frida-ps -U

    就可以看见所有的程序进程了,也就说明frida全部安装成功。

    注意

    最好选择frida-server和frida一样版本的server,不然会有很多问题;同时,也要注意是frida-server,不是下面图片上这些。

    image-20220622153101458

    AndroidHook之frida学习2-简单函数的hook

    要想要hook,那么可以从最基本的程序开始,比如,hook安卓应用中的一个函数,或者调用函数,拦截函数的传参,影响函数的返回值等。

    写一点代码

    下面就用一个简单的安卓程序代码来演示,比如,用Android Studio新建一个简单的程序,添加一个button,用于点击。

    1
    2
    3
    4
    5
    6
    7
    8
    @Override
    public void onClick(View p){
    Toast.makeText(MainActivity.this,showMessage("button clicked"), Toast.LENGTH_LONG).show();
    }
    public String showMessage(String a)
    {
    return "rightShow:" + a;
    }

    正常的演示效果如下:

    image-20220625161815094

    image-20220625162016423

    使用frida来hook函数返回值

    首先是fridatest.py文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    import frida
    import sys
    import os

    def message(msg, data):
    if msg['type'] == 'send':
    print("[*] {0}".format(msg['payload']))
    else:
    print(msg);

    print(os.system("adb devices"));
    os.system("adb forward tcp:27042 tcp:27042");
    os.system("adb forward tcp:27043 tcp:27043");

    devices = frida.get_remote_device();
    process = devices.attach("fridatest1");
    with open("fridatest.js") as f:
    script = process.create_script(f.read());
    script.on('message', message);#注册回调
    script.load() #js注入目标应用

    sys.stdin.read()#避免结束

    然后写fridatest.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Java.perform(function(){
    var clasz = Java.use('com.qqq.fridatest1.MainActivity');
    clasz.showMessage.implementation = function(a)
    {
    console.log("hook start");
    send("success!");
    send(a);
    return "frida:"+a;
    }
    })

    就可以改变showMessage函数的返回值,原本是“rightshow:button clicked”,后面被frida改为了“frida:button clicked”,比较神奇哈,演示的效果如下:

    image-20220625163258507

    很显然,这样直接hook成功。

    代码解释

    对于python代码就不做解释了,具体的写在注释里面,这里主要讲一下js代码,js 代码中的Java.use('com.qqq.fridatest1.MainActivity');是直接使用的目标类,然后对showMessage方法进行监听hook,然后在js的function(a)可以接受源java函数showMessage传来的参数,然后进行利用后,返回一定的内容。

    js代码中的send()函数,为python代码中注册的回调函数,实现与js与python互交,处理某些逻辑会很方便。

    注意

    值得注意的是,在hook时,需要使用adb shell启用frida-server,不然,python代码一定会报错。也可以像我一样,在bin目录下新建文本文档,里面的内容为/data/local/tmp/frida-server,并将这个文本文档重命名为frida,并赋予可执行权限,然后就可以在各个目录下直接使用frida命令开启frida-server。其次,最好使用su权限启动frida-server,不然,可能遇到一个报错,一个system文件找不到。

    如下是我直接在Magisk on x86终端中使用su启动frida-server的截图,至于其它,也可以自己瞎折腾。除了这样,adb shell或带有root 的termux高级终端也行。

    image-20220625165652171

    上一篇:
    记简单实现动态加载APK
    下一篇:
    Android动态注册NDK函数
    本文目录
    本文目录