Frida学习笔记(2):第一个安卓例子


安装示例 APK

首先在模拟器上安装好官方提供的示例 APK

打开运行,可以看到是一道 CTF 题,通过和 CPU 玩石头剪刀布连续获胜 1000 次可以得到 flag。

剪刀石头布

显然这道题的做法有很多种,直接分析源码、修改源码、通过 Hook 修改获胜状态等方式都可以搞定。

那就根据官方文档来 Hook 一把玩玩吧。

执行 python 脚本

直接把官方文档的 python 代码拷下来:

import frida, sys

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

jscode = """
Java.perform(function () {
  // 这里定义了需要被hook的函数(即安卓程序中的关键方法)
  var MainActivity = Java.use('com.example.seccon2015.rock_paper_scissors.MainActivity');

  // 当按钮按下时
  var onClick = MainActivity.onClick;
  onClick.implementation = function (v) {
    // 打印一条消息来说明函数被调用
    send('onClick');

    // 执行原始的点击事件
    onClick.call(this, v);

    // 在执行原始点击事件后设置变量的值
    this.m.value = 0;
    this.n.value = 1;
    this.cnt.value = 999;

    // 在控制台打印消息,此时应该已经得到flag
    console.log('Done:' + JSON.stringify(this.cnt));
  };
});
"""

# 官方文档用的是frida.get_usb_device(),这里因为使用模拟器,换成frida.get_remote_device()
process = frida.get_remote_device().attach('com.example.seccon2015.rock_paper_scissors')
script = process.create_script(jscode)
script.on('message', on_message)
print('[*] Running CTF')
script.load()
sys.stdin.read()

这段 python 代码的作用是,连接到设备并附加到目标进程上,再将 JS 脚本注入到进程中。

而 JS 代码的作用则是让点击事件执行后变量的值改变。

通过 adb 连接到模拟器 shell,启动 frida 服务端。

再设置 TCP转发:

adb forward tcp:27042 tcp:27042
adb forward tcp:27043 tcp:27043

然后在模拟器上启动石头剪刀布程序,最后在 Win10 上执行上面的 python 脚本。

现在,在模拟器上随便点一个按钮,都能拿到 flag:

flag

控制台也打印了语句:

console-log

显然这一次 Hook 操作是成功了。

直接使用 JS 脚本

先不启动 app,在 Win10 上执行命令:

frida -U -f com.example.seccon2015.rock_paper_scissors --no-pause

此时模拟器上 app 会自动启动。并且命令行中会显示 frida 的界面:

frida -U -f

现在可以使用 frida 的 JavaScript Api 了。在 cmd 中执行以下 JS 脚本:

// 这里要用performNow
Java.performNow(function () {
  var MainActivity = Java.use('com.example.seccon2015.rock_paper_scissors.MainActivity');
  var onClick = MainActivity.onClick;
  onClick.implementation = function (v) {
    onClick.call(this, v);
    this.m.value = 0;
    this.n.value = 1;
    this.cnt.value = 999;
    console.log('Done:' + JSON.stringify(this.cnt));
  };
});

现在回到模拟器中点击任意按钮,现象与使用 python 时相同,说明 Hook 成功。

实际上,frida 允许在 app 启动时直接以 -l xx.js 指定 JS 脚本。但在我进行测试时,使用 Java.performNow() 会出现类未加载的问题;而使用 Java.perform() 则会出现必须重新编辑 js 文件才执行的问题——这个缺点也是可利用的,修改 JS 文件后不需要重新运行 frida。


文章作者: yuanbug
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 yuanbug !
评论
  目录