frida环境搭建及hook入门

科技一点鑫得 2024-03-08 03:20:43
frida是什么

frida环境搭建

frida为CS架构,需要安装客户端和服务端

安装客户端需要提前准备好python3环境,执行pip install frida-tools命令即可完成frida客户端的安装(可以通过-i参数指定国内镜像源,加快安装过程,如阿里镜像源地址为https://mirrors.aliyun.com/pypi/simple/),客户端安装完成后将支持frida、frida-ps、frida-trace、frida-discover、frida-ls-devices、frida-kill等一系列命令。安装服务端server端需要安装在要hook的主机上,server端的安装版本必须与客户端版本一致,且server端的安装包文件必须和主机的CPU架构匹配。这里以mumu android模拟器12为例,首先使用adb shell getprop ro.product.cpu.abi查看CPU架构,如下结果为x86_64,则下载frida-server-16.1.3-android-x86_64.xz,解压后上传到/data/local/tmp目录下,并赋权777。PS C:\Users\xxx> adb shell getprop ro.product.cpu.abix86_64

执行adb shell "/data/local/tmp/frida-server-16.1.3-android-x86_64 &"启动服务端server端下载链接:https://github.com/frida/frida/releases

检查安装是否成功在客户端执行frida-ps -U,如果能返回手机端运行的进程则说明frida环境搭建成功PS C:\Users\xxx> frida-ps -U PID Name---- ------------------------------------------------1450 adbd1568 android.ext.services...2437 应用中心2666 抖音2008 设置端口转发后续执行frida注入可能会提示找不到设备,这时尝试添加端口转发,27042是默认客户端和服务端通信端口,不确定27043是不是必须的,网上搜索的结果都是两个端口都加入了转发。adb forward tcp:27042 tcp:27042adb forward tcp:27043 tcp:27043hook入门

frida环境搭建只是第一步,怎么使用frida才是真正的挑战,因为掌握它需要软件开发技能、软件逆向技能、操作系统等各种能力,能力越强越能发挥出它的威力,这里仅给出简单的入门示例,因为我也是新手。

开发一个简单的android app因为我不熟悉android开发,为了让自己对android app结构有个初步的认识,我参考网上的教程开发了一个简单的app,这个app就是求两个数的和。如果你已经很熟悉android app开发请直接忽略这一步。

布局文件activity_main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:text="a:"> </TextView> <EditText android:id="@+id/a" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" tools:ignore="TouchTargetSizeCheck,SpeakableTextPresentCheck" android:ems="10"> </EditText> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:text="b:"> </TextView> <EditText android:id="@+id/b" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" tools:ignore="TouchTargetSizeCheck,SpeakableTextPresentCheck" android:ems="10"> </EditText> </LinearLayout> <Button android:id="@+id/btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Sum"> </Button> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:text="a+b = "> </TextView> <TextView android:id="@+id/c" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:textColor="#0aaaaa" android:text="" android:ems="10"> </TextView> </LinearLayout></LinearLayout>

MainActivity.java,调用了com.example.hookdemo.HookDemo的Add方法

package com.example.appdemo;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import com.example.hookdemo.HookDemo;public MainActivity extends AppCompatActivity { private TextView tvc; private EditText edta, edtb; private Button btn; private int numC; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn = (Button)this.findViewById(R.id.btn); edta = (EditText)this.findViewById(R.id.a); edtb = (EditText)this.findViewById(R.id.b); tvc = (TextView)this.findViewById(R.id.c); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String inputA = edta.getText().toString(); String inputB = edtb.getText().toString(); int numA = Integer.valueOf(inputA).intValue(); int numB = Integer.valueOf(inputB).intValue(); numC = HookDemo.Add(numA, numB); tvc.setText(String.valueOf(numC)); } }); }}

HookDemo.java

package com.example.hookdemo;public HookDemo { public static int Add(int a, int b) { return a + b; }}

接下来我们就hook这个求和的Add方法,注入我们自己的代码实现直接修改求和的入参。

运行python代码进行注入frida的脚本是通过python来编写的,但是真正的注入代码是使用JavaScript来写,下面的示例python代码将注入js代码写在jscode变量中,这里需要特别注意的是frida官网给出的示例frida.get_usb_device().attach方式传入的是包名,但是实际测试发现报错frida.ProcessNotFoundError: unable to find process with name 'com.example.appdemo',提示找不到这个进程。解决的办法是通过adb shell ps命令找到对应的pid,直接传入pid可以正常运行。import frida, sysdef on_message(message, data): if message["type"] == "send": print("[*] {0}".format(message["payload"])) else: print(message)jscode = """// 确保当前线程附件到虚拟机并调用其中的方法Java.perform(() => { // hook的包名 var hookdemo = Java.use('com.example.hookdemo.HookDemo'); // 注入hook方法的代码 hookdemo.Add.implementation = function (a, b) { // 直接修改入参a、b为固定值 a = 12; b = 13; var res = this.Add(a, b); console.log(a, b, res); // 向frida客户端发送消息 send(JSON.stringify({ "a": a, "b": b, "c":res })); return res; }});"""# 通过adb shell ps找到注入app对应的pid# process = frida.get_usb_device().attach("com.example.appdemo")process = frida.get_usb_device().attach(2620)script = process.create_script(jscode)# 当收到message时调用on_messagescript.on("message", on_message)script.load()sys.stdin.read()

运行python脚本,然后在mumu模拟器输入两个数并点击求和按钮就会触发调用Add方法,这时控制台会打印message消息以及console.log的打印信息,而app显示的求和结果也被改变了,说明我们的代码成功注入app并实现了改变原有方法的行为。

命令行形式进行注入除了运行python脚本的方式进行注入之外,也可以在客户端输入命令方式进行代码注入,直接将js代码单独保存为hook.js文件// 确保当前线程附件到虚拟机并调用其中的方法Java.perform(() => { // hook的包名 var hookdemo = Java.use('com.example.hookdemo.HookDemo'); // 注入hook方法的代码 hookdemo.Add.implementation = function (a, b) { // 直接修改入参a、b为固定值 a = 12; b = 13; var res = this.Add(a, b); console.log(a, b, res); // 向frida客户端发送消息 send(JSON.stringify({ "a": a, "b": b, "c":res })); return res; }});

frida-ps -U列出运行的进程id和进程名,找到需要注入的app名称,示例为appDemo

PS C:\Users\xxx> frida-ps -U PID Name---- ------------------------------------------------2228 abb1302 adbd...2620 appDemo1041 audioserver1064 cameraserver

执行frida -U 进程名 -l xx.js即可进行注入测试,注入成功会显示如下打印信息

C:\Users\xxx>frida -U hello_world -l hook1.js ____ / _ | Frida 16.1.3 - A world-class dynamic instrumentation toolkit | (_| | > _ | Commands: /_/ |_| help -> Displays the help system . . . . object? -> Display information about 'object' . . . . exit/quit -> Exit . . . . . . . . More info at https://frida.re/docs/home/ . . . . . . . . Connected to PGAM10 (id=127.0.0.1:16384)Attaching...start<class: com.example.hookdemo.Student>[PGAM10::hello_world ]->

然后在mumu模拟器输入两个数并点击求和按钮触发调用Add方法,求和结果始终为25,因为注入的代码将a、b改为了固定的值。控制台也会打印相应的信息,说明我们注入的代码已经工作了。

0 阅读:0

科技一点鑫得

简介:感谢大家的关注