|
|
本帖最后由 陌璃与鱼 于 2025-4-21 08:14 编辑
好久没发帖了,发一个Xposed开发的教程 ,也算是我的学习笔记吧,可能会有一些错误,请大佬指出,
用的开发软件是AIDE Pro,直接创建模板即可
正文:
基本介绍:
Xposed是一款可以在不修改APK的情况下影响程序运行的框架,基于它可以制作出许多功能强大的模块,且在功能不冲突的情况下同时运作。在这个框架下,我们可以编写并加载自己编写的插件APP,实现对目标apk的注入拦截等。
关于Xposed类定义:
首先必须继承IXposedHookLoadPackage接口,并重写handleLoadPackage回调方法,像这样:
- public class HookInit implements IXposedHookLoadPackage {
- @Override
- public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {}
- }
复制代码
(AIDE Pro提供的模板已经帮我创建好了,所以这一步了解一下就好)
其中回调方法的LoadPackageParam lpparam参数是Xposed提供的,他可以获取当前应用的信息,他也提供了很多属性,如classLoader(当前类加载器),packageName(包名称)等
Xposed提供了很多封装好的Hook函数,但是本质使用的还是Java反射,下面我将写一个安卓demo作为案例来教大家怎么使用xposed提供的函数
- 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();
- }
- }
- //新建文件,并创建类:
- 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]);
- }
- });
复制代码
一共五个参数:
第一个参数是类名,
第二个是当前应用的类加载器,
第三个参数是方法名称,
第四个参数是方法的参数类型(空参则不填)
最后的参数是一个类,我是用的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.findAndHookConstructor(Class<?> 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]);
- }
- });
- }}
复制代码
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
-
查看全部评分
总评分:好评 +2
金币 +4
|