Frida介绍以及功能
- Frida 是一款功能强大的动态分析工具,主要用于对操作系统、桌面应用、移动应用和浏览器进行逆向工程和安全测试;
- 提供了比较灵活的 js api,可以在运行时通过注入代码来修改程序的逻辑;
- 因为本人研究的是Android方向,所以后面都会以Android例子为主;
功能
- 动态 Hook
- 可以在运行时通过 js代码来 hook 应用程序的方法,以达到修改程序逻辑;
- 内存分析
- 可以对程序内存进行实时分析,包括查找关键数据结构等;
- 动态脚本注入
- 可以在运行时注入js脚本来扩展程序的功能,如添加调试信息等;
hook Java 函数
hook Java函数例子
setImmediate(function () {
Java.perform(function () {
var MainActivity = Java.use('com.example.MainActivity');
// Hook Java 方法
MainActivity.foo.implementation = function (str) {
// 调用方法
var ret = this.foo(str);
console.log('Return value:', ret);
// 返回
return ret;
};
})
})
hook Native 函数
setImmediate(function () {
Java.perform(function () {
const nativeFuncAddr = Module.findExportByName(null, 'nativeFunc');
// Frida Gadget
Interceptor.attach(nativeFuncAddr, {
onEnter: function(args) {
// 输出函数的参数
console.log('nativeFunc(' + args[0] + ', ' + args[1] + ')');
// 修改参数
args[0] = ptr('0x1234');
args[1] = ptr('0x5678');
},
onLeave: function(retval) {
// 输出函数的返回值
console.log('returned: ' + retval);
}
});
})
})
Frida启动的两种模式以及区别
- frida启动有两种方式,分别为Spawn模式和 Attach 模式;
区别:
- 在 Spawn模式下,Frida 直接启动目标进程,然后在该进程中注入 Frida 的 Agent,也就是说,启动既注入;
- 在 Attach 模式下,Frida 会依附到已经运行的目标进程上,并在该进程中注入 Agent;
Spawn 模式启动方式:frida -U {package} -l xxx.js
Attach 模式启动方式:$ frida -U -l xxx.js -f {package}
Frida Hook 原理
- frida Server运行在目标设备上,他负责链接客户端与服务端;
- frida在目标进程中会运行一个frida gadget,他的主要作用是将frida Service和目标的进程连接,并提供一些接口实现hook;
- 实际使用中,可以在Client编写js代码,通过frida Service发送到目标进程的frida gadget中;
- frida gadget将js代码注入到目标进程的art虚拟机中,完成hook操作;
- 如果目标进程执行了hook函数时,frida会拦截并执行js代码中的逻辑;
其中,frida gadget会在目标进程中生成一个so文件;
在生成frida gadget的同时,同样也会在目标应用中生成一个json文件,名字一般为:frida-gadget.json
;
这个JSON文件中包含了一些关于Gadget的元数据信息,比如应用的包名、Gadget的版本号、Gadget启动时需要加载的库文件、被Gadget hook的函数列表等等;
这些信息可以被Frida客户端读取并解析,以便于正确地加载和运行Gadget。在一些情况下,我们也可以修改这个JSON文件,以实现一些更高级的功能,例如修改Gadget版本号或者修改Gadget hook的函数列表。
frida-gadget.json内容
{
"entrypoint": "module_initialize", // gadget的入口函数名
"auxiliary": [ // 辅助模块列表
"auxiliary_module1.js", // 第一个辅助模块
"auxiliary_module2.js" // 第二个辅助模块
],
"android": { // Android平台的配置
"package_name": "com.example.app", // 目标应用的包名
"use_frida_gadget": true, // 是否使用Frida Gadget模式
"spawn": true, // 是否在目标应用启动时自动启动gadget
"debug": true // 是否输出gadget的日志信息
},
"ios": { // iOS平台的配置
"use_frida_gadget": true, // 是否使用Frida Gadget模式
"spawn": true, // 是否在目标应用启动时自动启动gadget
"debug": true // 是否输出gadget的日志信息
},
"linux": { // Linux平台的配置
"use_frida_gadget": true, // 是否使用Frida Gadget模式
"debug": true // 是否输出gadget的日志信息
},
"macos": { // macOS平台的配置
"use_frida_gadget": true, // 是否使用Frida Gadget模式
"spawn": true, // 是否在目标应用启动时自动启动gadget
"debug": true // 是否输出gadget的日志信息
},
"windows": { // Windows平台的配置
"use_frida_gadget": true, // 是否使用Frida Gadget模式
"debug": true // 是否输出gadget的日志信息
}
}