本文只是一个入门级教程,如果你想了解更多,欢迎访问

0x1 Frida框架简介

Frdia是一个强大的基于ptrace的trace工具,简言之,就是一个hook也就是跟踪并劫持函数的工具。

  • 基于ptrace的动态trace
  • 支持dalvik虚拟机、ART运行时以及native代码的hook
  • 使用Javascript进行hook逻辑的编写
  • 官方提供Python、C#、swift、node等语言

0x11 Frida的安装

由于Frida工具是一个Python模块,直接可用pip进行安装

pip install frida

开启Android设备的adb调试,在gtihub(https://github.com/frida/frida/releases)上下载frida最新版本的server,这个frida-server需要与用户使用的手机相匹配。请注意,这个server是需要跟我们使用pip安装的frida版本一致。 这就是为什么我们需要下载最新版本,因为pip默认会安装最新版本的frida。
在这里插入图片描述
下载完成之后,使用adb命令,导入到 /data/local/tmp目录下,使用chmod命令修改权限为可执行。执行该二进制文件,如果出错,请跳转到0x21节。

在笔记本上,cmd将当前目录转移到frida的安装目录,即python/Script目录下,这样便于运行frida的相关命令,输入frida-ps -U,如果打印了Android手机上所有运行的进程,说明此时,我们的安装成功了。更多命令,请参考官网或者其他教程。

0x12 Android Studio新建一个用于Hook的Demo

假设我们的包名设为com.lys.demoapplication

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this);
                alertDialog.setTitle("弹框");
                alertDialog.setMessage(getString());
                alertDialog.setCancelable(false);
                alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener()	{
                    @Override
                    public void onClick(DialogInterface	dialog, int	which)	{
                    }
                });
                alertDialog.setNegativeButton("CANCEL", new DialogInterface.OnClickListener()	{
                    @Override
                    public void onClick(DialogInterface	dialog, int	which)	{
                    }
                });
                alertDialog.show();

            }
        });
    }

    private String getString(){
        return "未被hook,我是原始函数";
    }
}

布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="弹框"/>

</LinearLayout>

我们的目标就是hook getString() 函数。
在这里插入图片描述

0x2 Frida Hook三步骤

0x21 adb shell关闭系统SELinux

再打开服务端之前,需要先关闭SELinux,即在adb shell中输入

setenforce 0

此时,再运行 getenforce 命令,如果打印 “Permissive”,说明关闭成功,即可再次运行Frida服务端程序了。

0x22 开启Frida服务端程序

使用adb命令,开启Frida服务端程序
在这里插入图片描述

0x23 编写并运行脚本

编写Frida脚本,进行hook操作

import frida
import sys

device = frida.get_device("127.0.0.1:62001")
session = device.attach("com.lys.demoapplication")
src = """
setImmediate(function(){
    Java.perform(function(){
        send("starting script");        
        var Activity = Java.use("com.lys.demoapplication.MainActivity");
        Activity.getString.overload().implementation = function(){
            var result = this.getString();
            send("getString = " + result);
            var newResult = "我已被劫持!";
            send(newResult);
            return newResult;
        };   
        
    });
});
"""


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


script = session.create_script(src)
script.on("message", on_message)
script.load()
sys.stdin.read()

这里简要介绍以下各个函数的作用。

  • Java.perform(fn):在JNI中,要访问JVM运行时,需要保证vm附加到当前线程。此函数在内部调用VM:AttachCurrentThread,然后执行fn回调函数中的JS脚本操作Java运行时,最后使用VM:DetachCurrentThread释放资源。
  • Java.use(className):通过类名获得Java类,返回一个包裹好的JS对象,通过此对象访问JavaClass的成员,还可以使用$new方法调用类的构造器。

Frida完整的JS代码手册,请参考:https://www.frida.re/docs/javascript-api/

打开之前编写好的app,再运行我们的脚本,点击app中的弹框按钮,脚本打印出如下结果
在这里插入图片描述
app弹框已经被修改
在这里插入图片描述

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐