本文内容为xposed开发基础内容,可作为xposed开发基础学习。所述内容与源码仅限用于学习和研究目的。
关于android hook环境搭建,可参考网上的基础教程。
hook方法1
通过hook设置剪贴板内容的方法,打印栈,找调用方法。
public class HookMain implements IXposedHookLoadPackage {
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
if (loadPackageParam.packageName.equals("com.smile.gifmaker")){//只hook某手应用内的事件
XposedHelpers.findAndHookMethod(
"android.content.ClipboardManager",//包名+类名
loadPackageParam.classLoader,//一般固定
"setPrimaryClip",//方法名
ClipData.class,//参数类型
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
//super.afterHookedMethod(param);
new Exception().printStackTrace();
}
}
);
}
}
}
打开某手,点击分享-复制链接。查看logcat(warning):

可以看到,在 j.a.b.f.t 类下的a方法中调用了设置剪贴板内容的方法(setPrimaryClip)。用mt管理器打开这个方法所在smali,搜索行(19333180)定位。可以看到该a方法参数为CharSequence。可以通过简单分析smali代码或是转为java代码查看此方法逻辑,可以发现,此方法即将传入的 CharSequence 设置到剪贴板,所以此方法的参数即为我们需要改的东西。
接下来就是hook这个方法了,类路径:j.a.b.f.t,方法名:a,参数:CharSequence。关键代码如下:
public class HookMain implements IXposedHookLoadPackage {
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
if (loadPackageParam.packageName.equals("com.smile.gifmaker")){//只hook某手应用内的事件
XposedHelpers.findAndHookMethod(
"j.a.b.f.t",//包名+类名(类路径)
loadPackageParam.classLoader,
"a",//方法名
CharSequence.class,//参数类型
new XC_MethodHook() {
//在方法执行前,对参数进行值的修改
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
//super.beforeHookedMethod(param);
CharSequence charSequence = (CharSequence)param.args[0];
Log.i("xposedtest",charSequence.toString());
Matcher matcher = Patterns.WEB_URL.matcher(charSequence);
//正则匹配网址,如果找到则将原参数值更改为纯网址链接
if (matcher.find()){
String requestUrl = matcher.group();
CharSequence charSequence1 = requestUrl;
param.args[0] = charSequence1;
Log.i("xposedtest",requestUrl);
}
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
}
}
);
}
}
}
思路很简单,就是hook获取a方法参数,正则匹配网址url,更改方法参数的值为正则后的url。
hook方法2
为什么要用hook方法2呢?大家可以看到,方法1不是直接hook设置设置剪贴板内容的方法,而是调用其的方法,因正好发现这个方法的参数即为复制内容所以对其参数进行hook。那有什么问题呢?很明显可以看到代码是经过混淆的,所以就是不同的某手版本的那个方法不一定是我们找到的这个方法,也可能不存在。
所以更好的一种解决办法就是直接hook某手内所有设置剪贴板内容的方法setPrimaryClip,判断如何设置的剪贴板的内容存在url,直接修改为纯url。关键代码如下:
public class HookMain implements IXposedHookLoadPackage {
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
if (loadPackageParam.packageName.equals("com.smile.gifmaker")){//只hook快手应用内的事件
XposedHelpers.findAndHookMethod(
"android.content.ClipboardManager",//包名+类名(类路径)
loadPackageParam.classLoader,
"setPrimaryClip",//方法名
ClipData.class,//参数类型
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
//super.beforeHookedMethod(param);
ClipData clipData = (ClipData) param.args[0];
String text = clipData.getItemAt(0).getText().toString();
Matcher matcher = Patterns.WEB_URL.matcher(text);
if (matcher.find()){
String requestUrl = matcher.group();
clipData = ClipData.newPlainText("",requestUrl);
param.args[0] = clipData;
}
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
}
}
);
}
}
}
如上就是对某手应用内复制链接功能的hook,当然可以同理扩展到其他应用,也可以做一个可选应用的净化软件内复制链接的内容的xposed模块。当然这个复制是指软件本身内的某方法进行设置剪贴板内容,而不是手动调用系统的复制功能。
本人也是初学xposed开发,关于本文,如有更好的意见建议,欢迎评论交流。
发表评论