Frida

Frida 原理及简单使用 - Only-xiaoxiao - 博客园 (cnblogs.com)

找的一篇佬的博客

Android

基本环境创建

对于安卓模拟器:

首先需要手机端有frida server,如果是模拟器需要x86和x64的版本,如果是真机,需要arm86和arm64。然后本机需要frida。

模拟器

建立连接

在电脑端使用adb shell连接至手机端,在shell中启动frida_server,启动参数为:

1
./frida-server-x -l 0.0.0.0:xxxx

启动server时,-l指定ip和端口号,,用于创建和电脑端的连接

电脑端使用adb

1
adb forward tcp:xxxx tcp:xxxx

和手机端建立通信完成,现在frida-server正在等待电脑的frida连接

附加进程

不过frida附加的是进程,所以先使用

1
frida-ps -H 127.0.0.1:xxxx

-H表示frida指定使用端口号连接目标,用ps来查看目标的进程名,

得到进程名yyy后,使用

1
frida -H 127.0.0.1:xxxx yyy -l hook.js

使用同样的方法附加目标的yyy进程,并直接附加脚本hook.js,这里的脚本需要指定全部路径

连接上之后应该会出现frida提示信息和字符画

之后出现的命令行可以写入任意frida-js指令

真机

建立连接,由于手机是通过usb连接的,所以先在手机端启动server。
然后

1
frida-ps -U

U指usb调试

取得进程名。

然后使用

1
frida -U apk_name -l hook.js

使用hook.js附加到apk_name进程

使用脚本

native层的Hook:

1
2
3
4
5
6
7
8
9
10
11
function hook(){
}


function main(){
Java.perform(function (){//Java.perform函数会把后面传入的函数在Java环境中执行,这里使用匿名函数比较方便,里面写hook函数,如果只有一个hook函数可以直接传hook函数
hook();
});
}

setImmediate(main);//根据GPT,该函数把传入的函数注册到本轮消息队列末尾,IO操作完成时触发的函数之后,不会阻塞IO操作同时也会尽可能快速地执行这个函数

在hook中写自己的代码比如:

1
2
3
4
5
6
7
8
function hook(){
let xtea = Java.use("example.encrypt.xtea");//加载对应类
xtea["encrypt"].implementation =
function (iArr, iArr2) {
console.log(`xtea.encrypt is called: iArr=${iArr}, iArr2=${iArr2}`);
this["encrypt"](iArr, iArr2);
};
}
1
xtea["encrypt"]可以通过[]取对应的方法,然后使用implementation来重写方法,后面跟一个相同传参的匿名函数,注意一定要在这个函数中调用this["encrypt"](iArr, iArr2);来调用原函数,如果这个函数有返回值可以令let retV = this["encrypt"](iArr, iArr2);再console.log出来

Windows

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var number = 0;
function main(){
var base = Module.findBaseAddress("xxx.exe")//通过exe来寻找基址
console.log("inject success")
if (base){
Intercepor.attach(base.add(0xFFF),{//这里的数值是目标指令地址相对于base的偏移量
onEnter: function(args){//进入时执行
console.log(args)
},
{
onLeave: function(retval){//离开时执行
console.log(retval)
}
});
}
}

上面是插指令的桩

1
2
3
4
5
6
7
8
9
10
functionsToHook.forEach(functionName => {
Interceptor.attach(Module.getExportByName("xxx.dll", functionName), {//通过导出表直接插函数
onEnter: function (args) {
xxx
},
onLeave: function (retval) {
xxx
}
});
});

这是插函数的桩


未完结