app逆向-ratel框架-通过Java的反射机制主动调用Java类函数

news/2024/4/13 12:27:06/文章来源:https://blog.csdn.net/u010226586/article/details/136537600

文章目录

    • 一、前言
    • 二、实现方法
      • 1、对静态函数的主动调用
      • 2、ratel框架-对静态函数的主动调用
      • 3、对实例方法进行主动调用(无参)
      • 4、对实例方法进行主动调用(有参)
      • 5、ratel框架-对实例方法进行主动调用(有参/无参)
      • 6、内部类的方法主动调用(有参)
      • 7、ratel框架-内部类函数主动调用(有参)
      • 8、JNI函数主动调用
      • 9、ratel框架-JNI函数主动调用
    • 三、完整代码

一、前言

Java的反射机制是指在运行时动态地获取类的信息以及操作类的属性、方法、构造函数等的能力。通过反射机制,可以在程序运行时检查类的结构,获取类的字段、方法、注解等信息,调用类的方法,以及动态创建类的实例,而无需在编译时确定这些信息。

二、实现方法

1、对静态函数的主动调用

// 步骤一先通过这个app的classloader拿到类实例,(只有这个app的classloader才能加载这个app的类)
Class<?> ClassMysteryBox = lpparam.classLoader.loadClass("com.example.myapplication.MysteryBox");
// 步骤二通过实例拿到方法
Method staticMethod = ClassMysteryBox.getDeclaredMethod("staticMethod", String.class, int.class);
staticMethod.setAccessible(true);
// 步骤三通过方法进行调用
Object zhangsan = staticMethod.invoke(ClassMysteryBox, "张三", 1000);
Log.d(TAG, "handleLoadPackage: zhangsan = " + zhangsan);// 1.2 对实例方法进行主动调用 public String instanceMethod(String name,int price){
// 步骤一先调用目标方法的无参的默认的构造函数
Object instance = ClassMysteryBox.newInstance();
Method instanceMethod = ClassMysteryBox.getDeclaredMethod("instanceMethod", String.class, int.class);
Object lisi = instanceMethod.invoke(instance, "李四", 200);
Log.d(TAG, "handleLoadPackage: lisi = " + lisi);

2、ratel框架-对静态函数的主动调用

// 2.1 静态方法的调用 方法一:public static Object callStaticMethod(Class<?> clazz, String methodName, Object... args) {
Object o = RposedHelpers.callStaticMethod(ClassMysteryBox, "staticMethod", "张三", 200);
Log.d(TAG, "handleLoadPackage: o = " + o);
// 方法二(需要自己写参数类型):public static Object callStaticMethod(Class<?> clazz, String methodName, Class<?>[] parameterTypes, Object... args) {
Object o1 = RposedHelpers.callStaticMethod(ClassMysteryBox, "staticMethod", new Class<?>[]{String.class, int.class}, "张三", 200);
Log.d(TAG, "handleLoadPackage: o1 = " + o1);

3、对实例方法进行主动调用(无参)

// 步骤一先调用目标方法的无参的默认的构造函数
Object instance = ClassMysteryBox.newInstance();
Method instanceMethod = ClassMysteryBox.getDeclaredMethod("instanceMethod", String.class, int.class);
Object lisi = instanceMethod.invoke(instance, "李四", 200);
Log.d(TAG, "handleLoadPackage: lisi = " + lisi);

4、对实例方法进行主动调用(有参)

// private MysteryBox(String brand){
Constructor<?> declaredConstructor = ClassMysteryBox.getDeclaredConstructor(int.class);
Object instance1 = declaredConstructor.newInstance(222222);
Log.d(TAG, "handleLoadPackage: instance1 = " + instance1);
Object wangwu = instanceMethod.invoke(instance1, "王五", 600);
Log.d(TAG, "handleLoadPackage: wangwu = " + wangwu);

5、ratel框架-对实例方法进行主动调用(有参/无参)

// public static Object newInstance(Class<?> clazz, Object... args) {
// public static Object newInstance(Class<?> clazz, Class<?>[] parameterTypes, Object... args) {
// 无参构造函数实例化
Object o2 = RposedHelpers.newInstance(ClassMysteryBox);
Log.d(TAG, "handleLoadPackage: o2 = " + o2);Object instance5 = RposedHelpers.newInstance(ClassMysteryBox, "测试");
Log.d(TAG, "handleLoadPackage: instance5 = " + instance5);

6、内部类的方法主动调用(有参)

// 通过类加载器加载目标类
Class<?> classInnerClass = lpparam.classLoader.loadClass("com.example.myapplication.MysteryBox$InnerClass");
// 获取构造函数进行类实例
Constructor<?> declaredConstructor1 = classInnerClass.getDeclaredConstructor();
declaredConstructor1.setAccessible(true);
Object instance2 = declaredConstructor1.newInstance();
// 获取类的方法
Method innerClassMethod = classInnerClass.getDeclaredMethod("innerClassMethod", String.class, int.class);
innerClassMethod.setAccessible(true);
// 进行方法调用
Object zhaoliu = innerClassMethod.invoke(instance2, "赵六", 300);
Log.d(TAG, "handleLoadPackage: zhaoliu = " + zhaoliu);

7、ratel框架-内部类函数主动调用(有参)

Class<?> aClass = RposedHelpers.findClass("com.example.myapplication.MysteryBox$InnerClass", lpparam.classLoader);
Object o3 = RposedHelpers.callMethod(RposedHelpers.newInstance(aClass), "innerClassMethod", "赵六", 200);
Log.d(TAG, "handleLoadPackage: o3 = " + o3);

8、JNI函数主动调用

// 1.4 对于JNI函数的处理(native)
Class<?> NativeLib = lpparam.classLoader.loadClass("com.example.myapplication.NativeLib");
Constructor<?> constructor = NativeLib.getConstructor();
constructor.setAccessible(true);
Object instance3 = constructor.newInstance();
Method nativeMethod = NativeLib.getDeclaredMethod("nativeMethod");
// native和private方法都要设true才能访问
nativeMethod.setAccessible(true);
Object result = nativeMethod.invoke(instance3);
Log.d(TAG, "handleLoadPackage: result = " + result);

9、ratel框架-JNI函数主动调用

// 2.4 JNI函数的处理
Object instance6 = RposedHelpers.newInstance(RposedHelpers.findClass("com.example.myapplication.NativeLib", lpparam.classLoader));
Object nativeMethod1 = RposedHelpers.callMethod(instance6, "nativeMethod");
// 这里打印出来的依然是没有经过生命周期处理后的值,因为这是直接new的activity的实例,不会经过oncreate的处理
Log.d(TAG, "handleLoadPackage: nativeMethod1 = " + nativeMethod1);

三、完整代码

package com.example.plugintest;import android.os.Bundle;
import android.util.Log;import com.virjar.ratel.api.rposed.IRposedHookLoadPackage;
import com.virjar.ratel.api.rposed.RC_MethodHook;
import com.virjar.ratel.api.rposed.RposedHelpers;
import com.virjar.ratel.api.rposed.callbacks.RC_LoadPackage;import java.lang.reflect.Constructor;
import java.lang.reflect.Method;public class InvokeEntry implements IRposedHookLoadPackage {private static final String TAG = "pluginTest->";@Overridepublic void handleLoadPackage(RC_LoadPackage.LoadPackageParam lpparam) throws Throwable {System.out.println(TAG + "包名是什么:" + lpparam.packageName);if (lpparam.packageName.equals("com.example.myapplication")){Log.d(TAG, "handleLoadPackage: hook success");// 1. 利用Java的反射机制完成对于类函数的主动调用// 1.1 对静态函数的主动调用 public static String staticMethod(String name,int price){// 步骤一先通过这个app的classloader拿到类实例,(只有这个app的classloader才能加载这个app的类)Class<?> ClassMysteryBox = lpparam.classLoader.loadClass("com.example.myapplication.MysteryBox");// 步骤二通过实例拿到方法Method staticMethod = ClassMysteryBox.getDeclaredMethod("staticMethod", String.class, int.class);staticMethod.setAccessible(true);// 步骤三通过方法进行调用Object zhangsan = staticMethod.invoke(ClassMysteryBox, "张三", 1000);Log.d(TAG, "handleLoadPackage: zhangsan = " + zhangsan);// 1.2 对实例方法进行主动调用 public String instanceMethod(String name,int price){// 步骤一先调用目标方法的无参的默认的构造函数Object instance = ClassMysteryBox.newInstance();Method instanceMethod = ClassMysteryBox.getDeclaredMethod("instanceMethod", String.class, int.class);Object lisi = instanceMethod.invoke(instance, "李四", 200);Log.d(TAG, "handleLoadPackage: lisi = " + lisi);// 如果采用有参的构造函数// private MysteryBox(String brand){Constructor<?> declaredConstructor = ClassMysteryBox.getDeclaredConstructor(int.class);Object instance1 = declaredConstructor.newInstance(222222);Log.d(TAG, "handleLoadPackage: instance1 = " + instance1);Object wangwu = instanceMethod.invoke(instance1, "王五", 600);Log.d(TAG, "handleLoadPackage: wangwu = " + wangwu);// 1.3 内部类的处理// 通过类加载器加载目标类Class<?> classInnerClass = lpparam.classLoader.loadClass("com.example.myapplication.MysteryBox$InnerClass");// 获取构造函数进行类实例Constructor<?> declaredConstructor1 = classInnerClass.getDeclaredConstructor();declaredConstructor1.setAccessible(true);Object instance2 = declaredConstructor1.newInstance();// 获取类的方法Method innerClassMethod = classInnerClass.getDeclaredMethod("innerClassMethod", String.class, int.class);innerClassMethod.setAccessible(true);// 进行方法调用Object zhaoliu = innerClassMethod.invoke(instance2, "赵六", 300);Log.d(TAG, "handleLoadPackage: zhaoliu = " + zhaoliu);// 1.4 对于JNI函数的处理(native)Class<?> NativeLib = lpparam.classLoader.loadClass("com.example.myapplication.NativeLib");Constructor<?> constructor = NativeLib.getConstructor();constructor.setAccessible(true);Object instance3 = constructor.newInstance();Method nativeMethod = NativeLib.getDeclaredMethod("nativeMethod");// native和private方法都要设true才能访问nativeMethod.setAccessible(true);Object result = nativeMethod.invoke(instance3);Log.d(TAG, "handleLoadPackage: result = " + result);// 1.5 处理1.4存在的问题:像1.4那样new MainActivity实例是不会走oncreate等等的生命周期,所以在各生命周期中做的赋值或修改操作将无法// 出现在新实例中。于是我们不需要自己new,而是hook它本来存在的那个//RposedHelpers.findAndHookMethod(NativeLib, "onCreate", Bundle.class, new RC_MethodHook() {//    @Override//    protected void afterHookedMethod(MethodHookParam param) throws Throwable {//        super.afterHookedMethod(param);//        // 获得真实运行在app中的实例//        Object thisObject = param.thisObject;//        Object invoke = nativeMethod.invoke(thisObject);//        Log.d(TAG, "afterHookedMethod: 真实返回值为:" + invoke);//    }//});// 通过平头哥框架完成函数的主动调用// 2.1 静态方法的调用 方法一:public static Object callStaticMethod(Class<?> clazz, String methodName, Object... args) {Object o = RposedHelpers.callStaticMethod(ClassMysteryBox, "staticMethod", "张三", 200);Log.d(TAG, "handleLoadPackage: o = " + o);// 方法二(需要自己写参数类型):public static Object callStaticMethod(Class<?> clazz, String methodName, Class<?>[] parameterTypes, Object... args) {Object o1 = RposedHelpers.callStaticMethod(ClassMysteryBox, "staticMethod", new Class<?>[]{String.class, int.class}, "张三", 200);Log.d(TAG, "handleLoadPackage: o1 = " + o1);// 2.2 实例函数的调用// public static Object newInstance(Class<?> clazz, Object... args) {// public static Object newInstance(Class<?> clazz, Class<?>[] parameterTypes, Object... args) {// 无参构造函数实例化Object o2 = RposedHelpers.newInstance(ClassMysteryBox);Log.d(TAG, "handleLoadPackage: o2 = " + o2);Object instance5 = RposedHelpers.newInstance(ClassMysteryBox, "测试");Log.d(TAG, "handleLoadPackage: instance5 = " + instance5);// 2.3 内部类的处理Class<?> aClass = RposedHelpers.findClass("com.example.myapplication.MysteryBox$InnerClass", lpparam.classLoader);Object o3 = RposedHelpers.callMethod(RposedHelpers.newInstance(aClass), "innerClassMethod", "赵六", 200);Log.d(TAG, "handleLoadPackage: o3 = " + o3);// 2.4 JNI函数的处理Object instance6 = RposedHelpers.newInstance(RposedHelpers.findClass("com.example.myapplication.NativeLib", lpparam.classLoader));Object nativeMethod1 = RposedHelpers.callMethod(instance6, "nativeMethod");// 这里打印出来的依然是没有经过生命周期处理后的值,因为这是直接new的activity的实例,不会经过oncreate的处理Log.d(TAG, "handleLoadPackage: nativeMethod1 = " + nativeMethod1);}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_998217.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

访问修饰符、Object(方法,使用、equals)、查看equals底层、final--学习JavaEE的day15

day15 一、访问修饰符 含义&#xff1a; 修饰类、方法、属性&#xff0c;定义使用的范围 理解&#xff1a;给类、方法、属性定义访问权限的关键字 注意&#xff1a; ​ 1.修饰类只能使用public和默认的访问权限 ​ 2.修饰方法和属性可以使用所有的访问权限 访问修饰符本类本包…

H5小游戏,斗地主

H5小游戏源码、JS开发网页小游戏开源源码大合集。无需运行环境,解压后浏览器直接打开。有需要的,私信本人,发演示地址,可以后再订阅,发源码,含60+小游戏源码。如五子棋、象棋、植物大战僵尸、开心消消乐、扑鱼达人、飞机大战等等 <!DOCTYPE html> <html> <…

BERT学习【BERT的例子以及作用】

一、case 1.case1 多输入单输出。通过输入一个句子&#xff08;sequence&#xff09;&#xff0c;然后输出一个句子的分类&#xff08;这个句子是正向还是负向&#xff09;。将句子输入BERT&#xff0c;然后通过softmax输出分类。 2.case2 多输入多输出。输入一个句子&…

评测本地部署的语音识别模型

1 引言 最近&#xff0c;朋友给我发来了一段音频&#xff0c;想转录成文字&#xff0c;并使用大型润色文本。音频中的普通话带有一定的口音&#xff0c;并且讲解内容较为专业&#xff0c;所以一般的语音识别工具很难达到较高的识别率。 于是试用了两个大模型。Whisper 是目前…

ai脚本创作的软件有哪些?分享3款好用的工具!

随着人工智能技术的飞速发展&#xff0c;AI脚本创作软件已经成为内容创作者们的新宠。这些软件不仅能够帮助我们更高效地生成文章、视频脚本等&#xff0c;还能为我们提供独特的创意视角和无限的灵感。本文将带您深入了解几款备受瞩目的AI脚本创作软件&#xff0c;看看它们如何…

Truenas入门级教程

Truenas入门教程 前言&#xff1a;系统相关配置 采用I3 4160&#xff0c;采用了2块500G的硬盘&#xff0c;内存为8G&#xff0c;两个网卡只用了其中一个&#xff0c;系统安装的是core版本 硬件采用DELL3020MT机箱&#xff0c;自带3个SATA网口&#xff0c;后期网口不够&#…

C++:Stack和Queue的模拟实现

创作不易&#xff0c;感谢三连&#xff01; 一、容器适配器 适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结)&#xff0c;该种模式是将一个类的接口转换成客户希望的另外一个接口。 就如同是电源适配器将不适用的交流电…

Java中的List

List集合的特有方法 方法介绍 方法名描述void add(int index,E element)在此集合中的指定位置插入指定的元素E remove(int index)删除指定索引处的元素&#xff0c;返回被删除的元素E set(int index,E element)修改指定索引处的元素&#xff0c;返回被修改的元素E get(int inde…

正则表达式-分组

1、oracle-正则表达式&#xff1a;将09/29/2008 用正则表达式转换成2008-09-29 select regexp_replace(09/29/2008, ^([0-9]{2})/([0-9]{2})/([0-9]{4})$, \3-\1-\2) replace from dual; 解析&#xff1a;regexp_replace-替换&#xff0c; 第一个参数&#xff1a;需要进行处…

《TCP/IP详解 卷一》第13章 TCP连接管理

目录 13.1 引言 13.2 TCP连接的建立与终止 13.2.1 TCP半关闭 13.2.2 同时打开与关闭 13.2.3 初始序列号 13.2.4 例子 13.2.5 连接建立超时 13.2.6 连接与转换器 13.3 TCP 选项 13.3.1 最大段大小选项 13.3.2 选择确认选项 13.3.3 窗口缩放选项 13.3.4 时间戳选项与…

DCFL: for Oriented Tiny Object Detection

文章目录 AbstractIntroductionContributionRelated Work定向目标检测微小目标检测多尺度学习标签分配上下文信息特征增强MethodOverview动态先验Coarse Prior MatchingFiner Dynamic Posterior MatchingAblation StudyAnalysis不平衡问题的调解可视化速度Conclusionhh 源代码 …

ArcGIS筛选工具:19段SQL示例代码,所有需求一网打尽

一、使用方法 筛选工具(Select_analysis)主要用于从输入要素类或输入要素图层中提取要素&#xff08;通常使用选择或结构化查询语言 (SQL) 表达式&#xff09;&#xff0c;并将其存储于输出要素类中。 以三调图斑为例&#xff0c;图斑中有一个【DLMC】字段&#xff0c;该字段…

1.3 数据库系统的结构

目录 1.3.1 数据库系统模式的概念 1.3.2 数据库系统的三级模式结构 1. 模式 2. 外模式 3.内模式&#xff08;也称存储模式&#xff09; 1.3.3 数据库的二级映像功能与数据独立性 1.外模式&#xff0f;模式映像 2.模式&#xff0f;内模式映像 1.3.4 总结 模式 内模式…

【python词云】根据文本生成简单词云图片(以豆瓣电影250为例,附源码)

效果图 代码 先在内置终端中安装模块 pip install wordcloudpip install jiebaimport wordcloud import jieba# 读入txt文本数据 f open("./douban250.txt", "r", encoding"utf-8") text f.read() f.close()# 切割分词 # jieba.lcut(text)就…

基于cnn卷积神经网络的车辆颜色检测识别-图像去雾-图像去雨(改进yolo目标检测-附代码)

– 引言&#xff1a; 开篇简述图像处理在智能交通监控、自动驾驶等领域的关键作用&#xff0c;并强调随着深度学习尤其是卷积神经网络&#xff08;CNN&#xff09;的发展&#xff0c;在复杂环境下的车辆颜色精确识别、图像恢复&#xff08;如去雾和去雨&#xff09;等难题得以…

Chromium内核浏览器编译记(四)Linux版本CEF编译

转载请注明出处&#xff1a;https://blog.csdn.net/kong_gu_you_lan/article/details/136508294 本文出自 容华谢后的博客 0.写在前面 本篇文章是用来记录编译Linux版本CEF的步骤和踩过的坑&#xff0c;以防止后续再用到的时候忘记&#xff0c;同时也希望能够帮助到遇到同样问…

【【C语言简单小题学习-1】】

实现九九乘法表 // 输出乘法口诀表 int main() {int i 0;int j 0;for (i 1; i < 9; i){for (j 1; j < i;j)printf("%d*%d%d ", i , j, i*j);printf("\n"); }return 0; }猜数字的游戏设计 #define _CRT_SECURE_NO_WARNINGS 1 #include<stdi…

如何将github上代码克隆到本地

1、需求 想把github上一篇论文的代码下载到本地。 2、前提 本地电脑已经安装了Git。&#xff08;没有安装需要到官网下载安装&#xff09; 3、解决方法 大功告成

第四篇【传奇开心果系列】Python的自动化办公库技术点案例示例:深度解读Pandas生物信息学领域应用

传奇开心果博文系列 系列博文目录Python的自动化办公库技术点案例示例系列 博文目录前言一、Pandas生物学数据操作应用介绍二、数据加载与清洗示例代码三、数据分析与统计示例代码四、数据可视化示例代码五、基因组数据分析示例代码六、蛋白质数据分析示例代码七、生物医学图像…

【方法】如何打开7Z分卷压缩文件?

什么是7Z分卷压缩文件&#xff1f;就是在压缩文件时&#xff0c;将文件压缩成若干个大小一样、以“文件名.7z.序号”格式命名的7Z压缩包&#xff0c;可以方便存储和传输&#xff0c;如下图所示。 一、7Z分卷压缩文件如何打开&#xff1f; 我们只需要按照普通压缩包的打开方式&…