首页
社区
课程
招聘
1
[原创]Xposed 快速入门
发表于: 2025-4-14 18:00 1257

[原创]Xposed 快速入门

2025-4-14 18:00
1257

基本介绍:

Xposed是一款可以在不修改APK的情况下影响程序运行的框架,基于它可以制作出许多功能强大的模块,且在功能不冲突的情况下同时运作。在这个框架下,我们可以编写并加载自己编写的插件APP,实现对目标apk的注入拦截等。


关于开发环境的配置我就不多说了,别的大佬讲的都很详细,而且我是直接用手机开发测试的,没有配置环境

关于Xposed类定义:

首先必须继承IXposedHookLoadPackage接口,并重写handleLoadPackage回调方法,像这样:


public class HookInit implements IXposedHookLoadPackage {

 @Override


 public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {


  }

}

其中回调方法的LoadPackageParam lpparam参数是Xposed提供的,他可以获取当前应用的信息,他也提供了很多属性,如classLoader(当前类加载器),packageName(包名称)等


Xposed提供了很多封装好的Hook函数,但是本质使用的还是Java反射,下面我将写一个安卓demo作为案例来教大家怎么使用xposed提供的函数


新建MainActivity.java文件

package com.demo;


import android.app.Activity;

import android.os.Bundle;

import android.widget.Button;

import android.widget.EditText;

import android.view.View;

import android.widget.Toast;


public class MainActivity extends Activity {

    Button button1;

    Button button2;

    Button button3;

    EditText edit;


    static String Name="admin";

    static int pass=123456;


    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);        

        setContentView(R.layout.activity_main);


        button1 = findViewById(R.id.puton);

        button2 = findViewById(R.id.statics);

        button3 = findViewById(R.id.cons);

        edit = findViewById(R.id.activitymainEditText1);

        //方法参数测试

        button1.setOnClickListener(

            new View.OnClickListener() {


                @Override

                public void onClick(View view) {

                    String pass=edit.getText().toString();           

                    //传入编辑框内容

                    check(pass);


                }

            });

        //静态变量测试

        button2.setOnClickListener(new View.OnClickListener() {


                @Override

                public void onClick(View view) {

                    Toast.makeText(getApplication(), "name:" + Name + "\n" + "pass:" + pass, Toast.LENGTH_SHORT).show();

                }

            });

        //构造方法测试

        button3.setOnClickListener(new View.OnClickListener() {


                @Override

                public void onClick(View view) {

                    demo2test demo =new demo2test("Anna", 1);

                    Toast.makeText(getApplication(), "name:" + demo.getName() + "\n" + "id:" + demo.getId(), Toast.LENGTH_SHORT).show();

                }

            });

    }


    public void check(String pass) {

        // 判断参数内容是否和密码相同

        if (pass.equals("123456")) {

            Toast.makeText(getApplication(), "密码正确", Toast.LENGTH_SHORT).show();

        } else {

            Toast.makeText(getApplication(), "密码错误", Toast.LENGTH_SHORT).show();

        }}


    public void test() {

        Toast.makeText(getApplication(), "我被调用了?", Toast.LENGTH_SHORT).show();

    }

}


新建demo2test.Java文件

package com.demo;


/**

 * @Author Moiy

 * @Date 2025/04/09 09:20

 */

public class demo2test {

    String name;

    int id;


    public demo2test(String name, int id) {

        this.name = name;

        this.id = id;

    }

    

    

    public void setName(String name) {

        this.name = name;

    }


    public String getName() {

        return name;

    }


    public void setId(int id) {

        this.id = id;

    }


    public int getId() {

        return id;

    }}



软件界面布局:

这个安卓app定义了三个按钮

  • 方法按钮(检测编辑框内容是否正确)

  • 静态按钮(输出静态变量内容)

  • 构造按钮(输出构造函数传入的变量)



Hook方法:


关于Xposed hook,一般使用的都是XposedHelpers类下的函数,比如Hook方法使用的就是findAndHookMethod方法,这个函数有两个重载分别是


findAndHookMethod(String className, ClassLoader classLoader, String methodName, Object... parameterTypesAndCallback) {}



findAndHookMethod(Class<?> clazz, String methodName, Object... parameterTypesAndCallback) {}




具体使用

XposedHelpers.findAndHookMethod(


    "com.demo.MainActivity",


    lpparam.classLoader,


    "check",


   String.class,


   new XC_MethodHook(){

     protected void beforeHookedMethod(MethodHookParam param){

       //设置方法参数为123456        


      param.args[0]="123456";


     }


     protected void afterHookedMethod(MethodHookParam param) throws Throwable {     


                        //打印日志   


      XposedBridge.log("方法参数Hook成功: 现参数 = " + param.args[0]);      


     }


    });


一共五个参数:


第一个参数是类名



第二个是当前应用的类加载器


第三个参数是方法名称


第四个参数是方法的参数类型(空参则不填,如果需要填,参数类型 +.class即可)


最后的参数是一个类,我是用的XC_MethodHook类,他提供了两个方法


分别是beforeHookedMethod(方法调用前)和afterHookedMethod(方法调用后)执行


这两个方法中需要定义一个参数,MethodHookParam param,这个参数可以获取方法的信息,它提供了很多属性,如args(方法参数数组),thisObject(当前实例对象)等,


如果你只想打印出来是否Hook等不需要方法运行状态的信息,那你可以不填参这个参数


下面是Hook成功打印出来的日志(最后一条):



关于Class对象的获取,Xposed提供的有XposedHelpers.findClass()方法


方法提供了有两个重载,正常直接在方法传入类名与当前应用的类加载器,如XposedHelpers.findClass("xxx.xxx.xx",lpparam.classLoader),然后定义一个Class对象接收即可


Hook静态变量:

所需函数


XposedHelpers.setStaticxxxField(Class<?> clazz, String fieldName, int value)


XposedHelpers.setStaticObjectField(Object obj, String fieldName, Object value) 



第一个是基础类型的Hook



第二个是对象类型的Hook




关于基础类型的Hook,XposedHelpers中提供了很多方法,如setStaticIntField(),setStaticByteField(),setStaticCharField()等,


关于对象的就只有setStaticObjectField()方法


具体代码:


//hook变量(更改变量值(对象,字段名,需要修改的值))


       Class clas = XposedHelpers.findClass("com.demo.MainActivity", lpparam.classLoader);      


XposedHelpers.setStaticObjectField(clas, "Name", "pass");


 XposedHelpers.setStaticIntField(clas, "pass", 6666);


XposedBridge.log("变量Hook成功");



下面是Hook成功打印出来的日志(最后一条):

Hook构造方法


所需函数:


XposedHelpers.findAndHookConstructorClass<?> clazz, Object... parameterTypesAndCallback)


参数传入与Hook方式findAndHookMethod方法基本相同


具体代码:

//hook构造方法

Class claz =XposedHelpers.findClass("com.demo.demo2test", lpparam.classLoader);


XposedHelpers.findAndHookConstructor(claz, String.class, int.class, new XC_MethodHook(){

                protected void beforeHookedMethod(XC_MethodHook.MethodHookParam param) {

                    //设置构造参数


                    param.args[0] = "Moiy"; 


                    param.args[1] = 9999;


                }


                protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {                   


                    //打印日志          


                    XposedBridge.log("构造方法Hook成功: = " + param.args[0] + " " + param.args[1]);                     


                }


            });



这个没什么好讲的,和findAndHookMethod方法基本一样


默认不填构造参数的话,hook的就是空参构造,有的话就是有参构造


日志输出(最后一条):


什么?你问我为什么不讲更高级的用法?


篇幅有限,下次一定



最后给大家看一下Hook全代码:

package con.xposed.demo;


 


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.LoadPackageParam;


import java.lang.reflect.Method;


 


 


public class HookInit implements IXposedHookLoadPackage {

 


 @Override


 public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {

        if (!lpparam.packageName.equals("com.demo")) return; //判断包名


final Class<?> claz =XposedHelpers.findClass("com.demo.demo2test", lpparam.classLoader);


//hook构造方法


        XposedHelpers.findAndHookConstructor(claz, String.class, int.class, new XC_MethodHook(){

                protected void beforeHookedMethod(XC_MethodHook.MethodHookParam param) {

                    //设置构造参数


                    param.args[0] = "Moiy"; 


                    param.args[1] = 9999;


                }


                protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {                   


                    //打印日志          


                    XposedBridge.log("构造方法Hook成功: = " + param.args[0] + " " + param.args[1]);                     


                }


            });


//hook静态变量(更改静态变量值(对象,字段名,需要修改的值))


        Class<?> clas = XposedHelpers.findClass("com.demo.MainActivity", lpparam.classLoader);      


        XposedHelpers.setStaticObjectField(clas, "Name", "pass");


        XposedHelpers.setStaticIntField(clas, "pass", 6666);


        XposedBridge.log("静态方法Hook成功");


 //hook方法(类名,加载器,方法名,参数,匿名类)       


   XposedHelpers.findAndHookMethod(


    "com.demo.MainActivity",


    lpparam.classLoader,


    "check",String.class,


    new XC_MethodHook(){

     protected void beforeHookedMethod(MethodHookParam param){

                        //设置方法参数为123456        


      param.args[0]="123456";                           


     }


     protected void afterHookedMethod(MethodHookParam param) throws Throwable {     


                        //打印日志   


      XposedBridge.log("方法参数Hook成功: 现参数 = " + param.args[0]);      


     }     


    });


}}


[注意]看雪招聘,专注安全领域的专业人才平台!

最后于 2025-4-15 14:38 被Moly编辑 ,原因: 修复显示
收藏
免费 1
支持
分享
赞赏记录
参与人
雪币
留言
时间
我是小奥
感谢你的贡献,论坛因你而更加精彩!
2天前
最新回复 (3)
雪    币: 46
活跃值: (101)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
没人评论,那我就自己评论
2025-4-15 10:40
0
雪    币: 254
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
感谢分享,很详细
2025-4-15 18:44
0
雪    币: 1478
活跃值: (947)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
感谢分享,很详细
4天前
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册