第一次使用Xposed框架

引言: 

第一次使用Xposed框架, 知道作怎麼用, 就不知道怎麼作,來看看
javascript

  1. 首先給機器安裝框架app

  2. 開發框架模塊須要導入jar

  3. 測試體驗

  4. 總結

---------------------------------------------------------
php

一,首先給機器安裝框架app 

Xposed Installer,因爲Android 5.0以上採用ART,而5.0如下默認採用Dalvik, 因此是有兩個版本的Xposed,附上下載連接:
html

Android 4.0.3-4.4: repo.xposed.info/module/de.r…java

Android 5.0以上:forum.xda-developers.com/showthread.…android

筆者下載的是XposedInstaller_3.1.5.apk, app能夠安裝在機器上,打開以下圖, 若是提示未激活就先安裝, 安裝須要機器系統已root, 安裝重啓機器就能夠了npm

注: 機器能夠是真機, 或者電腦上安裝個模擬器 (筆者用的是夜神模擬器)
api

二, 開發框架模塊須要導入jar

開發Xposed框架模塊, 固然用Android Studio 工具開發了, 先建一個app項目,筆者項目名XposedDemo, 將下載的jar包複製到libs目錄下, 而後,選擇libs文件夾,鼠標右鍵選 Add to libs ...便可被引用. 以下圖
bash

XposedBridge.jar下載jcenter.bintray.com/de/robv/and…


接着,建一個類XposedHookUtil , 使用接口, 以下圖,不報錯就能夠
app

public class XposedHookUtil implements IXposedHookLoadPackage {
    public static final String PACKAGE_NAME = "com.example.xposeddemo";
    public static final String CLASS_NAME_MAINACTIVITY = "com.example.xposeddemo.MainActivity";
    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
        String packgageName = loadPackageParam.packageName;
        //過濾包, 這麼作,在當前的包下hook對就不會報錯了
        if (!PACKAGE_NAME.equals(packgageName)) {
            if (packgageName.contains("com.example.xposeddemo")){
                XposedHelpers.findAndHookMethod(CLASS_NAME_MAINACTIVITY,
                    loadPackageParam.classLoader, "getTTAd", new XC_MethodReplacement() {
                        @Override
                        protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
                            //return null;
                            return "廣告被攔截了";
                        }
                    });
                //hook全部方法, 按需使用
                XposedHelpers.findAndHookMethod(Application.class, "attach", Context.class,
                    new XC_MethodHook() {
                        @Override
                        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                            ClassLoader cl = ((Context) param.args[0]).getClassLoader();
                            Class<?> clazz = null;
                            try{
                                clazz = cl.loadClass(CLASS_NAME_MAINACTIVITY);
                            }catch (Exception e){
                                Log.e("TAG >>>>>____1___>>>>>>", "find class is fail : msg:"+e.getMessage());
                            }
                            if (clazz != null){
                                XposedHelpers.findAndHookMethod(clazz, testMethod, new XC_MethodHook() {
                                    @Override
                                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                                        Log.e("TAG >>>>>___2____>>>>>>", testMethod+" method result : "+param.toString());
                                        if (param.getResult() != null){
                                            Set set = (Set) param.getResult();
                                            Log.e("TAG >>>> return res", " ------------------ set size:"+set.size());
                                            Iterator<Object> it = set.iterator();
                                            int i = 1;
                                            while (it.hasNext()){
                                                Object o = it.next();
                                                Log.e("TAG >>> ret listitem", (i++) +". next "+o.toString());
                                                //反射獲取對象中特定屬性的值
                                                Class clazz = o.getClass();
                                                Field[] fields = clazz.getFields();//getDeclaredFields();
                                                for (Field f : fields){
                                                    String cName = f.getName();
                                                    //boolean hasJsonProperty = f.isAnnotationPresent();
                                                    Object obj = f.get(o);
                                                    if (obj instanceof Long) {
                                                        Log.e("TAG >> listi", "attr name:"+cName+", long value:"+((long)obj));
                                                    } else if (obj instanceof String) {
                                                        Log.e("TAG >> listi", "attr name:"+cName+", String value:"+obj);
                                                    } else if (obj instanceof Integer) {
                                                        Log.e("TAG >> listi", "attr name:"+cName+", int value:"+((int)obj));
                                                    } else {
                                                        Log.e("TAG >> listi", "attr name:"+cName+", not know class of value");
                                                    }
                                                }
                                            }
                                        }
                                        super.afterHookedMethod(param);
                                    }
                                });
                            }
                            Log.e("TAG >>>>>____1___>>>>>>", "method result : "+param.getResult());
                            super.afterHookedMethod(param);
                        }
                    });
                    Log.i("TAG >>>", "-END-");
               }
        }else{
            Log.e("TAG E >>>", " 經過包"+packgageName);
        }

    }
}
複製代碼

還有MainActivity類, 貼上源碼, 就不作解釋了,還有頁面佈局,大體能夠看出來框架

public class MainActivity extends AppCompatActivity {
    private TextView tv_ad;
    private Button btn_load_ad;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv_ad = findViewById(R.id.tv_ad);
        btn_load_ad = findViewById(R.id.btn_load_ad);
        btn_load_ad.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                tv_ad.setText(getTTAd());
            }
        });
    }
    public String getTTAd(){
        Log.e("+++++++>>>>>> TAG I", "MainActivity getTTAd()");
        return "廣告加載成功";
    }
}複製代碼

接着,改下AndroidManifest.xml這個文件, 樣子以下,只是添加了meta-data部分,這個等安裝後, 信息xposeddescription是能夠在Xposed框架app上的模塊中看到

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.xposeddemo">
    <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">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>


        <meta-data android:name="xposedmodule" android:value="true" />
        <meta-data android:name="xposeddescription" android:value="test xposed module" />
        <meta-data android:name="xposedminversion" android:value="54+" />

    </application>
</manifest>複製代碼

接着,在文件夾asserts中建立一個文本文件名爲xposed_init, 注意不能帶.txt, 內容就是剛剛寫好的XposedHookUtril類名,前面加上應用包名

com.example.xposeddemo.XposedHookUtil複製代碼

最後,打包安裝前,肯定一下, 須要改Module下的app的build.gradle文件,以下圖

改動後內容是這樣子的,就是其中compileOnly被替換了

dependencies {
    compileOnly fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    compileOnly files('libs/api-82.jar')
}複製代碼


三,測試體驗

每次修改模塊app安裝使用都須要重啓機器, 選擇 軟重啓 就能夠, 這樣就不會中斷調試日誌輸出.

可被Xposed框架app檢測到的模塊, 如圖:

順利的話, 效果不錯, 如圖:


四,總結

筆者只是作個筆記總結, 不作多解釋, 這裏告一段落了, 如還有不明白的地方,建議看下筆者參考來源吧,

最後貼上參考文獻來源:

  • Xposed真的能夠隨心所欲 點我
  • Xposed教程,含jar下載地址 點我
  • Xposed框架的使用--簡單入門  點我
  • Xposed模塊編寫遇到的一些問題以及解決 點我
  • 整理Android XposedHook使用問題 點我
  • 反射獲取對象中特定屬性的值 點我
  • Xposed使用教程 點我
  • Xposed經常使用方法使用詳解 點我
相關文章
相關標籤/搜索