searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Frida使用笔记

2024-07-16 09:32:21
17
0

0x01 环境准备

1. 环境搭建

安装容易遇到坑:pip install 有时候会遇到 ssl 问题,主要是python3的版本,最好用3.6。

  1. pip3 install frida-tools安装Frida客户端,frida --version输出版本信息代表安装成功;
  2. GitHub官方下载手机CPU型号对应的[frida-server];
  3. 解压frida-server-10.7.7-android-arm64.xz压缩文件,将frida-server push到Android手机.
    adb push ./frida-server-10.7.7-android-arm64 /data/local/tmp
  4. 设置frida-server权限.
    chmod 755 /data/local/tmp/frida-server-10.7.7-android-arm64
  5. 启动frida-server
    /data/local/tmp/frida-server-10.7.7-android-arm64
    如果需要frida-server在后台运行,使用下面命令最后加个 & 符合:
    /data/local/tmp/frida-server-10.7.7-android-arm64 &
  6. 在pc端执行命令frida-ps -U,看能否正常显示手机进程.-Ua查看运行的进程,ios可以查看应用包名。

7.有时候莫名其妙就是连不上,拔了线重新接一下

2. 在虚拟机使用Frida

  1. 远程连接虚拟机:adb connect 127.0.0.1:21503端口在安装软件安装目录的\MemuHyperv VMs\MEmu\MEmu.memu-prev文件中查询
  2. 将frida-server拷贝到虚拟机中,授权并启动.
  3. 本地转发端口adb forward tcp:27042 tcp:27042 和 adb forward tcp:27043 tcp:27043
  4. frida-ps -aR测试是否成功.

网易mumu

  1. adb shell进入shell
  2. 安装frida-server-12.8.6-android-x86(不支持64位)
  3. 在pc端执行命令frida-ps -U,看能否正常显示手机进程(​虚拟机相当于直接使用usb链接了​)

0x02 操作笔记

1. 注入OR生成新进程

  • 注入进程: frida -U com.xxx.xxx (注入到运行中的进程)
  • 生成进程: frida -U -f com.xxx.xxx (注入到Zygote,生成新进程)
  • 使用--no-pause命令,配合-f命令使用,不暂停在app启动时,如果没有使用no pause命令,需要进入CLI后用%resume恢复执行
  • 注入JS: frida -U com.xxx.xxx -l xxx.js
  • 在新进程中注入: frida -U -f com.xxx.xxx -l xxx.js --no-pause
  • F参数省去输入包名: frida -U -F -l xxx.js --no-pause, -F会直接注入当前APP

2. Hook Java

  1. Hook代码必须包装在Java.perform(function(){...})
  2. 使用setImmediate(function() {...}包装Java.perform,可以让已注入的代码实时更新(​修改js代码,无需重启即可立即生效​)
  3. 如果目标function没有重载方法,可以直接implementation Hook目标函数,如果目标function有多个重载方法,需要在implementation前使用overload(xx)。 注: Hook重载方法时,可以先不写overload,让注入报错,然后直接复制系统提示的重载方法,就省去自己写方法签名。
  4. $init表示构造方法,比如Hook testClz类的构造方法testClz.$init.implementation;
  5. Java.choose(className, callbacks) Hook没有被调用的方法、字段,示列如下:
Java.choose("com.github.curz0n.MainActivity" , {
  //每次扫描到一个实例对象,就调用一次,即,该类有多少个实例,该回调就会被触发多少次
  onMatch : function(instance){
    console.log("Found instance: "+instance);
    console.log("Result of secret func: " + instance.secret());
  },
  //当所有的对象都扫描完毕之后进行回调
  onComplete:function(){}
});
  1. function callSecretFun() {...}定义导出函数,使app内的方法可以在py里面直接调用;
function callSecretFun() { //定义导出函数
    Java.perform(function () { //找到隐藏函数并且调用
        Java.choose("com.github.curz0n.MainActivity", {
            onMatch: function (instance) {
                console.log("Found instance: " + instance);
                console.log("Result of secret func: " + instance.secret());
            },
            onComplete: function () { }
        });
    });
}
rpc.exports = {
    callsecretfunction: callSecretFun //把callSecretFun函数导出为callsecretfunction符号,导出名不可以有大写字母或者下划线
};

py里面直接调用script.exports.callsecretfunction()

常用命令

  • frida-ls-devices 列出电脑连接的设备
  • frida -D devices id 连接指定设备id的设备(电脑usb连接多台设备时)

回调对象

如下示例,长下面这个样子:

{
  "onMatch":function(arg1, ...){ ... },
  "onComplete":function(){ ... },
}

ByteString.of是用来把byte[]数组转成hex字符串的函数, Android系统自带ByteString类:
var ByteString = Java.use("com.android.okhttp.okio.ByteString");
ByteString.of(result).hex()

打印[object]
Java.openClassFile("/data/local/tmp/r0gson.dex").load();
const gson = Java.use('com.r0ysue.gson.Gson');
console.log(gson.$new().toJson(xxx));

3.JS code

xxx.js

console.log("Script loaded successfully 1");
Java.perform(function x() {
  //  hook initEx 并打印
  var test1 = Java.use('com.aliyun.security.yunceng.android.sdk.YunCeng')//定位到要hook的类名
  test1.initEx.implementation = function (arg1,arg2) {//equals就是我们要hook的函数,参数个数要对应上。
  console.log("initEx param1 : " + arg1);
  console.log("initEx param2 : " + arg2);//打印出来真实的解锁码
  var ret = this.equals(arg1);
  return ret;//返回值  返回值最好和hook的函数逻辑一致,不然会导致程序无法继续运行。如果只是单纯要打印就无所谓
  }

  // hook 打印资源类容
  var test1 = Java.use('im.ojuooqrdwu.ui.utils.ThirdPartSdkInitUtil')//定位到要hook的类名
  // 有的函数涉及到重载, 如果不知道怎么写,可以先不用overload,从frida的报错信息补充完整即可。
  test1.a.overload('android.content.Context').implementation = function (arg1,arg2,arg3,arg4,arg5,arg6) {
    console.log("initExRaw param1 : " + arg1.getResources().getString(0x7f0f140b));  // 原混淆代码为 R.getString("name"), 可以直接用资源文件里面的二进制值
    console.log("initExRaw param1 : " + arg1.getResources());
    console.log("initExRaw param2 : " + arg2);//打印出来真实的解锁码
  }

});
console.log("Script loaded successfully 2");

image.png

0条评论
0 / 1000
MelodyZX
2文章数
0粉丝数
MelodyZX
2 文章 | 0 粉丝
MelodyZX
2文章数
0粉丝数
MelodyZX
2 文章 | 0 粉丝
原创

Frida使用笔记

2024-07-16 09:32:21
17
0

0x01 环境准备

1. 环境搭建

安装容易遇到坑:pip install 有时候会遇到 ssl 问题,主要是python3的版本,最好用3.6。

  1. pip3 install frida-tools安装Frida客户端,frida --version输出版本信息代表安装成功;
  2. GitHub官方下载手机CPU型号对应的[frida-server];
  3. 解压frida-server-10.7.7-android-arm64.xz压缩文件,将frida-server push到Android手机.
    adb push ./frida-server-10.7.7-android-arm64 /data/local/tmp
  4. 设置frida-server权限.
    chmod 755 /data/local/tmp/frida-server-10.7.7-android-arm64
  5. 启动frida-server
    /data/local/tmp/frida-server-10.7.7-android-arm64
    如果需要frida-server在后台运行,使用下面命令最后加个 & 符合:
    /data/local/tmp/frida-server-10.7.7-android-arm64 &
  6. 在pc端执行命令frida-ps -U,看能否正常显示手机进程.-Ua查看运行的进程,ios可以查看应用包名。

7.有时候莫名其妙就是连不上,拔了线重新接一下

2. 在虚拟机使用Frida

  1. 远程连接虚拟机:adb connect 127.0.0.1:21503端口在安装软件安装目录的\MemuHyperv VMs\MEmu\MEmu.memu-prev文件中查询
  2. 将frida-server拷贝到虚拟机中,授权并启动.
  3. 本地转发端口adb forward tcp:27042 tcp:27042 和 adb forward tcp:27043 tcp:27043
  4. frida-ps -aR测试是否成功.

网易mumu

  1. adb shell进入shell
  2. 安装frida-server-12.8.6-android-x86(不支持64位)
  3. 在pc端执行命令frida-ps -U,看能否正常显示手机进程(​虚拟机相当于直接使用usb链接了​)

0x02 操作笔记

1. 注入OR生成新进程

  • 注入进程: frida -U com.xxx.xxx (注入到运行中的进程)
  • 生成进程: frida -U -f com.xxx.xxx (注入到Zygote,生成新进程)
  • 使用--no-pause命令,配合-f命令使用,不暂停在app启动时,如果没有使用no pause命令,需要进入CLI后用%resume恢复执行
  • 注入JS: frida -U com.xxx.xxx -l xxx.js
  • 在新进程中注入: frida -U -f com.xxx.xxx -l xxx.js --no-pause
  • F参数省去输入包名: frida -U -F -l xxx.js --no-pause, -F会直接注入当前APP

2. Hook Java

  1. Hook代码必须包装在Java.perform(function(){...})
  2. 使用setImmediate(function() {...}包装Java.perform,可以让已注入的代码实时更新(​修改js代码,无需重启即可立即生效​)
  3. 如果目标function没有重载方法,可以直接implementation Hook目标函数,如果目标function有多个重载方法,需要在implementation前使用overload(xx)。 注: Hook重载方法时,可以先不写overload,让注入报错,然后直接复制系统提示的重载方法,就省去自己写方法签名。
  4. $init表示构造方法,比如Hook testClz类的构造方法testClz.$init.implementation;
  5. Java.choose(className, callbacks) Hook没有被调用的方法、字段,示列如下:
Java.choose("com.github.curz0n.MainActivity" , {
  //每次扫描到一个实例对象,就调用一次,即,该类有多少个实例,该回调就会被触发多少次
  onMatch : function(instance){
    console.log("Found instance: "+instance);
    console.log("Result of secret func: " + instance.secret());
  },
  //当所有的对象都扫描完毕之后进行回调
  onComplete:function(){}
});
  1. function callSecretFun() {...}定义导出函数,使app内的方法可以在py里面直接调用;
function callSecretFun() { //定义导出函数
    Java.perform(function () { //找到隐藏函数并且调用
        Java.choose("com.github.curz0n.MainActivity", {
            onMatch: function (instance) {
                console.log("Found instance: " + instance);
                console.log("Result of secret func: " + instance.secret());
            },
            onComplete: function () { }
        });
    });
}
rpc.exports = {
    callsecretfunction: callSecretFun //把callSecretFun函数导出为callsecretfunction符号,导出名不可以有大写字母或者下划线
};

py里面直接调用script.exports.callsecretfunction()

常用命令

  • frida-ls-devices 列出电脑连接的设备
  • frida -D devices id 连接指定设备id的设备(电脑usb连接多台设备时)

回调对象

如下示例,长下面这个样子:

{
  "onMatch":function(arg1, ...){ ... },
  "onComplete":function(){ ... },
}

ByteString.of是用来把byte[]数组转成hex字符串的函数, Android系统自带ByteString类:
var ByteString = Java.use("com.android.okhttp.okio.ByteString");
ByteString.of(result).hex()

打印[object]
Java.openClassFile("/data/local/tmp/r0gson.dex").load();
const gson = Java.use('com.r0ysue.gson.Gson');
console.log(gson.$new().toJson(xxx));

3.JS code

xxx.js

console.log("Script loaded successfully 1");
Java.perform(function x() {
  //  hook initEx 并打印
  var test1 = Java.use('com.aliyun.security.yunceng.android.sdk.YunCeng')//定位到要hook的类名
  test1.initEx.implementation = function (arg1,arg2) {//equals就是我们要hook的函数,参数个数要对应上。
  console.log("initEx param1 : " + arg1);
  console.log("initEx param2 : " + arg2);//打印出来真实的解锁码
  var ret = this.equals(arg1);
  return ret;//返回值  返回值最好和hook的函数逻辑一致,不然会导致程序无法继续运行。如果只是单纯要打印就无所谓
  }

  // hook 打印资源类容
  var test1 = Java.use('im.ojuooqrdwu.ui.utils.ThirdPartSdkInitUtil')//定位到要hook的类名
  // 有的函数涉及到重载, 如果不知道怎么写,可以先不用overload,从frida的报错信息补充完整即可。
  test1.a.overload('android.content.Context').implementation = function (arg1,arg2,arg3,arg4,arg5,arg6) {
    console.log("initExRaw param1 : " + arg1.getResources().getString(0x7f0f140b));  // 原混淆代码为 R.getString("name"), 可以直接用资源文件里面的二进制值
    console.log("initExRaw param1 : " + arg1.getResources());
    console.log("initExRaw param2 : " + arg2);//打印出来真实的解锁码
  }

});
console.log("Script loaded successfully 2");

image.png

文章来自个人专栏
MelodyZX
2 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0