Xposed

xposed开发环境搭建

创建一个无Activity的项目,切换到Project视图,在app目录下创建一个lib目录
在这里插入图片描述
将xposed的jar添加到lib目录下,选中这个jar包,然后右击,将这个添加为库(编译的时候,不需要打包这个jar包)
在build.gradle的dependencies中添加一行

provided files('lib/api-82.jar')

在这里插入图片描述
修改AndroidManifest.xml

<meta-data
    android:name="xposedmodule"
    android:value="true" />
<meta-data
    android:name="xposeddescription"
    android:value="my name is xiaojianbang" />
<meta-data
    android:name="xposedminversion"
    android:value="53" />

在这里插入图片描述
然后创建一个类Hook,输入内容

public class Hook implements IXposedHookLoadPackage{

    // Xposed是一个全局的Hook
    // 如果对一个app进行过滤,需要 参数XC_LoadPackage.LoadPackageParam loadPackageParam进行判断
    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
        Log.d("showme","hook start...");

        if(!loadPackageParam.packageName.equals("com.xingin.xls")) return;
        
    }
}

在main目录下创建一个assets目录,创建一个文本文件 xposed_init
指定入口类:在其中输入 Hook类的完整路径名(包名.类名)
在这里插入图片描述
点击Build
在这里插入图片描述
找到生成的apk,进行安装
在这里插入图片描述
安装好之后,激活模块,然后重启
在这里插入图片描述

hook构造函数

ClassLoader classLoader = loadPackageParam.classLoader;
Class StudentClass = classLoader.loadClass("com.showme.xposedhook01.Student");
XposedHelpers.findAndHookConstructor(StudentClass, new XC_MethodHook() {
    @Override
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
        super.beforeHookedMethod(param);
        XposedBridge.log("com.showme.xposedhook01.Student() is called!!beforeHookedMethod");
    }

    @Override
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
        super.afterHookedMethod(param);
        XposedBridge.log("com.showme.xposedhook01.Student() is called!!afterHookedMethod");
    }
});


XposedHelpers.findAndHookConstructor(StudentClass, String.class, new XC_MethodHook() {
    @Override
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
        super.beforeHookedMethod(param);
        java.lang.Object[] argsobjarray = param.args;
        String name = (String) argsobjarray[0];
        XposedBridge.log("com.showme.xposedhook01.Student(String) is called!!beforeHookedMethod--" + name);
    }

    @Override
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
        super.afterHookedMethod(param);
        XposedBridge.log("com.showme.xposedhook01.Student(String) is called!!afterHookedMethod");
    }
});


XposedHelpers.findAndHookConstructor("com.showme.xposedhook01.Student", loadPackageParam.classLoader, String.class, String.class, new XC_MethodHook() {
    @Override
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
        super.beforeHookedMethod(param);
        java.lang.Object[] argsobjarray = param.args;
        String name = (String) argsobjarray[0];
        String id = (String) argsobjarray[1];
        XposedBridge.log("com.showme.xposedhook01.Student(String,String) is called!!beforeHookedMethod--" + name + "---" + id);

    }
});


ClassLoader pathClassLoader= loadPackageParam.classLoader;
final Class stuClass=pathClassLoader.loadClass("com.showme.xposedhook01.Student");
XposedHelpers.setStaticObjectField(stuClass,"teacher","teacher888");
String teachername2= (String) XposedHelpers.getStaticObjectField(stuClass,"teacher");



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[] argsobjarray = param.args;
        String name = (String) argsobjarray[0];
        String id = (String) argsobjarray[1];
        int age = (int) (argsobjarray[2]);
        argsobjarray[1] = "2050";
        argsobjarray[2] = 100;

        String teacher= (String) argsobjarray[3];
        String nickname= (String) argsobjarray[4];

        XposedBridge.log("com.showme.xposedhook01.Student(String,String) is called!!beforeHookedMethod--" + name + "---" + id + "--" + age+"---"+teacher+"---"+nickname);
    }

    @Override
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
        super.afterHookedMethod(param);

        Object thisobj = param.thisObject;

    /*       Field nicknameField=stuClass.getDeclaredField("nickname");
        XposedBridge.log(stuClass+"--nicknameField->"+nicknameField);
        nicknameField.setAccessible(true);
        nicknameField.set(thisobj,"bear");*/

        XposedHelpers.setObjectField(thisobj,"nickname","chick");

        Object returnobj = param.getResult();
        XposedBridge.log(thisobj + "---" + returnobj);
        XposedBridge.log("com.showme.xposedhook01.Student(String,String,int) is called!!afterHookedMethod");
    }
});

hook系统类,DexClassLoader,应用加载了哪些插件

XposedHelpers.findAndHookConstructor(DexClassLoader.class, String.class, String.class, String.class, ClassLoader.class, new XC_MethodHook() {
    @Override
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
        super.beforeHookedMethod(param);
        Object array[]=param.args;
        String dexpath= (String) array[0];
        String optimizedDirectory= (String) array[1];
        String librarySearchPath= (String) array[2];
        XposedBridge.log("DexClassLoader beforeHookedMethod:"+dexpath+"---"+optimizedDirectory+"---"+librarySearchPath);

    }

    @Override
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
        super.afterHookedMethod(param);

        DexClassLoader dexClassLoader= (DexClassLoader) param.thisObject;
        XposedBridge.log("DexClassLoader afterHookedMethod:"+dexClassLoader);
    }
});

hook属性:使用java反射和Xposed的API

ClassLoader classLoader = loadPackageParam.classLoader;
Class StudentClass = classLoader.loadClass("com.showme.xposedhook.Student");

// java反射
Field teacherField=stuClass.getDeclaredField("teacher");
teacherField.setAccessible(true);
teacherField.set(null,"teacher666");
String teachername1= (String) teacherField.get(null);
XposedBridge.log("teacherField->"+teachername1);

// Xposed中的实现和java反射一样,但是默认调用了 setAccessible(true);
XposedHelpers.setStaticObjectField(stuClass,"teacher","teacher888");
String teachername2= (String) XposedHelpers.getStaticObjectField(stuClass,"teacher");


@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
    super.afterHookedMethod(param);

    Object thisobj = param.thisObject;
    XposedHelpers.setObjectField(thisobj,"nickname","chick");

    Object returnobj = param.getResult();
    XposedBridge.log(thisobj + "---" + returnobj);
}

hook一般方法

ClassLoader classLoader = loadPackageParam.classLoader;
Class StuClass = classLoader.loadClass("com.showme.xposedhook01.Student");

// 一般java函数的hook 
XposedHelpers.findAndHookMethod("com.showme.xposedhook01.Student", loadPackageParam.classLoader, "privatefunc", String.class, int.class, new XC_MethodHook() {
    @Override
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
        super.beforeHookedMethod(param);
        Object[] objectarray = param.args;
        String arg0 = (String) objectarray[0];
        int arg1 = (int) objectarray[1];
        XposedBridge.log("beforeHookedMethod11 privatefunc->arg0:" + arg0 + "---arg1:" + arg1);

    }

    @Override
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
        super.afterHookedMethod(param);

        String result = (String) param.getResult();
        XposedBridge.log("afterHookedMethod11 privatefunc->result:" + result);

    }
});

// 内部类中的函数hook
Class personClass = XposedHelpers.findClass("com.showme.xposedhook01.Student$person", loadPackageParam.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());
    }
});

// 匿名内部类函数的hook - 匿名内部类总会有一个类名的,用那个类名就行了

// 类中JNI函数的hook - 和普通函数一样

主动调用函数

// java 反射的方式
ClassLoader classLoader = loadPackageParam.classLoader;
Class StuClass = classLoader.loadClass("com.showme.xposedhook01.Student");
Method publicstaticfunc_method = StuClass.getDeclaredMethod("publicstaticfunc", String.class, int.class);
publicstaticfunc_method.invoke(null, "InvokedByXposed", 100);

// Xposed 中的API
//            public static java.lang.Object callMethod(java.lang.Object obj, java.lang.String methodName, java.lang.Object... args) { /* compiled code */ }
//
//            public static java.lang.Object callMethod(java.lang.Object obj, java.lang.String methodName, java.lang.Class<?>[] parameterTypes, java.lang.Object... args) { /* compiled code */ }
//
//            public static java.lang.Object callStaticMethod(java.lang.Class<?> clazz, java.lang.String methodName, java.lang.Object... args)
//
//            public static java.lang.Object callStaticMethod(java.lang.Class<?> clazz, java.lang.String methodName, java.lang.Class<?>[] parameterTypes, java.lang.Object... args)

java.lang.Class<?>[] parameterTypes = {String.class, int.class};

XposedHelpers.callStaticMethod(StuClass, "publicstaticfunc", parameterTypes, "publicstaticfunc is called by XposedHelpers.callStaticMethod11", 100);
XposedHelpers.callStaticMethod(StuClass, "publicstaticfunc", "publicstaticfunc is called by XposedHelpers.callStaticMethod22", 200);

XposedHelpers.callStaticMethod(StuClass, "privatestaticfunc", parameterTypes, "privatestaticfunc is called by XposedHelpers.callStaticMethod11", 400);
XposedHelpers.callStaticMethod(StuClass, "privatestaticfunc", "privatestaticfunc is called by XposedHelpers.callStaticMethod22", 300);


Method privatestaticfunc_method = StuClass.getDeclaredMethod("privatestaticfunc", String.class, int.class);
privatestaticfunc_method.setAccessible(true);
String result = (String) privatestaticfunc_method.invoke(null, "privatestaticfuncIsInvokedByXposed", 200);


//            public static java.lang.Object callMethod(java.lang.Object obj, java.lang.String methodName, java.lang.Object... args) { /* compiled code */ }
//
//            public static java.lang.Object callMethod(java.lang.Object obj, java.lang.String methodName, java.lang.Class<?>[] parameterTypes, java.lang.Object... args) { /* compiled code */ }

//            public static java.lang.Object newInstance(java.lang.Class<?> clazz, java.lang.Object... args) { /* compiled code */ }
//
//            public static java.lang.Object newInstance(java.lang.Class<?> clazz, java.lang.Class<?>[] parameterTypes, java.lang.Object... args) { /* compiled code */ }


Object StuObjByXposed = XposedHelpers.newInstance(StuClass, "StuObjByXposed.newInstance", "500");
String result1 = (String) XposedHelpers.callMethod(StuObjByXposed, "publicfunc", "publicfunc is called by XposedHelpers.callMethod", 125);
XposedBridge.log("publicfunc XposedHelpers.callMethod result->" + result1);

XposedHelpers.callMethod(StuObjByXposed, "privatefunc", "privatefunc is called by XposedHelpers.callMethod", 130);




//Student cstudent = new Student("xiaohua", "2020");
XposedHelpers.findAndHookConstructor(StuClass, String.class, String.class, new XC_MethodHook() {
    @Override
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
        super.beforeHookedMethod(param);
        XposedBridge.log("Student(String,String) is called beforeHookedMethod");
    }

    @Override
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
        super.afterHookedMethod(param);
        XposedBridge.log("Student(String,String) is called afterHookedMethod");
        Object cstudent=param.thisObject;
        XposedHelpers.callMethod(cstudent,"publicfunc","publicfunc is called XposedHelpers.findAndHookConstructor",666);
        XposedHelpers.callMethod(cstudent,"privatefunc","privatefunc is called XposedHelpers.findAndHookConstructor",888);
    }
});


//            public String getNickname() {
//                return nickname;
//            }

XposedHelpers.findAndHookMethod(StuClass, "getNickname", new XC_MethodHook() {
    @Override
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
        super.beforeHookedMethod(param);
        Object obj=param.thisObject;
        XposedHelpers.callMethod(obj,"publicfunc","beforeHookedMethod publicfunc is called XposedHelpers.callMethod",444);
        XposedHelpers.callMethod(obj,"privatefunc","beforeHookedMethod privatefunc is called XposedHelpers.callMethod",333);

        XposedBridge.log("getNickname is called beforeHookedMethod->"+obj);
    }

    @Override
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
        super.afterHookedMethod(param);
        Object obj=param.thisObject;
        XposedHelpers.callMethod(obj,"publicfunc","afterHookedMethod publicfunc is called XposedHelpers.callMethod",222);
        XposedHelpers.callMethod(obj,"privatefunc","afterHookedMethod privatefunc is called XposedHelpers.callMethod",111);

        XposedBridge.log("getNickname is called afterHookedMethod->"+param.thisObject);
    }
});

加壳APP处理

/*
1、对于有壳的apk,Xposed首先拿到的是壳的classloader
2、壳一般在,壳代码的OnCreate修成classloader
*/
public class HookShellApk implements IXposedHookLoadPackage {

    public static Field getClassField(ClassLoader classloader, String class_name,
                                      String filedName) {

        try {
            Class obj_class = classloader.loadClass(class_name);//Class.forName(class_name);
            Field field = obj_class.getDeclaredField(filedName);
            field.setAccessible(true);
            return field;
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;

    }

    public static Object getClassFieldObject(ClassLoader classloader, String class_name, Object obj,
                                             String filedName) {

        try {
            Class obj_class = classloader.loadClass(class_name);//Class.forName(class_name);
            Field field = obj_class.getDeclaredField(filedName);
            field.setAccessible(true);
            Object result = null;
            result = field.get(obj);
            return result;
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;

    }

    public static Object invokeStaticMethod(String class_name,
                                            String method_name, Class[] pareTyple, Object[] pareVaules) {

        try {
            Class obj_class = Class.forName(class_name);
            Method method = obj_class.getMethod(method_name, pareTyple);
            return method.invoke(null, pareVaules);
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;

    }

    public static Object getFieldOjbect(String class_name, Object obj,
                                        String filedName) {
        try {
            Class obj_class = Class.forName(class_name);
            Field field = obj_class.getDeclaredField(filedName);
            field.setAccessible(true);
            return field.get(obj);
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NullPointerException e) {
            e.printStackTrace();
        }
        return null;

    }

    public static ClassLoader getClassloader() {
        ClassLoader resultClassloader = null;
        Object currentActivityThread = invokeStaticMethod(
                "android.app.ActivityThread", "currentActivityThread",
                new Class[]{}, new Object[]{});
        Object mBoundApplication = getFieldOjbect(
                "android.app.ActivityThread", currentActivityThread,
                "mBoundApplication");
        Application mInitialApplication = (Application) getFieldOjbect("android.app.ActivityThread",
                currentActivityThread, "mInitialApplication");
        Object loadedApkInfo = getFieldOjbect(
                "android.app.ActivityThread$AppBindData",
                mBoundApplication, "info");
        Application mApplication = (Application) getFieldOjbect("android.app.LoadedApk", loadedApkInfo, "mApplication");
        resultClassloader = mApplication.getClassLoader();
        return resultClassloader;
    }

    public void GetClassLoaderClasslist(ClassLoader classLoader) {
        //private final DexPathList pathList;
        //public static java.lang.Object getObjectField(java.lang.Object obj, java.lang.String fieldName)
        XposedBridge.log("start dealwith classloader:" + classLoader);
        Object pathListObj = XposedHelpers.getObjectField(classLoader, "pathList");
        //private final Element[] dexElements;
        Object[] dexElementsObj = (Object[]) XposedHelpers.getObjectField(pathListObj, "dexElements");
        for (Object i : dexElementsObj) {
            //private final DexFile dexFile;
            Object dexFileObj = XposedHelpers.getObjectField(i, "dexFile");
            //private Object mCookie;
            Object mCookieObj = XposedHelpers.getObjectField(dexFileObj, "mCookie");
            //private static native String[] getClassNameList(Object cookie);
            //    public static java.lang.Object callStaticMethod(java.lang.Class<?> clazz, java.lang.String methodName, java.lang.Object... args) { /* compiled code */ }
            Class DexFileClass = XposedHelpers.findClass("dalvik.system.DexFile", classLoader);

            String[] classlist = (String[]) XposedHelpers.callStaticMethod(DexFileClass, "getClassNameList", mCookieObj);
            for (String classname : classlist) {
                XposedBridge.log(dexFileObj + "---" + classname);
            }
        }
        XposedBridge.log("end dealwith classloader:" + classLoader);

    }

    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
        Log.i("Xposed01", loadPackageParam.packageName);
        XposedBridge.log("HookLebo->app packagename" + loadPackageParam.packageName);
        if (loadPackageParam.packageName.equals("com.test.abc")) {
            XposedBridge.log("showme " + loadPackageParam.packageName);
            Class StubAppClass=XposedHelpers.findClass("com.test.abc.MyWrapperProxyApplication",loadPackageParam.classLoader);
            Method[] methods=StubAppClass.getDeclaredMethods();
            for(Method i:methods){
                XposedBridge.log("com.test.abc.MyWrapperProxyApplication->"+i);
            }
            XposedHelpers.findAndHookMethod("com.test.abc.MyWrapperProxyApplication", loadPackageParam.classLoader, "onCreate", new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    super.beforeHookedMethod(param);
                    XposedBridge.log("com.test.abc.MyWrapperProxyApplication->onCreate beforeHookedMethod");
                }

                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);
                    XposedBridge.log("com.test.abc.MyWrapperProxyApplication->onCreate afterHookedMethod");

                    ClassLoader finalClassLoader=getClassloader();
                    XposedBridge.log("finalClassLoader->" + finalClassLoader);
                    XposedHelpers.findAndHookMethod("com.orginal.apk.MainActivity", finalClassLoader, "onCreate", Bundle.class, new XC_MethodHook() {
                        @Override
                        protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                            super.beforeHookedMethod(param);
                            XposedBridge.log("beforeHookedMethod com.orginal.apk.MainActivity.onCreate");

                        }

                        @Override
                        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                            super.afterHookedMethod(param);
                            XposedBridge.log("afterHookedMethod com.orginal.apk.MainActivity.onCreate");

                        }
                    });
                }
            });
        }
    }
}

so中函数处理

1、创建android studio native项目,使用inhook框架,编写hook的内容
2、通过Xposed,在java.lang.Runtime.loadLibrary的时机加载so

// java.lang.System.loadLibrary,的下一级,会使用当前调用者的ClassLoader,所以会被使用成Xposed的ClassLoader
// 可以用java.lang.Runtimem,但是在不同版本的源码中,loadLibrary的名字不一样,需要适配
XposedHelpers.findAndHookMethod("java.lang.Runtime", loadPackageParam.classLoader, "loadLibrary", String.class,ClassLoader.class, new XC_MethodHook() {
    @Override
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
        super.beforeHookedMethod(param);
        String soname= (String) param.args[0];
        XposedBridge.log("beforeHookedMethod Runtime.load("+soname+","+param.args[1]+")");
    }

    @Override
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
        super.afterHookedMethod(param);
        String soname= (String) param.args[0];
        XposedBridge.log("afterHookedMethod Runtime.load("+soname+")");
        if(soname.contains("native-lib")){
            System.load("/data/data/com.showme.xposedhookso/files/hookso.so");
        }
    }
});

对于armv8,可以使用sandHook框架

指纹检测与简单定制


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值