frida笔记(安卓)
https://github.com/frida/frida/
##0x00 安装
frida分为2端 服务端和客户端 也就是被控制端和控制端
-
控制端安装 frida和frida-tool 这两个 可以去github下载安装包/apt intsall/使用pip3安装
之前使用的kali 2020使用github上安装包完美安装
dpkg -i
ubuntu16 … -
被控制端 只需要在github下载 并运行frida-server 就可以
##0x01基本使用
将frida-server放置到安卓可执行路径下 一般是/data/local/tmp
并打开手机端口转发(27403端口是否有用待定,博客写的)
adb push frida-server /data/local/tmp
adb forward tcp:27042 tcp:27042
adb forward tcp:27043 tcp:27043
adb shell
进入shell 运行frida-server
su
cd /data/local/tmp
chmod 777 frida-server
./frida-server
运行成功没有任何提示
在控制端使用frida-ps -U
查看是否连接成功 //-U表示usb设备
如果显示出手机上进程表示连接成功 可以进行下一步操作了
##0x02 简单hook(普通函数)
使用python脚本和js代码对安卓apk进行hook
与xposed不同 注意运行frida进行hook时候 apk必须正在运行 不可以hook中关了apk再来
想要被hook的一段安卓小demo
package com.example.myfrida;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
Button bt1=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt1=findViewById(R.id.button1);
bt1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,haha("giao"),Toast.LENGTH_LONG).show();
}
});
}
public static String haha(String str){
return str+"skrrrrrr...";
}
}
有时候hooked的内容在oncreate里边 你又要先运行app再hook 这时候又不能重运行app 可以使用返回键 返回到桌面 再打开app 这时候oncreate函数再次运行 并且没有关闭进程 不要用home键!! 不要杀了后台再打开!!
1.单独使用js
使用 -l 参数指定js脚本 后加包名 (此处应该不单单是包名,ps列表中运行中的二进制程序应该都可以hook 用法肯定和这个不一样)
最后的参数不是包名 是进程名 一个安装包可能有多个子进程 需要到frida-ps -U
列表里寻找 配合grep 包名
找的快一些
frida -U -l test.js com.example.myfrida
js脚本内容
if(Java.available){ //判断java虚拟机是否加载
Java.perform(function(){ //perform 为核心函数
var MainActivity = Java.use("com.example.myfrida.MainActivity"); //使用Java.use方法来找到被hooked类
MainActivity.haha.implementation=function(){
//调用MainActivity类中haha函数 并用implementation方法重写
//!!!!!=function()内也可以不用写参数!!!!
return "yigiaowoligiaogiao";
//此处是简单hook下 只重写函数内容 改下返回值
//也可以=function(a) 之后用send(a)将原本的参数发送到控制端
}
});
}
Java.available字段
这个字段标记Java虚拟机(例如: Dalvik 或者 ART)是否已加载, 操作Java任何东西之前,要确认这个值是否为
true
。
结束hook输入exit
退出
2.使用python调用js
康康python脚本内容
#coding=utf8
import frida, sys
jscode = """
if(Java.available){
Java.perform(function(){
var MainActivity = Java.use("com.example.myfrida.MainActivity");
MainActivity.haha.overload("java.lang.String").implementation=function(a){
console.log("[*] Frida测试的JS代码已调用!");
send("HOOK成功!");
send(a);
return this.haha("dnmd");
}
});
}
"""
#这个on_message函数名可以随意修改
def on_message(message, data):
if message['type'] == 'send':
print("[*] {0}".format(message['payload']))
else:
print(message)
pass
# 查找USB设备并附加到目标进程
session = frida.get_usb_device().attach('com.example.myfrida')
# 在目标进程里创建脚本
script = session.create_script(jscode)
# 注册消息回调
script.on('message', on_message)
print('[*] Start attach')
# 加载创建好的javascript脚本
script.load()
# 读取系统输入
sys.stdin.read()
直接运行就可以hook 注意是python3
python3 test.py
//有两个点比较疑惑MainActivity.haha.overload("java.lang.String").implementation=function(a){
的 overload("java.lang.String")
可以省略 仍然正常运行 重载overload到底要不要加??
=function(a)
里边的参数也可以省略
这两点是同一个点 当同一个类中有两个及以上同名函数时候 必须要加上overload() 和参数 用以区分
没有同名函数的话 加不加都可以
https://blog.csdn.net/zhy025907/article/details/80795661
有时间看看这个笔记 他的记录连接
##0x03构造函数hook
和普通函数一样 先获取类 但调用构造函数时候使用$init
表示构造函数的函数名
MainActivity.$init.implementation=function(a,b){
//..如果构造函数有参数 可以写参数
// do something
return this.$init(a,b);
}
##0x04自定义类对象参数的hook和对象实例化
如果某个函数的参数不是int,String等基本类型 而是一个自定义类 和xp一样 参数直接输入完整类名就可以
MainActivity.test.overload("com.giao.util").implementation=function(a,b){
//如果没有重载 overload甚至可以省略
// do something
return this.test(a,b);
}
实例化一个类对象 使用$new()函数 但是如果想实例它 事先要使用Java.use()
把这个类找出来
jscode = """
if(Java.available){
Java.perform(function(){
var call = Java.use("com.example.myfrida.call");
var fucked=Java.use("com.giao.student");
call.who.implementation=function(a){
//后边这几处代码没有测试过 只作为使用参考
var stu=fucked.$new("zhangsan",24,177,"男");
send(stu.getname()); //测试是否成功
return this.who(stu);
}
});
}
"""
##0x05类变量修改
如果要修改类变量 可以给变量名.value
赋值进行修改
也可以使用反射方式来进行调用 用到的时候再记录
##0x06与xposed的比较
-
目前来看 并没有直接打印参数,打印返回值等功能 只可以是修改函数(好在可以调用原函数)
如果只是想要打印 一定要加上return 否则会破坏原函数逻辑
-
最直观的就是方便 不用安装 不用重启
但是hook时候必须应用打开 adb连接着 不适用于日常使用