一、环境说明
已经安装xposed Installer的雷电安卓7.1虚拟机
开发环境Android Studio Koala Feature Drop | 2024.1.2
库版本 XposedBridgeApi-89.jar
库下载地址:网盘地址:https://pan.baidu.com/s/1ZgzC4ktrFe1DhDi8w9WroA?pwd=jloj
二、开发流程
1、新建一个Empty Activity项目
包名输入com.example.xposedtest
2、新建目录lib
3、将XposedBridgeApi-89.jar拷贝到lib目录下,使用Ctrl+V命令,然后点击Add As Library
4、修改AndroidManifest.xml,添加meta-data字段
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.XposedTest"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<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="beefreesky test module" />
<meta-data
android:name="xposedminversion"
android:value="89" />
</application>
5、在MainActivity.java中添加一个按钮,点击后弹出“我没有被劫持”消息。
public class MainActivity extends AppCompatActivity {
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, getMessageString(), Toast.LENGTH_SHORT).show();
}
});
}
private String getMessageString()
{
return "我没有被劫持";
}
}
6、新建Java类:HookDemo
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodReplacement;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
public class HookDemo implements IXposedHookLoadPackage{
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
XposedBridge.log("Hook到包=============================== " + loadPackageParam.packageName);
//Log.d("Hook到包============ ", "==================================" );
if (loadPackageParam.packageName.equals("com.example.xposedtest")) {
XposedBridge.log("Hook到包 " + loadPackageParam.packageName);
Class clazz = loadPackageParam.classLoader.loadClass("com.example.xposedtest.MainActivity");
/* XposedHelpers.findAndHookMethod(clazz, "getMessageString", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
XposedBridge.log("Hook到包 " + loadPackageParam.packageName + "======beforeHookedMethod");
super.beforeHookedMethod(param);
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
XposedBridge.log("Hook到包 " + loadPackageParam.packageName + "========afterHookedMethod");
param.setResult("你已被劫持");
}
});
*/
// /*
XposedHelpers.findAndHookMethod(clazz, "getMessageString", new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
return "你已被劫持!!!!!!";
}
});
// */
}
}
}
实现IXposedHookLoadPackage接口,重载handleLoadPackage方法,实例中用到了两种方法,一种是在调用原来的方法前、后增加自己的代码,另一种是替换原来的方法。
7、新建assets文件夹
在assets文件夹下新建文件xposed_init,输入com.example.xposedtest.HookDemo。必须是包名+自己编写的Hook代码类的类目,注意大小写要一致
8、编译,到虚拟机运行,发现增加了XposedTest模块
打钩后重启,就会实现HOOK了
查看日志
三、注意的问题
本人第一次编译运行时,一致未能HOOK成功。发现需要调整build.gradle.kts
dependencies {
implementation(libs.appcompat)
implementation(libs.material)
//implementation(files("lib\\XposedBridgeAPI-89.jar"))
compileOnly(files("lib\\XposedBridgeAPI-89.jar"))
implementation(libs.activity)
implementation(libs.constraintlayout)
testImplementation(libs.junit)
androidTestImplementation(libs.ext.junit)
androidTestImplementation(libs.espresso.core)
}
将implementation改为compileOnly,就OK了
complieonly 和implement的区别
compileOnly和implementation是Gradle构建系统中的两种依赖配置方式,它们的主要区别在于依赖的可见性和作用范围。
compileOnly:这种依赖类型仅参与编译过程,但不参与打包。这意味着,如果一个项目依赖了某个compileOnly的库,那么在编译时这个库是必须的,以确保代码能够成功编译。然而,在打包时,这个库不会被包含在内,因此,如果其他模块或工程没有显式地添加这个库作为依赖,那么在运行时就会出现问题,因为运行时找不到这个库。此外,compileOnly依赖的库对其他模块是不可见的,即它们不会泄露给其他模块。
implementation:与compileOnly不同,implementation依赖的库不仅参与编译,还参与打包。这意味着,当项目依赖了一个implementation的库时,这个库不仅在编译时可用,而且在运行时也是必须的。换句话说,如果一个项目使用了implementation依赖的库中的类或方法,那么这些类或方法必须被包含在最终打包的文件中。此外,implementation依赖的库对其他模块是可见的,即它们会被泄露给其他模块。
总的来说,compileOnly和implementation的主要区别在于依赖的可见性、作用范围以及是否参与打包。compileOnly主要用于确保编译时的正确性,而implementation则确保了运行时和其他模块间的正确交互