Xposed java 反射
getDeclaredField
是可以获取一个类的所有字段,方法仅对类本身的字段有效果,对于继承的父类的字段无效
getField
只能获取类的public 字段,只能获取类及其父类的公共字段
setAccessible
通过反射获取私有变量的值,在访问时会忽略访问修饰符的检查
Field
是一个类,位于java.lang.reflect
包下。在Java反射中Field
类描述的是类的属性信息,功能包括:
- 获取当前对象的成员变量的类型
- 对成员变量重新设值
反射获取类方法调用和修改
1 | package com.example.testxp; |
Xposed 获取所有方法和字段
for 循环的三种写法
第一种写法 传统的方法,遍历数组
1 | String[] arr = { "amy", "heinrich", "cindy", "git" }; |
第二种写法 而对于遍历Collection对象,这个循环则通常是采用这样的形式
1 | String[] arr = { "amy", "heinrich", "cindy", "git" }; |
第三种方法也很常见
不严格的说,Java的第三种for循环基本是这样的格式:
for (循环变量类型 循环变量名称 : 要被遍历的对象) 循环体
借助这种语法,遍历一个数组的操作就可以采取这样的写法:
1 | String[] arr = { "amy", "heinrich", "cindy", "git" }; |
遍历所有类、字段、内部类:
类和字段:
getDeclaredMethod()
获取的是类自身声明的所有方法,包含public、protected和private方法,就是获取当前类下面的所有方法,通过toString()
把方法信息打印出来,不包括方法体。
getDeclaredFields()
:获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的声明字段。通过这两种方法就可以遍历所有的方法和字段。
内部类:
getDeclaredClasses()
:得到该类所有的内部类,除去父类的
getName()
:得到该内部类的名字在通过
getDeclaredMethod()
和getDeclaredFields()
获取内部中所有方法和字段
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 package com.example.testxp;
import android.util.Base64;
import android.util.Log;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.MessageDigest;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Map;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodReplacement;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
public class Hello implements IXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
Log.d("KeyboArd", "hook...");
if(lpparam.packageName.equals("com.xiaojianbang.xposeddemo")){
Class clazz = XposedHelpers.findClass("com.xiaojianbang.xposeddemo.Demo", lpparam.classLoader);
Log.d("KeyboArd",clazz.getName());
// XposedHelpers.setStaticObjectField(clazz,"Tag","KeyboArd");
// XposedHelpers.findAndHookMethod(
// XposedHelpers.findClass("com.xiaojianbang.xposeddemo.Demo$InnerClass",lpparam.classLoader),
// "innerFunc",String.class,new XC_MethodHook(){
// public void beforeHookedMethod(MethodHookParam param) throws Throwable{
// Field reffield = clazz.getDeclaredField("reflect");
// Object obj = clazz.newInstance();
// reffield.setAccessible(true);
// String str = (String) reffield.get(obj);
// Log.d("KeyboArd","这是反射获取的字段"+str);
// reffield.set(obj,"fanshedafa");
// String str2 = (String)reffield.get(obj);
// Log.d("KeyboArd","这是反射设置的字段"+str2);
// Method refmethod = clazz.getDeclaredMethod("reflect");
// refmethod.setAccessible(true);
// refmethod.invoke(obj);
// refmethod.invoke(obj);
// refmethod.invoke(obj);
// }
// });
for (Method method : clazz.getDeclaredMethods()) {
Log.d("KeyboArd", method.toString());
}
Field[] fd = clazz.getDeclaredFields();
for (Field field : fd) {
Log.d("KeyboArd", field.toString());
}
Log.d("KeyboArd", "====================================");
Class[] cls = clazz.getDeclaredClasses();
for (int i = 0; i < fd.length; i++) {
Log.d("KeyboArd", cls[i].getName());
for (Method method2 : cls[i].getDeclaredMethods()) {
Log.d("KeyboArd", method2.toString());
}
for (Field field2 : cls[i].getDeclaredFields()) {
Log.d("KeyboArd", field2.toString());
}
}
}
这里有个坑,我设置的 Log.d
的 tag
参数是 KeyboArd
,但是测试的demo
的 默认tag
是 xiaojianbang
,所以一开始我出现了测试时候,怎么都输出不了的问题,后来把Logcat 监测改为 xiaojianbang
时候发现可以正常输出,才找到问题所在。
当Logcat 监测为 KeyboArd
时,点击按钮没有输出没有反应
当监测改为xiaojianbang
时,正常输出。
所以要把初始TAG
的字符串也给hook 修改了。
1 | package com.example.testxp; |
可以了。
得了,今天又水了一篇。