首页
社区
课程
招聘
[原创]Xposed学习记录
发表于: 2019-6-22 23:29 9751

[原创]Xposed学习记录

2019-6-22 23:29
9751

纸上得来终觉浅,绝知此事要躬行。

看了很多xposed的教程,自以为掌握了个大概,直到今天整理,练习时才发现自己不过是眼高手低,有太多的东西需要学习了。路漫漫,还需脚踏实地!
没有找到合适样本,自己写了个简单的类练手。
abstract class person{
    public int age=0;
    public void eat(String food){};
}

public class HookGoal {
    private static String TAG="HookGoal:";
    private int hookGoalNumber;
    public HookGoal(int number){
        hookGoalNumber=number;
        Log.i(TAG,"HookGoal hookGoalNumber:"+hookGoalNumber);
    }
    public void func0(){
        Log.i(TAG,"welcome");
    }
    private void func1(){
        new person(){
            @Override
            public void eat(String food) {
                Log.i(TAG,"eat "+food);
            }
        }.eat("apple");
    }
    private static void func2(String s){
        Log.i(TAG,"func2 "+s);
    }
    private void func3(DiyClass[] arry){
        for(int i=0;i<arry.length;i++)
            Log.i(TAG,"DiyClass["+i+"].getData:"+arry[i].getData());
    }
    private class InnerClass{
        private int innerNumber;
        public InnerClass(String s){
            innerNumber=0;
            Log.i(TAG,"InnerClass 构造函数 "+s);
            Log.i(TAG,"InnerClass innerNumber:"+innerNumber);
        }
        private void innerFunc(String s){
            Log.i(TAG,"InnerClass innerFunc "+s);
        }
    }
    public void show(){
        func1();
        func2("私有静态方法");
        DiyClass[] arry={new DiyClass(0),new DiyClass(0),new DiyClass(0)};
        func3(arry);
        InnerClass inner=new InnerClass("私有内部类");
        inner.innerFunc("内部类方法调用");
    }

}



public class DiyClass{
    private int data;
    public DiyClass(int data){
        this.data=data;
    }
    public int getData() {
        return data;
    }
    public void setData(int data) {
        this.data = data;
    }
}
要干下面几件事:
  • hook HookGoal类的构造函数,修改静态属性TAG
  • hook 私有成员方法func1内的匿名内部类的eat()方法 ,修改匿名内部类的age值
  • hook 私有静态方法func2 ,调用成员方法func0()、调用DiyClass类的成员方法getData()
  • hook 私有成员方法func3 参数为自定义类型数组,修改参数、 调用成员方法func0() 
  • hook 内部类InnerClass的构造函数(经论坛大哥指点已经可以),hook内部类innerFunc方法
public class HookMain implements IXposedHookLoadPackage {
    Context context;
    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
        XposedBridge.log("HookMain begain");
        if (!lpparam.packageName.equals("com.example.goal")) {
            Log.i("失败", "未找到包");
            XposedBridge.log("未找到包" );
            return;
        }
        Log.i("begin","hook is begaining");
        //hook context  后面可使用Toast
        XposedHelpers.findAndHookMethod(ContextThemeWrapper.class, "attachBaseContext",Context.class, new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                context=(Context) param.args[0];
            }
        });

        final Class<?> clazz=findClass("com.example.goal.HookGoal",lpparam.classLoader);
        //hook 有参构造函数
        XposedHelpers.findAndHookConstructor(clazz,int.class,new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                //修改构造函数参数
                param.args[0]=666;

                //设置 TAG为hooking
                setStaticObjectField(clazz,"TAG","hooking");
            }
        });
        Class nminner=findClass("com.example.goal.HookGoal$1",clazz.getClassLoader());
        //hook 匿名内部类的eat()方法
        findAndHookMethod(nminner, "eat",String.class, new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                param.args[0]="is hooking";
                //修改匿名内部类的age属性
                Log.i("nminner","修改前age值:"+getIntField(param.thisObject,"age"));
                setIntField(param.thisObject,"age",666);
                Log.i("nminner","修改后age值:"+getIntField(param.thisObject,"age"));
            }
        });

        final Class diy=findClass("com.example.goal.DiyClass",lpparam.classLoader);
        final Constructor init=diy.getConstructor(int.class);

        findAndHookMethod(clazz, "func2",String.class, new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                //hook 静态方法参数
                param.args[0]="is hooking";

                //调用func0方法
                XposedHelpers.callMethod(clazz.getConstructor(int.class).newInstance(666),"func0");
                Log.i("hooking","way1 (静态方法中)创建新对象调用func0");

                //调用外部 DiyClass的getData()
                int data=(int)callMethod(init.newInstance(666),"getData");
                Log.i("hooking","调用DiyClass中getData() 返回值:"+data);
            }
        });
        //hook 自定义类型数组参数
        Class diyClassArray= Array.newInstance(diy,3).getClass();
        findAndHookMethod(clazz, "func3", diyClassArray, new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                //调用func0方法
                XposedHelpers.callMethod(param.thisObject,"func0");
                Log.i("hooking","way2 (成员方法中)当前对象调用func0");

                //自定义类型数组
                Object a=Array.newInstance(diy,3);
                for(int i=0;i<3;i++)
                    Array.set(a,i,init.newInstance(666));
                param.args[0]=diyClassArray.cast(a);
                Log.i("func3",param.args[0].toString());
                Log.i("hooking","func3修改参数");
            }
        });
        Class inner=findClass("com.example.goal.HookGoal$InnerClass",clazz.getClassLoader());
        findAndHookConstructor(inner,clazz, String.class, new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                //修改内部类构造函数中的参数
                param.args[1]="is hooking";
                Log.i("inner Constructor",""+param.args[1]);
            }

            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                //在内部类构造函数中修改innerNumber值
                Log.i("inner Constructor","修改前的innerNumber:"+getIntField(param.thisObject,"innerNumber"));
               // Log.i("inner Constructor",""+param.thisObject);
                setIntField(param.thisObject,"innerNumber",6);
                Log.i("inner Constructor","修改后的innerNumber:"+getIntField(param.thisObject,"innerNumber"));
            }
        });
        findAndHookMethod(inner, "innerFunc", String.class, new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                param.args[0]="is hooking";
                Log.i("innerFunc","修改前的innerNumber:"+getIntField(param.thisObject,"innerNumber"));
                setIntField(param.thisObject,"innerNumber",666);
                Log.i("innerFunc","修改后的innerNumber:"+getIntField(param.thisObject,"innerNumber"));
                Log.i("innerFunc",""+param.args[0]);
            }
        });
    }
}

hook前Log
com.example.goal I/HookGoal:: HookGoal hookGoalNumber:0
com.example.goal I/HookGoal:: eat apple
com.example.goal I/HookGoal:: func2 私有静态方法
com.example.goal I/HookGoal:: DiyClass[0].getData:0
com.example.goal I/HookGoal:: DiyClass[1].getData:0
com.example.goal I/HookGoal:: DiyClass[2].getData:0
com.example.goal I/HookGoal:: InnerClass 构造函数 私有内部类
com.example.goal I/HookGoal:: InnerClass innerNumber:0
com.example.goal I/HookGoal:: InnerClass innerFunc 内部类方法调用

hook后Log
com.example.goal I/hooking: HookGoal hookGoalNumber:666
com.example.goal I/hooking: eat is hooking
com.example.goal I/hooking: HookGoal hookGoalNumber:666
com.example.goal I/hooking: welcome
com.example.goal I/hooking: 调用DiyClass中getData() 返回值:666
com.example.goal I/hooking: func2 is hooking
com.example.goal I/func3: [Lcom.example.goal.DiyClass;@4a89752c
com.example.goal I/hooking: func3修改参数
com.example.goal I/hooking: DiyClass[0].getData:666
com.example.goal I/hooking: DiyClass[1].getData:666
com.example.goal I/hooking: DiyClass[2].getData:666
com.example.goal I/inner Constructor: is hooking
com.example.goal I/hooking: InnerClass 构造函数 is hooking
com.example.goal I/hooking: InnerClass innerNumber:0
com.example.goal I/inner Constructor: 修改前的innerNumber:0
com.example.goal I/inner Constructor: 修改后的innerNumber:6
com.example.goal I/innerFunc: 修改前的innerNumber:6
com.example.goal I/innerFunc: 修改后的innerNumber:666
com.example.goal I/innerFunc: is hooking
com.example.goal I/hooking: InnerClass innerFunc is hooking


错误之处,还请不吝赐教,十分感谢!
同时也希望有疑惑的同学留下你的问题,大家多多交流。

实践是检验真理的唯一标准,今后还要勤加练习,多多实战。
计划:
  • 掌握Java层xposed hook及原理
  • 掌握native层frida hook及原理
  • 自己实现hook框架

学如逆水行舟,不进则退。与君共勉!






[课程]Linux pwn 探索篇!

最后于 2019-6-25 20:44 被堂前燕编辑 ,原因: 修正一些错误
收藏
免费 4
支持
分享
最新回复 (14)
雪    币: 761
活跃值: (618)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
学习了。。
2019-6-23 10:03
0
雪    币: 1526
活跃值: (2077)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
学习了
2019-6-24 10:51
0
雪    币: 69
活跃值: (3208)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
06-24 13:20:37.666: I/hooking(4158): DiyClass[2].getData:666
06-24 13:20:37.666: I/inner(4158): com.example.goal.HookGoal@33771ca7
06-24 13:20:37.666: I/hooking(4158): InnerClass 构造函数 is hooking
06-24 13:20:37.666: I/hooking(4158): InnerClass innerNumber:0
06-24 13:20:37.666: I/innerFunc(4158): is hooking
06-24 13:20:37.666: I/hooking(4158): InnerClass innerFunc is hooking

提示下 :.method public constructor <init>(HookGoal, String)V
 findAndHookConstructor(inner, clazz, String.class, new XC_MethodHook()
2019-6-24 13:23
0
雪    币: 10477
活跃值: (4167)
能力值: ( LV12,RANK:329 )
在线值:
发帖
回帖
粉丝
5
Breathleas 06-24 13:20:37.666: I/hooking(4158): DiyClass[2].getData:666 06-24 13:20:37.666: I/inner(4158): com ...
感谢提示,我怎么没想到反编译看下呢,十分感谢
2019-6-24 14:08
0
雪    币: 2375
活跃值: (433)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
你熟悉arm指令么
2019-6-25 08:39
0
雪    币: 10477
活跃值: (4167)
能力值: ( LV12,RANK:329 )
在线值:
发帖
回帖
粉丝
7
petersonhz 你熟悉arm指令么[em_16]
懂个大概
2019-6-25 09:07
0
雪    币: 218
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
最近也在学习xposed 老哥,可以加个qq交流一波吗
2019-7-10 11:32
0
雪    币: 574
活跃值: (364)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
学习了
2019-7-11 10:07
0
雪    币: 447
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
11
mark,学习一下
2019-7-11 20:15
0
雪    币: 2901
活跃值: (1597)
能力值: ( LV3,RANK:36 )
在线值:
发帖
回帖
粉丝
12
吾爱上我写过一篇帖子 Xposed常用方法使用详解(配合微信6.6.7源码) ,有兴趣可以看看
主要是Xposed中findAndHookMethod、findClass、findField、callMethod等最常用方法的使用
2019-7-12 09:29
0
雪    币: 634
活跃值: (1503)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
13
不妨试试看Xposed AndroidStudio模板
一些我常用的代码都放到里面了
https://github.com/monkeylord/XposedTemplateForAS
最后于 2019-7-12 10:27 被Monkeylord编辑 ,原因:
2019-7-12 10:26
0
雪    币: 265
活跃值: (21)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
感谢分享,mark学习了
2019-7-22 10:33
0
雪    币: 103
活跃值: (136)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
感谢分享,mark学习了
2019-9-17 16:27
0
游客
登录 | 注册 方可回帖
返回
//