前言
Xposed常年不更新,Lsposed支持Android更高版本并且继承了Xposed的所有API,于是我决定学习Lsposed。
先实现一个student类
package com.example.hookdemo01;
import android.util.Log;
public class student {
String name=null;
String id=null;
int age=0;
public String getNickname() {
return nickname;
}
public static String getTeachername() {
return teachername;
}
private String nickname=null;
public static String teachername=null;
public student(){
name="default";
id="default";
age=12;
}
public class person{
public String name;
public String sex;
public String getpersonname(String arg0){
return arg0;
}
}
public student(String name){
this.name=name;
id="default";
age=12;
}
public student(String name,String id){
this.name=name;
this.id=id;
age=12;
}
public student(String name,String id,int age){
this.name=name;
this.id=id;
this.age=age;
}
public student(String name,int age){
this.name=name;
this.age=age;
}
public student(String name,String id,int age,String nickname,String teacher){
this.name=name;
this.id=id;
this.age=age;
teachername=teacher;
this.nickname=nickname;
}
public static String publicstaticfunc(String arg1,int arg2){
String result=privatestaticfunc("privatestaticfunc",200);
Log.i("Xposed","Publicstaticfunc is called!"+arg1+"---"+arg2);
return arg1+"---"+arg2+"---"+result;
}
private static String privatestaticfunc(String arg1,int arg2){
Log.i("Xposed","privatestaticfunc is called!"+arg1+"---"+arg2);
return arg1+"---"+arg2;
}
public String publicfunc(String arg1,int arg2){
String result=privatefunc("privatefunc",500);
Log.i("Xposded","publicfunc is called");
person tmp=new person();
String tmpresult=tmp.getpersonname("person");
return arg1+"---"+arg2+"---"+result+"---"+tmpresult;
}
private String privatefunc(String arg1,int arg2){
Log.i("Xposded","privatefunc is called");
return arg1+"---"+arg2;
}
}
package com.example.hookdemo01;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
public void printstudent(student stu){
Log.i("Xposed-Fup1p1",stu.name+"---"+stu.id+"---"+stu.age);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
student astudent=new student();
student bstudent=new student("xiaoming");
student dstudent=new student("xiaoming",20);
student cstudent=new student("xiaohong","2010",20);
student estudent=new student("xiaohong","2010",20,"Fup1p1","kanxue");
printstudent(astudent);
printstudent(bstudent);
printstudent(cstudent);
printstudent(dstudent);
printstudent(estudent);
}
}
hook构造函数
package com.example.xposed01;
import android.util.Log;
import java.lang.reflect.Field;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
public class hookconstructor implements IXposedHookLoadPackage {//IXposedHookLoadPackage 接口,实现hook逻辑的类必须实现该接口,
//APP被加载的时候会调用该接口中的 handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) 方法,所以我们需要重写该函数,并在其中实现我们的hook逻辑
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {//XC_LoadPackage.LoadPackageParam,该类下包含与正在加载的应用程序的有关信息。
Log.i("Xposed->",lpparam.packageName);
XposedBridge.log("Fup1p1 Loaded app:->" + lpparam.packageName);
if(lpparam.packageName.equals("com.example.hookdemo01")){
ClassLoader classLoader=lpparam.classLoader;
Class studentclass=classLoader.loadClass("com.example.hookdemo01.student");
XposedHelpers.findAndHookConstructor(studentclass, new XC_MethodHook() {//传递了一个新的 XC_MethodHook 匿名内部类,并覆盖了 beforeHookedMethod 和 afterHookedMethod 方法,以便在构造函数执行前后执行我们的自定义代码。
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
XposedBridge.log("Fup1p1 com.example.hookdemo01.student() is called!!BeforeHookmethod");
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
XposedBridge.log("com.example.hookdemo01.student() is called!!afterHookmethod");
}
});
XposedHelpers.findAndHookConstructor(studentclass, String.class,new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
java.lang.Object[] argsobjarrray= param.args;
String name=(String) argsobjarrray[0];
XposedBridge.log("com.example.hookdemo01.student(String) is called!!BeforeHookmethod--"+name);
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
XposedBridge.log("com.example.hookdemo01.student(String) is called!!afterHookmethod--");
}
});
XposedHelpers.findAndHookConstructor(studentclass, String.class,String.class,new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
java.lang.Object[] argsobjarrray= param.args;
String name=(String) argsobjarrray[0];
String id=(String) argsobjarrray[1];
XposedBridge.log("com.example.hookdemo01.student(String,String) is called!!BeforeHookmethod--"+name+"---"+id);
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
XposedBridge.log("com.example.hookdemo01.student(String,String) is called!!afterHookmethod--");
}
});
XposedHelpers.findAndHookConstructor(studentclass, String.class,String.class,int.class,String.class,String.class,new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
java.lang.Object[] argsobjarrray= param.args;
String name=(String) argsobjarrray[0];
String id=(String) argsobjarrray[1];
int age=(int) argsobjarrray[2];
argsobjarrray[1]="2050";
argsobjarrray[2]=100;
String nickname= (String) argsobjarrray[3];
String teacher= (String) argsobjarrray[4];
XposedBridge.log("XXX com.example.hookdemo01.student(String,String,int) is called!!BeforeHookmethod--"+name+"---"+id+"---"+age+"---"+nickname+"---"+teacher);
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
XposedBridge.log("com.example.hookdemo01.student(String,String,int) is called!!afterHookmethod--");
}
});
}
}
}
修改属性
修改静态属性
ClassLoader pathclassloader=lpparam.classLoader;
Class stuclass=pathclassloader.loadClass("com.example.hookdemo01.student");
XposedBridge.log("StudentClass->"+stuclass);
不使用Xposed API
Field teacherFields=stuclass.getDeclaredField("teachername");
teacherFields.set(null,"teacher666");
String teachername= (String) teacherFields.get(null);
XposedBridge.log("teacherFields1->"+teachername);
使用Xposed API
XposedHelpers.setStaticObjectField(stuclass,"teachername","teacher888");
String teachername2= (String) XposedHelpers.getStaticObjectField(stuclass,"teachername");
XposedBridge.log("XposedHelpers.getStaticObjectField->"+teachername2);
修改非静态private属性
不使用Xposed API
ClassLoader pathclassloader=lpparam.classLoader;
Class stuclass=pathclassloader.loadClass("com.example.hookdemo01.student");
XposedHelpers.findAndHookConstructor(studentclass, String.class,String.class,int.class,String.class,String.class,new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
java.lang.Object[] argsobjarrray= param.args;
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Object thisobj=param.thisObject;
Field nicknamefield1=stuclass.getDeclaredField("nickname");
XposedBridge.log("nickname->"+nicknamefield1);
nicknamefield1.setAccessible(true);
nicknamefield1.set(thisobj,"Fup1p1-1");
}
});
使用Xposed API
ClassLoader pathclassloader=lpparam.classLoader;
Class stuclass=pathclassloader.loadClass("com.example.hookdemo01.student");
XposedHelpers.findAndHookConstructor(studentclass, String.class,String.class,int.class,String.class,String.class,new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
java.lang.Object[] argsobjarrray= param.args;
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Object thisobj=param.thisObject;
XposedHelpers.setObjectField(thisobj,"nickname","Fup1p1-2");
Object returnobj=param.getResult();
XposedBridge.log(thisobj+"---"+returnobj);
}
});
Hook内部类
要注意$符号
Class personclass=XposedHelpers.findClass("com.example.hookdemo01.student$person",lpparam.classLoader);
XposedHelpers.findAndHookMethod(personclass, "getpersonname", String.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
XposedBridge.log("beforeHookedMethod->getpersonname->"+param.args[0]);
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
XposedBridge.log("afterHookedMethod->getpersonname->"+param.getResult());
}
});
主动调用类函数
对于静态函数,直接调用。
对于非静态函数,需先得到类的实例,然后才能完成调用。
静态函数
通过反射获得Method,由于是静态函数,所以Object处设置为Null
Publicstaticfunc
不使用Xposed API
Class stuclass=classloader.loadClass("com.example.hookdemo01.student");
Method publicstaticfunc_method=stuclass.getDeclaredMethod("publicstaticfunc",String.class,int.class);
publicstaticfunc_method.invoke(null,"InvokeedbyXpossed",100);
使用Xposed API
java.lang.Class<?>[] parameterTYpes={String.class,int.class};
XposedHelpers.callStaticMethod(stuclass,"publicstaticfunc",parameterTYpes,"invokebyXpose11!!!",114514);
可以省略参数列表
XposedHelpers.callStaticMethod(stuclass,"publicstaticfunc","invokebyXpose22!!!",114514);
Privatestaticfunc
不使用Xposed API
其他相同,只需多加一行取消权限检查即可。
privatestaticfunc_method.setAccessible(true);
使用Xposed API
与publicstatic相同。如果查看xposed源码,就知道这个API已经默认取消权限检查了!
publicfunc
不使用Xposed API
Method public_method=stuclass.getDeclaredMethod("publicfunc",String.class,int.class);
Constructor stucons=stuclass.getDeclaredConstructor(String.class,int.class);
Object stuobj=stucons.newInstance("InstancebyXposed",300);
使用Xposed API
Object stuobjbyxposed1 =XposedHelpers.newInstance(stuclass,"stuobjbyxposed_newinstance1",114114);
String result1= (String) XposedHelpers.callMethod(stuobjbyxposed1,"publicfunc",parameterTYpes,"invokebyXpose333!!!",1145141919);
XposedBridge.log("invokebyXposed->"+result1);
privatefunc
使用Xposed API
Object stuobjbyxposed1 =XposedHelpers.newInstance(stuclass,"stuobjbyxposed_newinstance1",114114);
String result1= (String) XposedHelpers.callMethod(stuobjbyxposed1,"privatefunc",parameterTYpes,"invokebyXpose333!!!",1145141919);
XposedBridge.log("invokebyXposed->"+result1);
评论区