被hook的示例app
先写个示例app供后面hook用,示例代码尽量使用各种参数类型
void demo(){
int i=20;
byte[] bytes={'a','b','c'};
String s="kkk";
List<String> list=new ArrayList<>();
list.add("L");
list.add("i");
list.add("s");
list.add("t");
Person person=new Person();
person.age=18;
person.name="vvv";
Person person2 =hookTest(i,bytes,s,list,person);
Log.d(TAG, "demo中返回值的person.age,修改返回值后: "+person2.age);
Log.d(TAG, "demo中返回值的person.name,修改返回值后: "+person2.name);
}
//被hook的方法,参数包含int、byte[]、String、list、类
Person hookTest(int i, byte[] b, String str, List list,Person person){
Log.d(TAG, "demo中参数的person.age,修改参数前: "+person.age);
Log.d(TAG, "demo中参数的person.name,修改参数前: "+person.name);
person.age=i;
person.name=str;
Log.d(TAG, "demo中参数的person.age,修改参数后: "+person.age);
Log.d(TAG, "demo中参数的person.name,修改参数后: "+person.name);
return person;
}
public class Person {
int age;
String name;
}
hook代码
这里hook了上面示例的代码的hookTest方法,打印了int、byte[]、String、list、类的成员变量等参数和返回值,并修改了参数和返回值;
然后用callMethod主动调用hookTest方法;
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
final String TAG="vicHook";
//class可以通过loadClass获取或者使用XposedHelpers.findClass获取等两种方式
Class<?> clazz = lpparam.classLoader.loadClass("com.example.demo.MainActivity");
Class<?> clazz1=XposedHelpers.findClass("com.example.demo.Person",lpparam.classLoader);
if (clazz==null){
return;
}
//hook 方法hookTest,主要注意参数的写法,最后一个参数是Person类
XposedHelpers.findAndHookMethod(clazz, "hookTest",
int.class,
byte[].class,
String.class,
List.class,
clazz1, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
//打印各种类型的参数
Log.d(TAG, "打印int参数: "+param.args[0]);
Log.d(TAG, "打印byte[]参数: "+new String((byte[]) param.args[1],"UTF-8"));
Log.d(TAG, "打印String参数: "+param.args[2]);
Log.d(TAG, "打印list参数: "+ param.args[3]);
//打印person类的成员变量
int age=getIntField(param.args[4],"age");
Log.d(TAG, "打印参数perso类age变量: "+age);
String name = (String) getObjectField(param.args[4],"name");
Log.d(TAG, "打印参数perso类age变量: "+name);
//修改参数
param.args[0]=100;
param.args[2]="hhh";
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
//打印返回值
int age2=getIntField(param.getResult(),"age");
Log.d(TAG, "打印返回值perso类age变量: "+age2);
String name2 = (String) getObjectField(param.getResult(),"name");
Log.d(TAG, "打印返回值perso类age变量: "+name2);
//修改返回值
Object person=param.getResult();
setIntField(person,"age",30);
setObjectField(person,"name","mmm");
param.setResult(person);
}
});
//构造参数,用callMethod主动调用hookTest方法;关键点就是通过newInstance获取到类的对象
int p1=50;
byte[] p2={'z','x','c'};
String p3="xxx";
List<String> p4=new ArrayList<>();
p4.add("list");
Object p5=clazz1.newInstance();
XposedHelpers.callMethod(clazz.newInstance(),"hookTest",p1,p2,p3,p4,p5);
}
运行结果
从打印结果的可以看到,初始age=18,name=vvv,hook修改参数之后age变成100,name变成hhh,然后hook又修改返回值之后age变成30,name变成mmm;
主动调用的log,主动调用比原始方法先执行,findAndHookMethod也会hook到主动调用的方法打印参数;