第一次使用Xposed框架, 知道作怎麼用, 就不知道怎麼作,來看看
javascript
---------------------------------------------------------
php
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
開發Xposed框架模塊, 固然用Android Studio 工具開發了, 先建一個app項目,筆者項目名XposedDemo, 將下載的jar包複製到libs目錄下, 而後,選擇libs文件夾,鼠標右鍵選 Add to libs ...便可被引用. 以下圖
bash
接着,建一個類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檢測到的模塊, 如圖:
順利的話, 效果不錯, 如圖:
筆者只是作個筆記總結, 不作多解釋, 這裏告一段落了, 如還有不明白的地方,建議看下筆者參考來源吧,
最後貼上參考文獻來源: