初次接触Xposed开发[Xposed]

来源:赵克立博客 分类: Android 标签:--发布时间:2018-04-04 14:56:21最后更新:2020-09-07 22:53:15浏览:3768
版权声明:
本文为博主原创文章,转载请声明原文链接...谢谢。o_0。
更新时间:
2020-09-07 22:53:15
温馨提示:
学无止境,技术类文章有它的时效性,请留意文章更新时间,如发现内容有误请留言指出,防止别人"踩坑",我会及时更新文章

开发环境

xposed文档 http://api.xposed.info/reference/de/robv/android/xposed/package-summary.html

android 5.1 

androidStudio 3.0.1

需要的文件

XposedInstaller xposed框架安装地址  https://forum.xda-developers.com/showthread.php?t=3034811

手机要root下载完成后直接按提示安装就可以

XposedBridge api下载地址 https://bintray.com/rovo89/de.robv.android.xposed/api

下载后有两个jar包

image.png

一个示例


打开androidstudio新建一个项目,实现检测系统中所有app启动的时候输出包的路径到日志中


修改AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.keli.wechatx">
    <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/AppTheme">
        <meta-data
        android:name="xposedmodule"
        android:value="true"/>
        <meta-data
            android:name="xposeddescription"
            android:value="hello xposed"/>
        <meta-data
            android:name="xposedminversion"
            android:value="82"/>
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

添加api库

把下载的两个jar文件放入libs目录中,然后从androidstudio中添加进去

image.png

添加完后还要修改一个地方,在编译的时候这两个库是不能编译进去的,因为xposed框架里已经有这些库啦,编译进去就导致重复,会报错

找到app的构建脚本 build.gradle文件

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:2.2.2'
    implementation files('libs/api-82.jar')
    implementation files('libs/api-82-sources.jar')
}

改为

dependencies {
//    implementation fileTree(include: ['*.jar'], dir: 'libs')
    compileOnly fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:2.2.2'
    //源码
    implementation files('libs/api-82.jar')
    //文档,方便查看说明
    implementation files('libs/api-82-sources.jar')
}

新建XModule类,继承IXposedHookLoadPackage

这个类是在所有app重启的时候都会调用的类

public class XModule implements IXposedHookLoadPackage {
    @Override
    public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
        XposedBridge.log("load app:"+lpparam.packageName);
        if (lpparam.packageName.equals("com.tencent.mm")) {
            XposedBridge.log("...........find it............");
        }
    }
}

   功能就是输出启动的app包路径




添加xposed的启动包引入文件

新建assets文件夹

image.png

然后在这个文件夹中新建一个xposed_init的文件输入com.example.XModule

运行效果

image.png

实现修改指定app界面上TestView的值

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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="com.keli.wechatx.MainActivity">
    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

java hook

public class XModule implements IXposedHookLoadPackage {
    @Override
    public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
        XposedBridge.log("load app:"+lpparam.packageName);
        //如果是指定包的话,就hook这个包里的MainActivity类的onCreate这个方法,修改文字 
        if (lpparam.packageName.equals("com.xxx")) {
            XposedHelpers.findAndHookMethod("com.xxx.MainActivity", lpparam.classLoader, "onCreate", Bundle.class, new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    //不能通过Class.forName()来获取Class ,在跨应用时会失效
                    Class c=lpparam.classLoader.loadClass("com.xxx.MainActivity");
                    Field field=c.getDeclaredField("textView");
                    field.setAccessible(true);
                    //param.thisObject 为执行该方法的对象,在这里指MainActivity
                    TextView textView= (TextView) field.get(param.thisObject);
                    textView.setText("Hello Xposed");
                }
            });
        }
    }
}

添加钩子的另一种写法

if (lpparam.packageName.equals("com.xxx")) {
    Class clazz;
    //加载对应的类
    clazz = lpparam.classLoader.loadClass("com.xxx.MainActivity");
    //hook类中对应的方法
    XposedHelpers.findAndHookMethod(clazz,  "onCreate",  new XC_MethodHook() {
        @Override
        protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
            super.beforeHookedMethod(param);
        }
        @Override
        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
            //不能通过Class.forName()来获取Class ,在跨应用时会失效
            Class c=lpparam.classLoader.loadClass("com.xxx.MainActivity");
            Field field=c.getDeclaredField("textView");
            field.setAccessible(true);
            //param.thisObject 为执行该方法的对象,在这里指MainActivity
            TextView textView= (TextView) field.get(param.thisObject);
            textView.setText("Hello Xposed");
        }
    });
}

强制okhttp3走系统代理

原理为hook okhttp3的proxy方法,设置的时候直接返回

// hook okhttp3
Class Builder = lpparam.classLoader.loadClass("okhttp3.OkHttpClient$Builder");
Class Proxy = lpparam.classLoader.loadClass("java.net.Proxy");
XposedHelpers.findAndHookMethod(Builder,
        "proxy",
        Proxy,
        new XC_MethodReplacement() {
            @Override
            protected Object replaceHookedMethod(XC_MethodHook.MethodHookParam methodHookParam) throws Throwable {
                return methodHookParam.thisObject;
            }
        });



微信号:kelicom QQ群:215861553 紧急求助须知
Win32/PHP/JS/Android/Python