Frida环境搭建与简单Hook

环境配置

  • 安装Python运行环境

    为了与当前最新的frida版本兼容,需安装Python3.7+的版本

  • 安装fridafrida-tools

    1
    2
    3
    4
    5
    # 安装frida的时间比较长,完成后会显示版本号,下载frida-server文件时的版本需与该版本一致。
    pip install frida

    # 安装frida-tools
    pip install frida-tools
  • 下载frida-server文件

    frida官方Github下载server文件,如果是真机,选择 frida-server-版本-android-arm.xz;如果是模拟器,选择 frida-server-版本-android-x86.xz。如果操作系统是64位,则选择后缀为_64的文件。下载完成后需要解压。(下载很慢或无法下载可尝试用手机连4G下载, 亲测可行)

  • 将解压后的frida-server文件push到真机或模拟器中

    1
    2
    # 不一定要放在data/local/tmp目录下,但该目录所需权限较低
    adb push "frida-server文件路径" data/local/tmp
  • 依次运行以下命令,修改server文件权限

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    adb shell

    # 获取root权限
    su

    # 切换至frida-server文件所在目录
    cd data/local/tmp

    # 查看该目录下的所有文件
    ls

    # 觉得文件名太长可以用移动文件命令来修改一下文件名
    mv "frida-server" fs

    # 修改权限
    chmod 777 fs

    # 测试能否启动,若无任何报错则代表启动成功
    ./fs

简单Hook

此处以自己写的一个简单 Demo 为例,将 apk 文件在 jadx 中打开,在AndroidManifest.xml文件中找到这个 app 的入口类:

1559457700428

1559457982251

查看入口类源码,可以看到有个onCreate方法,一个 app 在启动时,首先会执行该方法。通过观察以上代码,可以发现 Button 上绑了一个点击事件 check ,在 check 函数中检测输入框中的用户名和密码是否为”ethan”和”1234”,如果是,则提示“登陆成功”,否则提示“登陆失败”。

现在,我们要通过 Hook 它的 check 方法,使得无论输入什么东西,点击按钮时都能提示登录成功。

新建一个 py 文件,写下frida的框架代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import frida,sys

jscode = """
Java.perform(function(){
var hook_cls = Java.use('com.example.myapplication.MainActivity')
hook_cls.check.implementation = function(a,b){
console.log("Hook Start...");
send(arguments);
a = "ethan";
b = "1234";
send("Success!");
return this.check(a,b);
}
}
);
"""

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

process = frida.get_remote_device().attach('com.example.myapplication')
script = process.create_script(jscode)
script.on("message",message)
script.load()
sys.stdin.read()

对于一些简单的Hook,我们只需关心 js 部分的代码即可。调用Java.use方法并传入类名的完整路径,可以声明一个我们需要Hook的类。此处我们需要Hook的是MainActivitycheck方法,可以用hook_cls.check.implementation来改写该方法的实现(相当于重新定义该方法)。

原方法中有两个参数,所以我们改写时也带上了两个参数 a 和 b 。使用console.log方法来打印一行开始Hook的消息,然后用send方法输出传入的参数数组。send方法与console.log方法都是在控制台打印消息, 二者区别在于, 如果消息是一个对象, send 会自动处理为 Json, console.log 则只会打印 Object。

将 a 和 b 改写为 “ethan” 和 “1234” ,再调用原来的 check 方法。

运行脚本

现在,让我们来运行一下看看效果。首先需要做一下端口转发:

1
adb forward tcp:27042 tcp:27042

然后进入 shell 并切换到data/local/tmp目录下来启动rida-server:

1
2
3
4
5
adb shell 

cd data/local/tmp

./fs

启动完成后,先在真机或模拟其中打开 app ,再运行脚本。这个顺序很重要,否则脚本会运行失败。

1559464962972

脚本运行后,在 app 中随便输入然后点下测试,如果能弹出”登录成功”,就代表Hook成功了。