avatar

目录
Xposed学习笔记(2)

Xposed java 反射

getDeclaredField是可以获取一个类的所有字段,方法仅对类本身的字段有效果,对于继承的父类的字段无效

getField只能获取类的public 字段,只能获取类及其父类的公共字段

setAccessible通过反射获取私有变量的值,在访问时会忽略访问修饰符的检查

Field是一个类,位于java.lang.reflect包下。在Java反射中Field类描述的是类的属性信息,功能包括:

  • 获取当前对象的成员变量的类型
  • 对成员变量重新设值

反射获取类方法调用和修改

java
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
package com.example.testxp;


import android.util.Log;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
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")){
final Class clazz = XposedHelpers.findClass("com.xiaojianbang.xposeddemo.Demo",lpparam.classLoader);
Log.d("KeyboArd",clazz.getName());
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("ref1");
refmethod.setAccessible(true);
refmethod.invoke(obj);
refmethod.invoke(obj);
refmethod.invoke(obj);

}
});
}
}



Xposed 获取所有方法和字段

for 循环的三种写法

第一种写法 传统的方法,遍历数组

java
1
2
3
4
5
6
7
8
9
10
String[] arr = { "amy", "heinrich", "cindy", "git" };

for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}

amy
heinrich
cindy
git

第二种写法 而对于遍历Collection对象,这个循环则通常是采用这样的形式

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
String[] arr = { "amy", "heinrich", "cindy", "git" };

List<String> list = Arrays.asList(arr);

for (Iterator<String> iterator = list.iterator();iterator.hasNext();)
{
System.out.println(iterator.next());
}


amy
heinrich
cindy
git

第三种方法也很常见

不严格的说,Java的第三种for循环基本是这样的格式:

for (循环变量类型 循环变量名称 : 要被遍历的对象) 循环体

借助这种语法,遍历一个数组的操作就可以采取这样的写法:

java
1
2
3
4
5
6
7
8
9
10
String[] arr = { "amy", "heinrich", "cindy", "git" };

for (String a : arr) {
System.out.println(a);
}

amy
heinrich
cindy
git

遍历所有类、字段、内部类:

类和字段:

getDeclaredMethod()获取的是类自身声明的所有方法,包含public、protected和private方法,就是获取当前类下面的所有方法,通过toString()把方法信息打印出来,不包括方法体。

getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的声明字段。

通过这两种方法就可以遍历所有的方法和字段。

内部类:

getDeclaredClasses():得到该类所有的内部类,除去父类的

getName():得到该内部类的名字

在通过getDeclaredMethod()getDeclaredFields()获取内部中所有方法和字段

java
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.dtag参数是 KeyboArd,但是测试的demo 的 默认tagxiaojianbang,所以一开始我出现了测试时候,怎么都输出不了的问题,后来把Logcat 监测改为 xiaojianbang时候发现可以正常输出,才找到问题所在。

当Logcat 监测为 KeyboArd时,点击按钮没有输出没有反应

当监测改为xiaojianbang时,正常输出。

所以要把初始TAG的字符串也给hook 修改了。

java
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());
}
}
}

可以了。


得了,今天又水了一篇。

文章作者: KeyboArd
文章链接: https://www.wrpzkb.cn/xposed2/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 KeyboArd's Blog
打赏
  • 微信
    微信
  • 支付寶
    支付寶

评论