测试用例
测试用例结构比较简单。 ![请添加图片描述](https://img-blog.csdnimg.cn/afd7b3ea6db34aa59fffd6215c024a04.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3p5YzM1NDU=,size_16,color_FFFFFF,t_70) 主要代码都在 MainActivity 和 Car 中。SecondActivity、MainService、MyReceiver以及布局文件并无实效代码,就不予展示了。
package com.zyc.objectiondemo;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
public static int CAR_COUNT = 0;
private Button btnShow;
private Button btnShow_int;
private Car car1;
private Car car2;
private Car car3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnShow = findViewById(R.id.btn_show);
btnShow.setOnClickListener(this);
btnShow_int = findViewById(R.id.btn_show_int);
btnShow_int.setOnClickListener(this);
car1 = new Car(1, "布加迪");
car2 = new Car(2, "奔驰qqqaaa");
car3 = new Car(3, "aaaqqq");
CAR_COUNT = 3;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_show:
Car tempCar1 = new Car(4);
tempCar1.setName("Car4");
String txt = tempCar1.show();
Toast.makeText(this, txt, Toast.LENGTH_SHORT).show();
break;
case R.id.btn_show_int:
Car tempCar2 = new Car(5,"Car5");
String txt2 = tempCar2.show(989);
Toast.makeText(this, txt2, Toast.LENGTH_SHORT).show();
break;
}
}
public void toastSelf() {
Toast.makeText(this, "I'm MainActivity", Toast.LENGTH_SHORT).show();
}
}
package com.zyc.objectiondemo;
public class Car {
private int id;
private String name;
public Car(int id) {
this.id = id;
}
public Car(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String show() {
return "id--> " + id + "\nname--> " + name;
}
public String show(int count) {
return "id--> " + id + "\nname--> " + name + "\ncount--> " + count;
}
}
运行 frida-server 后开启 objection 之旅:
objection -g com.zyc.objectiondemo explore
?
列出内存中加载的库
memory list modules 。 ![请添加图片描述](https://img-blog.csdnimg.cn/eda56cededab414d9aca4314e438fd72.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3p5YzM1NDU=,size_16,color_FFFFFF,t_70) 如果要把结果以json格式输出到本地可以在指令后添加参数,memory list modules --json /root/modules.json 。 ![请添加图片描述](https://img-blog.csdnimg.cn/0176148deeff4c45b21687217c325730.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3p5YzM1NDU=,size_16,color_FFFFFF,t_70) ?
列出某个库的导出函数
假设要列出 libssl.so 文件的导出函数,memory list exports libssl.so 。 ![请添加图片描述](https://img-blog.csdnimg.cn/77eb0b75a7ec45cab05957087902dab5.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3p5YzM1NDU=,size_16,color_FFFFFF,t_70) 该指令同样支持输出到json文件,memory list exports libssl.so --json /root/exports.json 。 ![请添加图片描述](https://img-blog.csdnimg.cn/731f661369694f7ebc1a365a8312bd87.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3p5YzM1NDU=,size_16,color_FFFFFF,t_70) ?
搜索内存数据
在内存中通过字节串可以搜索数据,APP点击按钮创建带“aaaqqq”和“奔驰qqqaaa”字样的Car类后,想找到“aaaqqq”运行memory search "61 61 61 71 71 71" ,或者模糊搜索memory search "61 61 61 71" 、memory search "61 61 61 ?? ?? 71" 。 ![请添加图片描述](https://img-blog.csdnimg.cn/aef9e18fa0f5499f8d7cea131440a84b.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3p5YzM1NDU=,size_16,color_FFFFFF,t_70) 该指令貌似无法搜索出带中文的字符串。 ![请添加图片描述](https://img-blog.csdnimg.cn/569d67e77e0a4bf59d11dc5b7d363ed1.jpg) 也可以增加参数通过字符串搜索,运行memory search "aaaqqq" --string ,此方式不支持模糊搜索。 ![请添加图片描述](https://img-blog.csdnimg.cn/b6c8fe3369a343cb9b420f080711c0bc.jpg) 如果只展示搜索到的偏移地址,不需要展示附近内存,运行memory search "61 61 61 71 71 71" --offsets-only 。 ![请添加图片描述](https://img-blog.csdnimg.cn/25908207118d40afb0b8d09d32449a8d.jpg) ?
写入内存数据
通过内存地址可以写入数据,比如搜索TextView的文字“Helloword”并通过memory write 0x12fc9c78 '61 61 61' 修改其中一处结果,再把进程切换一下后台&前台,就刷新成修改的数据了。 ![请添加图片描述](https://img-blog.csdnimg.cn/527ea5ff69724ec7a7d3ebe1b84189a7.gif) ?
提取内存数据
有了内存数据的偏移和长度,就可以通过memory dump from_base 0x12fc9c78 9 /root/memory.txt 指令把刚才的内存dump到本地。 ![请添加图片描述](https://img-blog.csdnimg.cn/54ee7878fbdf41d9ab37d667949f9295.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3p5YzM1NDU=,size_16,color_FFFFFF,t_70) ?
列出内存中所有的类
android hooking list classes ,本次找到了5511个类。 ![请添加图片描述](https://img-blog.csdnimg.cn/d738e2a43a544ecea20826dc88116874.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3p5YzM1NDU=,size_16,color_FFFFFF,t_70) ?
列出指定类的所有方法
假设要查看APP MainActivity 类的方法,运行android hooking list class_methods com.zyc.objectiondemo.MainActivity ,可以看到只打印了属于该类的方法,继承来的并不会打印。 ![请添加图片描述](https://img-blog.csdnimg.cn/33538e5d1bc4453e8e0a079a339fb858.jpg) ?
在内存中所有的类里搜索类
从已加载的类里查找和“zyc”关键字,运行android hooking search classes zyc 。 ![请添加图片描述](https://img-blog.csdnimg.cn/1dcbac718da1483d9e156a8133facf5d.jpg) ?
在内存中所有的类里搜索方法
假设要搜索带“onCreate”的方法,运行android hooking search methods onCreate 。该指令会遍历内存中所有已加载类的所有方法执行搜索,数据量非常大,过程相当耗时,甚至容易卡死和崩溃,所以会在运行前手动输入“y”同意。 ![请添加图片描述](https://img-blog.csdnimg.cn/c8189bbae3bd4ff0bd6bbc6407cb9a35.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3p5YzM1NDU=,size_16,color_FFFFFF,t_70) ?
列出所有Activity、Service、Receiver
查看APP的组件使用android hooking list activities 、android hooking list services 、android hooking list receivers 命令。 ![请添加图片描述](https://img-blog.csdnimg.cn/a561fb4f188e43df8b7a541ade57960f.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3p5YzM1NDU=,size_16,color_FFFFFF,t_70) ?
启动Activity
使用android intent launch_activity com.zyc.objectiondemo.SecondActivity 会以 Intent.FLAG_ACTIVITY_NEW_TASK 的方式直接启动Activity页面,通过此命令有时可以直接启动某些常规方式访问不到的页面。 ![请添加图片描述](https://img-blog.csdnimg.cn/b90739925551427d92fcbafbccb82f5b.gif) ?
内存堆上搜索实例
从用例代码可知,运行APP进入 MainActivity 后会创建3个Car对象,此时如果想查看内存中的Car实例,运行android heap search instances com.zyc.objectiondemo.Car 。 ![请添加图片描述](https://img-blog.csdnimg.cn/1cc4a0b4c6f542ec8bb3a759e3f7423b.jpg) ?
调用实例的方法
搜索到实例获取地址后可调用其方法。如果要调用实例1的 show() 方法,运行android heap execute 68389604 show 。 ![请添加图片描述](https://img-blog.csdnimg.cn/02a56010e1c448c79308ec4a5761877c.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3p5YzM1NDU=,size_16,color_FFFFFF,t_70) ?
实时注入实例
拿到实例后可以直接在实例上书写js注入,运行android heap evaluate 23973990 会进入js编辑器,可以实时编写、注入、调试,但没有代码提示。 ![请添加图片描述](https://img-blog.csdnimg.cn/70945b354e884de0b7c46ba054d22cf0.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3p5YzM1NDU=,size_16,color_FFFFFF,t_70) ?
导入Hook代码
objection支持导入Hook js文件使用,比如 /root/Desktop/objectionHook.js 有下面Hook代码:
function main() {
Java.perform(function () {
console.log("Hook start...");
var Car = Java.use("com.zyc.objectiondemo.Car");
Car.show.overload("int").implementation = function (arg1) {
console.log("Hook show..." + arg1);
return this.show(arg1);
}
});
}
setImmediate(main())
运行import /root/Desktop/objectionHook.js 就可以在objection中直接使用了。 ![请添加图片描述](https://img-blog.csdnimg.cn/b9669e3c01ef4219bac6be62edaa9cac.gif) ?
Hook类所有方法
运行android hooking watch class com.zyc.objectiondemo.Car 可以Hook到Car类下所有方法(不包括构造方法)的调用。 ![请添加图片描述](https://img-blog.csdnimg.cn/44dc367640a541bf87810a9d1e9e82a4.gif) ?
Hook类单个方法
如果只需要Hook单个方法(包括其重载),比如上面没有Hook到的Car类构造函数,可以运行android hooking watch class_method com.zyc.objectiondemo.Car.$init 。 ![请添加图片描述](https://img-blog.csdnimg.cn/8419949d5a1348d1944e624996257a72.gif) ? 如果不需要Hook方法的重载,可以在方法名后面加上参数类型android hooking watch class_method com.zyc.objectiondemo.Car.$init "int,java.lang.String" 。 ![请添加图片描述](https://img-blog.csdnimg.cn/4165bc6eb559422aa7cefced47d9a576.gif) 指令末尾加上对应选项可以展示参数、返回值和调用栈,运行android hooking watch class_method com.zyc.objectiondemo.Car.show --dump-args --dump-return --dump-backtrace 。 ![请添加图片描述](https://img-blog.csdnimg.cn/03f75e9f6b7544e2b4ef4f2725e796b0.gif) ?
任务系统
objection可以同时运行多项任务,比如下图创建Hook任务时打印了任务id 629342,通过指令jobs list 能查看当前运作的任务。 ![请添加图片描述](https://img-blog.csdnimg.cn/6b2129c51af1499faa9df4669c709b87.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3p5YzM1NDU=,size_16,color_FFFFFF,t_70) 可以通过id结束某项任务,运行jobs kill 629342 。 ![请添加图片描述](https://img-blog.csdnimg.cn/79c42568e1bc4136bfbd898112187f83.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3p5YzM1NDU=,size_16,color_FFFFFF,t_70) ?
参考资料
实用FRIDA进阶:内存漫游、hook anywhere、抓包
|