[Xposed]Xposed模块开发入门教程

Xposed开发基础实例

众所周知,Android系统中应用程序进程都是由Zygote进程孵化出来的,而Zygote进程是由Init进程启动的。Zygote进程在启动时会创建一个Dalvik虚拟机实例,每当它孵化一个新的应用程序进程时,都会将这个Dalvik虚拟机实例复制到新的应用程序进程里面去,而一个应用程序进程被Zygote进程孵化出来的时候,不仅会获得Zygote进程中的Dalvik虚拟机实例拷贝,还会与Zygote一起共享Java运行时库。

Xposed则通过替换app_process程序来控制Zygote进程,使得app_process在启动过程中会加载XposedBridge.jar这个jar包,从而完成对Zygote进程及其创建的Dalvik虚拟机的劫持。

这里不细讲Zygote!!!!

实战GoGoGo!

未作说明的话,本例中创建的工程为Empty Activity

构建一个简单的需要被劫持的应用

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textHello"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:textSize="50sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="是否被劫持"/>

</LinearLayout>

用简单的线性布局添加一个按钮即可,毕竟以后不可能自己去开发自己开发的app的模块。

MainActivity.java

package XXX;
// 此为你的包名,AS未作特殊设置的话会自动生成


import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.button);
        // 这个是按钮id
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity.this, getToast(), Toast.LENGTH_SHORT).show();
                Log.println(Log.INFO, "Tc", "调用onclick");
            }
        });
    }

    public String getToast() {
        return "我没有被劫持";
    }
}

只是对按钮进行OnClick事件的监听,让其返回未被劫持的提示

安装到真机或是虚拟机上

image

构建一个简单的需要被劫持的应用

这里建议新建一个工程,分开成2个应用模拟劫持

首先要更改src/main目录下的AndroidManifest.xml,让Xposed识别这是一个Xposed模块

AndroidManifest.xml

可以在 active 标签开始前添加以下信息

		<meta-data
            android:name="xposedmodule"
            android:value="true"
            />
        <meta-data
            android:name="xposeddescription"
            android:value="这是一个Xposed例程"
            />
        <meta-data
            android:name="xposedminversion"
            android:value="53"
            />

xposedmodule 是否为Xposed模块

xposeddescription 描述

xposedminversion 最小支持Xposed版本

导包

这里直接更改src/main目录下的build.gradle即可

dependencies添加

compileOnly 'de.robv.android.xposed:api:82'

然后直接选择上方Sync Now直接同步即可

若网络原因失败,可尝试更换国内仓库源

layout & Main

事实上,如果要开发一个功能强大且需要自定义设置的可以自行编写布局样式与MainActivity类

本实例中无需,但更改了layout中的TextView的内容与布局格式作为展示

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textHello"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="劫持测试"
        android:textSize="50sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</LinearLayout>

MainActivity.java

package XXX;
// 包名

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

这个就是自动生成的,未做更改

编写劫持类

在MainActivity同目录下创建Java类,本例中为HookTest

package XXX;
// 包名

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;

public class HookTest implements IXposedHookLoadPackage {
    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
        if (lpparam.packageName.equals("XXXX"))
            // 此处XXXX为被劫持的包名
        {
            XposedBridge.log("Im on hook");
            Class<?> clazz = lpparam.classLoader.loadClass("XXXX.YY");
            // 反射
            // 此处XXXX为被劫持包名,YY为劫持类
            XposedHelpers.findAndHookMethod(clazz, "getToast", new XC_MethodHook() 
                 // 这个getToast即为方法名
                {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    super.beforeHookedMethod(param);
                }

                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    param.setResult("已被劫持,耶斯莫拉");
                }
            });
        }
    }
}

让HookTest实现IXposedHookLoadPackage接口并重写handleLoadPackage方法


xposed_init

创建文件夹与文件

在main下New -> Folder -> AssetsFolder创建一个Assets文件夹,并在里面创建一个名为xposed_init的普通文件

image

image

写文件

将刚编写的劫持类包名.类写入到这个文件中,本例中类名为HookTest

image


安装与启用

安装到真机或者模拟器,我用的是LSPOSED,安装后则会直接提示模块未启用,点击进入选择作用域(目标应用)并打开开关

启用&效果

启用模块

image

检验

杀掉之前打开的目标应用后台,并重新启动

重新点击按钮

发现劫持成功

image


关闭模块并检验

关闭模块

image

重新打开

发现已还原

image

结语

像我们这个例子很简单,没有特意的进行代码混淆以及程序入口改写等等,我们寻找还是很简单的,一般市面上的App都是有很多反Xposed的行为,我们其实要学习的还有很多,这个小教程就当做个小入门吧。

posted @ 2022-10-03 00:00  小天呜啦啦  阅读(463)  评论(0)    收藏  举报