# FridaTestApp 学习Frida过程中的代码
[Frida document frida.re/docs/home](https://frida.re/docs/home/)
# Frida简单使用
## Frida java层hook
1. 编写MainActivity,添加按钮`btnMethodHooked`
2. 为其注册点击监听,编写HookedObject类,调用其中的方法
3. 运行
```bash
btnMethodHooked: 9
btnMethodHooked: helloFridahelloFrida
btnMethodHooked: 20
```
4. 编写Frida脚本
5. 运行
```bash
frida -H 192.168.0.104:8888 -f com.forgotten.fridatestapp -l test.js
```
```javascript
function main() {
Java.perform(function () {
// 先查找HookedObject类,然后hook其的stringTwo方法
Java.use("com.forgotten.fridatestapp.HookedObject").stringTwo.implementation = function (arg) {
// this为当前实例,获得原方法执行的结果
var result = this.stringTwo(arg);
// 打印参数和原方法结果
console.log("stringTwo arg,result: ", arg, result);
// 对方法的结果进行修改(相当于重写了该方法)
return Java.use("java.lang.String").$new("hhello");
};
// hook addNumber方法 function参数列表可以什么都不填
Java.use("com.forgotten.fridatestapp.HookedObject").addNumber.overload("int", "int").implementation = function () {
// 内置有变量[argument],为方法的参数列表
for (var i = 0; i < arguments.length; i++) {
console.log("addNumber arguments[" + i + "]=" + arguments[i]);
}
var result = this.addNumber(arguments[0], arguments[1]);
console.log("addNumber arg,result: ", arguments, result);
return 99;
};
});
}
// Frida一附加上,就执行函数
setImmediate(main);
```
- 对于内部类,通过`类名$内部类名`去use或者choose
## Frida访问方法及变量
- 方法调用
- 静态方法使用`Java.use`获得**类**后直接调用
- 非静态方法需要使用`Java.choose`查找到**类实例**后进行调用
- 构造方法为`$init`
- 静态/非静态变量
- 设置成员变量的值,写法是`[field_name].value = [value]`,其他方面和函数一样。
- 如果有一个成员变量和成员函数的名字相同,则在其前面加一个`_`,如`_[field_name].value = [value]`
```javascript
function invoke() {
Java.perform(function () {
// 在内存中搜索类的实例
Java.choose("com.forgotten.fridatestapp.HookedObject", {
// 如果匹配上执行回调,参数为类实例
onMatch: function (instance) {
console.log("Found `HookedObject` instance:", instance);
// 打印私有成员变量的值,需要[field].value
console.log("instance.score =", instance.score.value);
// 打印静态成员变量的值
console.log("HookedObject.msg =", Java.use("com.forgotten.fridatestapp.HookedObject").msg.value);
// 修改成员变量的值
instance.score.value = Java.use("java.lang.Integer").parseInt("-900");
// 打印修改之后的值
console.log("instance.score =", instance.score.value);
// 与方法同名的成员变量,需前面加_
console.log("instance.stringTwo =", instance._stringTwo.value);
},
// 搜索完成执行回调
onComplete: function () {
console.log("Found Completed");
},
});
});
}
// Frida附加上后延迟5秒执行,期间由于逻辑问题需要主动点击按钮来实例化对象
setTimeout(invoke, 5000);
```
### Frida构造打印对象
#### array数组`[Object Object]`
```javascript
Java.perform(function () {
// Hook Arrays.toString方法 重载char[]
Java.use("java.util.Arrays").toString.overload("[C").implementation = function () {
// 打印参数
console.log("arg = ", arguments[0]);
/* 手动构造一个Java array:参数一为类型,参数二为数组 */
var arg = Java.array("char", ["上", "山", "打", "老", "虎"]);
var result = this.toString(arg);
console.log("[NEW]arg,result = ", arg, result);
return result;
};
});
Java.perform(function () {
// Java.use("java.util.Arrays").toString.overload("[B").implementation = function () {
/* `.toString`方法同时也可用`["toString"]`替代,这两种形式等价 */
Java.use("java.util.Arrays")["toString"].overload("[B").implementation = function () {
var result = this.toString(arguments[0]);
console.log('["toString"] arg,result = ', arguments[0], result);
return result;
};
});
```
#### Map
```javascript
Java.perform(function () {
// 在内存中查找ConstructoredObject类的实例
Java.choose("com.forgotten.fridatestapp.construct.ConstructoredObject", {
onMatch: function (instance) {
// 找到后获取实例field map的值,尝试转为HashMap类型
var vmap = Java.cast(instance.map.value, Java.use("java.util.HashMap"));
console.log("vmap:", vmap);
console.log("vmap.toString():", vmap.toString());
},
onComplete: function () {
console.log("vmap: search completed");
},
});
});
```
#### 枚举类型
```javascript
Java.perform(function () {
Java.choose("com.forgotten.fridatestapp.construct.ConstructoredObject", {
onMatch: function (instance) {
// 找到后获取实例field map的值,尝试转为自定义Enum Signal类型
var venum = Java.cast(instance.color.value, Java.use("com.forgotten.fridatestapp.construct.ConstructoredObject$Signal"));
console.log("venum:", venum);
// 调用Enum的方法
console.log("venum.name():", venum.name());
},
onComplete: function () {
console.log("venum: search completed");
},
});
});
```
#### 转型
可以通过`getClass().getName().toString()`来查看当前实例的类型。
找到一个instance,通过`Java.cast`来强制转换对象的类型。
向上转型
**不能将父类对象转为子类类型**
```javascript
Java.perform(function () {
Java.choose("com.forgotten.fridatestapp.construct.ConstructoredObject", {
onMatch: function (instance) {
// 获取成员变量wJuice的值,并明确类型为父类Water
var wJuice = Java.cast(instance.wJuice.value, Java.use("com.forgotten.fridatestapp.construct.Water"));
// 调用父类Water的still()方法
console.log("wJuice.still():", wJuice.still(wJuice));
// 明确类型为子类Juice,调用其方法
console.log("wJuice.fillEnergy():", Java.cast(wJuice, Java.use("com.forgotten.fridatestapp.construct.Juice")).fillEnergy());
},
onComplete: function () {
console.log("wJuice: search completed");
},
});
});
```
#### 编写自定义类
```javascript
Java.perform(function () {
// 新建类实现的接口,先获取其类
var face = Java.use("com.forgotten.fridatestapp.construct.CheerInterface");
// 创建一个类
var beer = Java.registerClass({
// 类的名称,小写就可
name: "com.forgotten.fridatestapp.beer",
// 实现的接口数组,多个来写[a, b]
implements: [face],
// 类中含有的方法
methods: {
cheer: function () {
console.log("Cheer!!!");
},
},
/**
* 其余的可写属性:`super` 父类;`protocols` 该类遵循的协议数组?
*/
});
console.log("beer:", beer);
// 调用一下自己编写的类的方法
beer.$new().cheer();
});
```
#### Frida加载dex中
徐浪老师
- 粉丝: 8539
- 资源: 1万+
最新资源
- MTK BT认证测试,工具说明
- ubuntu系统,Qt结合opencv开发相关内容,本人操作过程中遇到问题及解答方案
- E000627美妆美甲医学美容医院类网站模板.zip+PHP+Mysql+易优CMS+建站模板
- 玉米识别数据集 yolov11格式标注,5647张图,可精准识别玉米粒,正确识别率达到99.6%,用于识别检测玉米粒个数统计,或识别是否包含玉米
- 玉米识别数据集 yolov9格式标注,5647张图,可精准识别玉米粒,正确识别率达到99.6%,用于识别检测玉米粒个数统计,或识别是否包含玉米
- 《机器学习实战》-机器学习领域的Python实践指南:涵盖基础理论与实战项目
- 机械设计铭牌气动打标机sw16可编辑全套技术资料100%好用.zip
- 机械设计密码门锁翻盖疲劳测试sw17可编辑全套技术资料100%好用.zip
- FreeModbus协议栈从入门到精通,含STM32+FreeRTOS主站、从站例程DEMO,注释详尽
- chrome插件 可以将一张图片分割成任意等份
- 德普微一级代理 DP5201AA DFN 2*2-6L, 1节锂电池用二合一保护
- 德普微一级代理 DP5201AB DFN 2*2-6L 1节锂电池用二合一保护
- 神卓S700异地组网设备的监控互联解决方案及其应用
- 德普微一级代理 DP5201BA DFN 2*2-6L 1节锂电池用二合一保护
- 德普微一级代理 DP5201DCA DFN1*1 1节锂离子/锂聚合物电池保护芯片(集成功率 MOS)
- 蓝桥杯嵌入式赛点资源包
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈