Xposed從入門到棄坑:一、Xposed初探

最近心血來(lái)潮,開始折騰xposed框架,xposed框架可以說(shuō)得上是款A(yù)ndroid系統(tǒng)God級(jí)別的開源hook框架,擁有非常高的權(quán)限,不過(guò)目前還暫不支持Android 7.0 以上的系統(tǒng)。這也是我一直沒(méi)有升級(jí)的原因

什么是xposed

Xposed框架是一款可以在不修改APK的情況下影響程序運(yùn)行(修改系統(tǒng))的框架服務(wù),基于它可以制作出許多功能強(qiáng)大的模塊,且在功能不沖突的情況下同時(shí)運(yùn)作。Xposed理論上能夠hook到系統(tǒng)任意一個(gè)Java進(jìn)程,由于是從底層hook,所以需要root權(quán)限,并且每次更新都要重新啟動(dòng)
Xposed官方git上面有幾個(gè)開源項(xiàng)目,包括XposedInstallerXposed、XposedBridge、XposedTools,這里就不具體介紹了,感興趣的可以查找相關(guān)資料,附上官方git地址:https://github.com/rovo89

Xposed模擬器環(huán)境搭建

由于Xposed項(xiàng)目每次安裝都要重新啟動(dòng),在真機(jī)上是非常耗時(shí)間的,所以在這里選擇Genymotion模擬器,老版本的Genymotion模擬器有免費(fèi)版本的,我提供一款mac版的模擬器。win自己百度下載,mac版下載地址:https://pan.baidu.com/s/1pLDbymn ,密碼:j3rf。鏡像選擇Android5.0系統(tǒng),其他版本類似。然后到官網(wǎng)下載Android5.0對(duì)應(yīng)的框架,飛機(jī)直達(dá),選擇.zip結(jié)尾的文件,下載完成后運(yùn)行模擬器,將zip包拖到模擬器界面刷入即可,完成后重啟模擬器。安裝XposedInstaller_3.1.1 .apk應(yīng)用,再次重啟。進(jìn)入剛剛安裝的app,提示已激活即安裝成功

第一個(gè)項(xiàng)目

創(chuàng)建Xposed工程

為了方便今后的教程,工程已傳到github,可以直接clone該工程到本地。項(xiàng)目地址:https://github.com/WrBug/XposedDemo ,后面的教程的代碼也都將在這個(gè)工程里面,通過(guò)clone的可忽略下面創(chuàng)建工程的步驟。通過(guò)命令切換到提交:

git checkout 20195ce

創(chuàng)建一個(gè)新工程,build.gradle添加依賴:
provided 'de.robv.android.xposed:api:82'
編輯AndroidManifest.xml,添加:

     <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"/>

配置完成后,安裝到模擬器,狀態(tài)欄彈出如下提示:

第一個(gè)框架:Hello Xposed

git提交:43e4ba39e95988f0fa699ad5eddb1e55b9613638

Activity創(chuàng)建

編輯activity_main.xml,放入一個(gè)TextView:

<?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"
    android:orientation="vertical"
    tools:context="com.wrbug.xposeddemo.MainActivity">

    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>
</LinearLayout>

MainActivity 里面設(shè)置文本信息:

public class MainActivity extends AppCompatActivity {
    TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.textview);
        textView.setText("WrBug");
    }
}

Activity很簡(jiǎn)單。就是一個(gè)textview的顯示。安裝到模擬器上,界面顯示一行WrBug,下面通過(guò)xposed將WrBug修改成Hello Xposed顯示。
思路:Xposed hook onCreate方法。在該方法執(zhí)行完后獲取TextView的實(shí)例。通過(guò)setText方法設(shè)置文本

Xposed實(shí)現(xiàn)

新建一個(gè)類XposedInit實(shí)現(xiàn)IXposedHookLoadPackage,關(guān)于IXposedHookLoadPackage等接口,后面的文章會(huì)有說(shuō)明。

public class XposedInit implements IXposedHookLoadPackage {
    @Override
    public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam){
        //app啟動(dòng)時(shí)調(diào)用
    }
}

新建assets文件夾,文件夾下新建xposed_init文件,編輯文件,填寫XposedInit的完整包名:com.wrbug.xposeddemo.XposedInit
在XposedInit中handleLoadPackage方法會(huì)在應(yīng)用啟動(dòng)時(shí)調(diào)用。所以需要篩選需要hook的app的包名,這里選擇同個(gè)應(yīng)用:

    @Override
    public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam){
        if (lpparam.packageName.equals("com.wrbug.xposeddemo")) {
            
        }
    }

通過(guò)XposedHelpers的findAndHookMethod方法hook onCreate 方法,獲取到TextView實(shí)例,在方法執(zhí)行后通過(guò)setText設(shè)置方法。

public class XposedInit implements IXposedHookLoadPackage {
    @Override
    public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) {
        if (lpparam.packageName.equals("com.wrbug.xposeddemo")) {
            XposedHelpers.findAndHookMethod("com.wrbug.xposeddemo.MainActivity", lpparam.classLoader, "onCreate", Bundle.class, new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    //不能通過(guò)Class.forName()來(lái)獲取Class ,在跨應(yīng)用時(shí)會(huì)失效
                    Class c=lpparam.classLoader.loadClass("com.wrbug.xposeddemo.MainActivity");
                    Field field=c.getDeclaredField("textView");
                    field.setAccessible(true);
                    //param.thisObject 為執(zhí)行該方法的對(duì)象,在這里指MainActivity
                    TextView textView= (TextView) field.get(param.thisObject);
                    textView.setText("Hello Xposed");
                }
            });
        }
    }
}

除了上面通過(guò)反射的方法來(lái)獲取以外,還可以通過(guò)findViewById等方法獲取TextView對(duì)象,有興趣的可以思考下如果xml里面沒(méi)有設(shè)置TextView的ID,并且不是MainActivity的成員變量,該怎么獲取這個(gè)View,歡迎大家在下方進(jìn)行討論。安裝重啟模擬器后,打開app,這時(shí)textView將顯示Hello Xposed

后面的文章會(huì)講解具體的使用,歡迎大家關(guān)注
更多精彩文章請(qǐng)關(guān)注:http://www.mandroid.cn

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,716評(píng)論 25 709
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,022評(píng)論 4 61
  • 文/東成西九 || 東哥說(shuō)職場(chǎng) 今天是日更第97天 || 轉(zhuǎn)載請(qǐng)聯(lián)系作者,違者必究 現(xiàn)在生活中,上大學(xué)的時(shí)候應(yīng)該是...
    東成西九閱讀 4,476評(píng)論 4 36
  • 我就是個(gè)辦不好事情的傻瓜 說(shuō)話藝術(shù)
    云從足下生閱讀 218評(píng)論 0 0

友情鏈接更多精彩內(nèi)容