第一次使用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检测到的模块, 如图:
顺利的话, 效果不错, 如图:
笔者只是作个笔记总结, 不作多解释, 这里告一段落了, 如还有不明白的地方,建议看下笔者参考来源吧,
最后贴上参考文献来源: