LSposed hook(学习分享)

Xposed模块编写

参考:
https://www.52pojie.cn/thread-1740944-1-1.html
https://www.52pojie.cn/thread-1748081-1-1.html

环境配置

电脑端准备

1.官网下载相关jar包
https://github.com/bywhat/XposedBridgeApi/blob/main/XposedBridgeAPI-82.jar
2.将jar包导入到android工程中

  • 项目下创建libs目录,将jar包导入
  • 配置gradle,直接在build.gradledependencies下添加即可
compileOnly(files("libs/XposedBridgeAPI-82.jar"))

3.配置项目

  • AndroidManifest.xml下的application添加下面元数据
<application  
    android:allowBackup="true"  
    android:icon="@mipmap/ic_launcher"  
    android:label="@string/app_name"  
    android:roundIcon="@mipmap/ic_launcher_round"  
    android:supportsRtl="true"  
    android:theme="@style/Theme.Test" >  
    <meta-data        android:name="xposedmodule"  
        android:value="true" />  
    <meta-data        android:name="xposeddescription"  
        android:value="My test xposed" />  
    <meta-data        android:name="xposedminversion"  
        android:value="82" />  
        <!-- 根据版本号 -->
</application>
  • main目录下添加assets/xposed_init文件,文件中写入口类名
com.example.xposed.MyXposed

4.在配置好的类中愉快的hook

public class MyXposed implements IXposedHookLoadPackage {  
  
    @Override  
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {  
        XposedBridge.log("MytagIs:" + loadPackageParam.packageName);  
    }  
}
手机端

1.用Magisk Root手机并在设置中开启zygisk

2.下载Lsposed
https://github.com/LSPosed/LSPosed

3.在Magisk 模块安装Lsposed zygisk版的发行压缩包

Xposed

类的路径
外部类:com.zj.wuaipojie.Demo
内部类:com.zj.wuaipojie.Demo$inner
hook函数

用回调函数XC_MethodHook来修改传入参数和返回值
常规函数

XposedHelpers.findAndHookMethod("com.zj.wuaipojie.Demo", loadPackageParam.classLoader, "a", "java.lang.String", new XC_MethodHook() {  
    @Override  
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {  
        super.beforeHookedMethod(param);  
        //获取参数  
        Log.d("zj2595", param.args[0].toString());  
        //设置传入参数
        param.args[0] = "hook普通参数";  
        Log.d("zj2595", param.args[0].toString());  
    }  
    @Override  
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {  
        super.afterHookedMethod(param);  
        //获取返回值  
        Log.d("zj2595", param.getResult().toString());  
        //设置返回值
        param.setResult("我hook普通返回");  
    }  
});

hook复杂/自定义方法

Class<?> clazz = loadPackageParam.classLoader.loadClass("com.zj.wuaipojie.Demo");  
XposedBridge.hookAllMethods(clazz, "complexParameterFunc", new XC_MethodHook() {  
    @Override  
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {  
        super.beforeHookedMethod(param);  
        Log.d("zj2595", param.args[0].toString());  
        param.args[0] = "hook复杂参数";  
        Log.d("zj2595", param.args[0].toString());  
    }  
  
    @Override  
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {  
        super.afterHookedMethod(param);  
        Log.d("zj2595", param.getResult().toString());  
        param.setResult("我hook复杂返回");  
    }  
});

用回调函数XC_MethodReplacement来替换该函数
替换函数

Class<?> clazz = loadPackageParam.classLoader.loadClass("com.zj.wuaipojie.Demo");  
XposedBridge.hookAllMethods(clazz, "repleaceFunc", new XC_MethodReplacement() {  
  
    @Override  
    protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {  
        Log.d("zj2595", "我将函数替换了");  
        return null;  
    }  
});

加固后函数


构造函数
通过签名区分

XposedBridge.hookAllConstructors(clazz, new XC_MethodHook() {  
    @Override  
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {  
        super.beforeHookedMethod(param);  
        Constructor<?> constructor = (Constructor<?>) param.method;  
        Class<?>[] parameterTypes  = constructor.getParameterTypes();  
        Log.d("zj2595", "构造" + Arrays.toString(parameterTypes));  
    }  
    @Override  
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {  
        super.afterHookedMethod(param);  
  
    }  
  
});

直接hook特定函数

XposedHelpers.findAndHookConstructor("com.zj.wuaipojie.Demo", loadPackageParam.classLoader, "java.lang.String", new XC_MethodHook() {  
    @Override  
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {  
        super.beforeHookedMethod(param);  
        Log.d("zj2595", "hook str构造函数");  
    }  
    @Override  
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {  
        super.afterHookedMethod(param);  
    }  
});  
  
XposedHelpers.findAndHookConstructor("com.zj.wuaipojie.Demo", loadPackageParam.classLoader, new XC_MethodHook() {  
    @Override  
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {  
        super.beforeHookedMethod(param);  
        Log.d("zj2595", "hook 空参构造函数");  
    }  
    @Override  
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {  
        super.afterHookedMethod(param);  
    }  
});

Dex


hook变量

静态成员变量

final Class<?> clazz = loadPackageParam.classLoader.loadClass("com.zj.wuaipojie.Demo");  
//获取静态成员变量  
        Log.i("zj2595", (String) XposedHelpers.getStaticObjectField(clazz, "staticField"));  
//设置静态成员变量  
        XposedHelpers.setStaticObjectField(clazz, "staticField", "hook_static");

普通成员变量
要在构造函数运行后获取修改

final Class<?> clazz = loadPackageParam.classLoader.loadClass("com.zj.wuaipojie.Demo");  
XposedBridge.hookAllConstructors(clazz, new XC_MethodHook() {  
    @Override  
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {  
        super.afterHookedMethod(param);  
        //获取成员变量  
        Log.d("zj2595", String.valueOf(XposedHelpers.getIntField(param.thisObject, "publicInt")));  
        //设置成员变量  
        XposedHelpers.setIntField(param.thisObject,"publicInt", 999);  
    }  
});
方法调用

成员方法

final Class<?> clazz = loadPackageParam.classLoader.loadClass("com.zj.wuaipojie.Demo");  
XposedHelpers.callMethod(clazz.newInstance(), "refl");

静态方法

final Class<?> clazz = loadPackageParam.classLoader.loadClass("com.zj.wuaipojie.Demo");  
XposedHelpers.callStaticMethod(clazz.newInstance(), "staticrefl");
Xposed应用

遍历类下的所有方法

XposedHelpers.findAndHookMethod(ClassLoader.class, "loadClass", String.class, new XC_MethodHook() {  
    @Override  
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {  
        super.afterHookedMethod(param);  
        Class<?> clazz = (Class<?>) param.getResult();  
        if(clazz.getName().contains("com.zj.wuaipojie")){  
            Method[] methods = clazz.getDeclaredMethods();  
            for(Method method : methods){  
                //排除抽象,本地,接口方法  
                if(!Modifier.isAbstract(method.getModifiers()) &&  
                !Modifier.isNative(method.getModifiers()) &&  
                !Modifier.isInterface(method.getModifiers())){  
                    XposedBridge.hookMethod(method, new XC_MethodHook() {  
                        @Override  
                        protected void beforeHookedMethod(MethodHookParam param) throws Throwable {  
                            super.beforeHookedMethod(param);  
                            Log.d("zj2595", method.toString());  
                        }  
                    });  
                }  
            }  
        }  
    }  
});

字符串赋值定位

XposedBridge.hookAllMethods(TextView.class, "setText", new XC_MethodHook() {  
    @Override  
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {  
        super.beforeHookedMethod(param);  
        PrintStack();  
    }  
});
//打印堆栈
private void PrintStack(){  
    Throwable ex = new Throwable();  
    StackTraceElement[] stacktrace = ex.getStackTrace();  
    for(StackTraceElement stack : stacktrace){  
        Log.d("zj2595", "line:" + stack.getLineNumber() + "  class:" + stack.getClassName() + "  method:" + stack.getMethodName() + "  file:" + stack.getFileName() );  
    }  
}

点击事件监听

XposedHelpers.findAndHookMethod(View.class, "setOnClickListener", View.OnClickListener.class,new XC_MethodHook() {  
    @Override  
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {  
        super.afterHookedMethod(param);  
        Class<?> clazz = param.args[0].getClass();  
        if(clazz != null){  
            XposedHelpers.findAndHookMethod(clazz, "onClick", View.class, new XC_MethodHook() {  
                @Override  
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {  
                    super.beforeHookedMethod(param);  
                    View view = (View)param.args[0];  
                    Log.i("zj2595", String.format("Buttonid:0x%x",view.getId()));  
                }  
            });  
        }  
    }  
});

修改布局

XposedHelpers.findAndHookMethod("com.zj.wuaipojie.ui.ChallengeSixth", loadPackageParam.classLoader, "onCreate", "android.os.Bundle", new XC_MethodHook() {  
    @Override  
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {  
        super.beforeHookedMethod(param);  
    }  
    @Override  
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {  
        super.afterHookedMethod(param);  
        View view = (View)XposedHelpers.callMethod(param.thisObject, "findViewById", 0x7f0800de);  
        view.setVisibility(View.GONE);  
    }  
});
posted @ 2025-04-08 13:46  ClownLMe  阅读(189)  评论(0)    收藏  举报