本人結合網絡上的種種教程以及自己實踐,記錄下一個完整的基本Xposed模塊項目的創建過程。
開發環境:
- Mac系統
- AndroidStudio 3.2.1
- gradle 3.2.1
- VirtualXposed(無需Root的使用Xposed模塊)
Xposed、相關網站
- Xposed官方網站:https://api.xposed.info/reference/packages.html
- Xposed Github網址:https://github.com/rovo89/Xposed
- VirtualXposed官方網站:https://vxposed.com/
- VirtualXposed Github網址:https://github.com/android-hacker/VirtualXposed
參考鏈接:
1、下載相關文件
官網下載鏈接:https://jcenter.bintray.com/de/robv/android/xposed/api/
由此鏈接進入,並下載以下兩個文件
2、創建基礎項目和環境搭建
2.1、使用AndroidStudio構建一個基礎項目,Android開發的基礎操作,這里略過。
2.2、添加引用
在Module的build.gradle中添加以下兩句引用,並注意要將 implementation fileTree(dir: 'libs', include: ['*.jar']) 修改為 compileOnly fileTree(dir: 'libs', include: ['*.jar']) 。
原因是Xposed里已有該JAR包內容,再次打包進去會沖突,就會導致handleLoadPackage沒有回調。
dependencies { //以下兩句引用 //provided 有錯就替換為 compileOnly compileOnly 'de.robv.android.xposed:api:82' //如果需要引入文檔,方便查看的話 compileOnly 'de.robv.android.xposed:api:82:sources' compileOnly fileTree(dir: 'libs', include: ['*.jar']) 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' }
單獨列出來,gradle版本不同,就使用 provided或者 compileOnly,implementation、api、compileOnly區別詳解可以參考鏈接 https://blog.csdn.net/yuzhiqiang_1993/article/details/78366985?locationNum=6&fps=1
compileOnly 'de.robv.android.xposed:api:82' //如果需要引入文檔,方便查看的話 compileOnly 'de.robv.android.xposed:api:82:sources'
2.3、聲明Xposed模塊
創建Xposed項目后,需要還在AndroidMenafest.xml文件里面聲明Xposed模塊,在application里面添加三個meta-data標簽(xposedmodule,xposeddescription,xposedminversion)。
- xposedmodule:表示作為Xposed的一個模塊
- xposeddescription:表示對本模塊的描述,該描述會顯示在安裝好后的程序名稱下方
- xposedminversion:表示的jar包的最低版本號
<meta-data android:name="xposedmodule" android:value="true"/> <meta-data android:name="xposeddescription" android:value="我就是個簡單的Xposed Demo"/> <meta-data android:name="xposedminversion" android:value="53"/>
如圖:

2.4、添加測試功能
在MainActivity視圖中添加一個測試Button,點擊后Toast提示

MainActivity中的邏輯代碼如下:
//將被hook的類 public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //點擊測試事件 findViewById(R.id.btn_test).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this, saySomething(), Toast.LENGTH_SHORT).show(); } }); } //將被hook的方法 public String saySomething(){ return "我是一個好人"; } }
完整功能就是,點擊按鈕,Toast提示“我是一個好人”,提示內容由 saySomething()提供。
2.5、創建掛鈎類
接下來,就是編寫xposed模塊,hook這里的MainActivity,並修改 saySomething()方法的返回值為“我是一個壞人”。
新建一個類Test,實現 IXposedHookLoadPackage接口,重寫 handleLoadPackage方法,先篩選到我們本程序的包名,然后用XposedHelpers里的 findAndHookMethod方法對MainActivity中的 saySomething方法進行劫持。
public class Test implements IXposedHookLoadPackage { @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable { //判斷包名 if (lpparam.packageName.equals("com.example.leaf.testvpdemo")) { Class clazz = lpparam.classLoader.loadClass("com.example.leaf.testvpdemo.MainActivity"); //hook saySomething()方法 XposedHelpers.findAndHookMethod(clazz, "saySomething", new XC_MethodHook() { protected void beforeHookedMethod(MethodHookParam param) throws Throwable { super.beforeHookedMethod(param); } protected void afterHookedMethod(MethodHookParam param) { param.setResult("我是一個壞人!"); } }); } } }
2.5、聲明類的入口
創建完我們鈎類之后,我們需要將該類加載到XposedInstaller中,也就是我們必須聲明該類的位置,需要在xposed_init中聲明。
先創建assets文件

然后在assets文件里,新建一個文件名為“xposed_init”(文件類型選text),注意沒有后綴

然后在 xposed_init 內寫入剛創建的入口類的完整類名,這里是 com.example.leaf.testvpdemo.Test

到此為止,完整的基本項目就完成了。
3、運行測試Xposed模塊
如果直接運行,然后在 VirtualXposed中打開該應用,會發現報錯,錯誤日志如下:
E/Xposed: java.lang.ClassNotFoundException: Didn't find class "com.example.leaf.testvpdemo.Test" on path: DexPathList
請確保禁用 Instant Run,否則hook的類不會直接包含在APK中,導致HOOK失敗!

禁用后,重新運行項目,並在“添加應用”將應用添加到 VirtualXposed內,再在“模塊管理”中,將模塊開啟,記得開啟模塊后要對 VirtualXposed進行重啟。


最后的效果如下:


