frida入门级详细讲解
观文须知
由于文章在编辑时使用的markdown,但论坛禁止调用外部图床,为了方便编写,文章未提供图片,如果真的对frida感兴趣,可以根据文章内容对操作进行复现。
文章后半部分充斥着大量的java、python和javascript代码,可能会产生不良副作用,如有不适请快速关闭页面,因此产生的不良后果本人概不负责。
读万卷书,不如行万里路;行万里路,不如阅人无数。
环境准备
- Android Studio(其他APP开发IDE也可以)
- mumu模拟器(重点安利对象,无广告小清新、无广告小清新、无广告小清新,重要的事情说三遍,夜神、雷电、闪电等等其他模拟器也可以)
- frida(笔者使用的是12.4.4版本,其他版本也可以)
Android Studio
这个没什么好说的,在官网下载安装即可。
mumu模拟器
这个更没什么好说的,在官方下载安装即可。
frida
客户端安装
笔者在这里使用的是Ubuntu for windows 10,直接使用pip install frida-tools
。
服务端安装
使用frida --version
命令获取frida客户端的版本,在frida官方github下载相同版本的frida-server。
使用adb push frida-server /data/local/tmp/
命令将frida-server文件push到模拟器的tmp文件夹,使用adb shell
命令进入到模拟器的shell,再shell中使用cd /data/local/tmp/
命令切换至tmp文件夹,使用chmod 755 frida-server
命令对frida-server文件的权限进行修改。
frida连接
在服务端执行./frida-server
命令启动服务。
在客户端执行frida-ps -U
命令可以看到进程列表。
frida的使用
测试APP准备
这里表弟随便写了一个APP,这个APP的功能是计算两个数的和,具体代码如下:
package com.test.test;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private Button btButton;
private EditText et1,et2;
private int num1,num2,num3;
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btButton = (Button)findViewById(R.id.button);
tv = (TextView)findViewById(R.id.textView6);
btButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
et1 = (EditText)findViewById(R.id.editText2);
et2 = (EditText)findViewById(R.id.editText3);
num1 = Integer.parseInt(et1.getText().toString());
num2 = Integer.parseInt(et2.getText().toString());
num3 = testbug(num1,num2);
tv.setText(String.valueOf(num3));
}
});
}
public int testbug(int testnum1,int testnum2) {
return testnum1+testnum2;
}
}
修改方法
目标
通过hook修改方法为获取两个数的差。
loaderHook.py代码
import time
import frida
device = frida.get_usb_device()
pid = device.spawn(["com.test.test"])
device.resume(pid)
time.sleep(1)
session = device.attach(pid)
with open("hook.js") as f:
script = session.create_script(f.read())
script.load()
input()
hook.js代码
Java.perform(function() {
var my_class = Java.use("com.test.test.MainActivity");
my_class.testbug.implementation = function(num1,num2) {
console.log("num1:" + num1 + " num2:" + num2);
var ret_value = test(num1,num2);
return ret_value;
}
function test(num1,num2) {
return num1-num2;
}
})
方法执行前修改参数
目标
通过hook在计算两数和之前对数值进行修改。
loaderHook.py代码
import time
import frida
device = frida.get_usb_device()
pid = device.spawn(["com.test.test"])
device.resume(pid)
time.sleep(1)
session = device.attach(pid)
with open("hook.js") as f:
script = session.create_script(f.read())
script.load()
input()
hook.js代码
Java.perform(function() {
var my_class = Java.use("com.test.test.MainActivity");
my_class.testbug.implementation = function(num1,num2) {
console.log("num1:" + num1 + " num2:" + num2);
num1=8;
num2=10;
var ret_value = this.testbug(num1,num2);
return ret_value;
}
})
方法执行后修改结果
目标
通过hook在计算两数和之后对结果进行修改。
loaderHook.py代码
import time
import frida
device = frida.get_usb_device()
pid = device.spawn(["com.test.test"])
device.resume(pid)
time.sleep(1)
session = device.attach(pid)
with open("hook.js") as f:
script = session.create_script(f.read())
script.load()
input()
hook.js代码
Java.perform(function() {
var my_class = Java.use("com.test.test.MainActivity");
my_class.testbug.implementation = function(num1,num2) {
console.log("num1:" + num1 + " num2:" + num2);
var ret_value = this.testbug(num1,num2);
ret_value = 86;
return ret_value;
}
})
调用APP内部的方法
目标
通过call直接调用APP内部编写的计算两数和的方法。
loaderCall.py代码
import time
import frida
device = frida.get_usb_device()
pid = device.spawn(["com.test.test"])
device.resume(pid)
time.sleep(1)
session = device.attach(pid)
with open("call.js") as f:
script = session.create_script(f.read())
script.load()
script.exports.callhidefunction(88,66)
call.js代码
function callHideFun(num1,num2) {
Java.perform(function() {
Java.choose("com.test.test.MainActivity", {
onMatch: function(hideFun) {
console.log(hideFun.testbug(num1,num2));
},
onComplete: function() {
}
});
});
}
rpc.exports = {
callhidefunction : callHideFun
};
问题汇总
mumu模拟器adb连接不上
启动mumu模拟器后,使用adb devices
命令查看连接设备发现没有设备,这个时候需要使用adb connect 127.0.0.1:7555
进行连接,再执行adb devices
命令即可看到mumu模拟器。
./frida-server: not executable: 32-bit ELF file
执行./frida-server
命令时可能会报./frida-server: not executable: 32-bit ELF file
错误,引起这个的原因是因为下载的frida服务端与模拟器的架构不符。
瞎扯淡
不知道是由于两耳不闻窗外事,一心只读圣贤书,还是因为真的风平浪静,一个季度过去了,貌似也没有发生什么大的事件。
想找一群有意思的人,一起做一些有意思的事,无关金钱与利益,只想追寻心和灵魂。
诗和远方最后都成为了自律和坚持。
大家有什么关于技术上的想法或者思路,哪怕是一些有意思的事,都可以告诉我,我可以和你一起通过努力去实现它或让距离变得更近。