上篇文章仅仅做到自动查看联系人信息就结尾了,这第二篇是自动跳转验证申请页面。
上篇结尾自动搜索好友并跳转到资料信息页,本篇功能是在信息页展示后自动点击添加好友按钮并跳转到验证申请页面。
另需注意,因为误操作,手机微信版本升级到最新了,所以在此以微信7.0.3为例
严重声明 本文的意图只有一个就是通过分析app学习更多的逆向技术,如果有人利用本文知识和技术进行非法操作进行牟利,带来的任何法律责任都将由操作者本人承担,和本文作者无任何关系,最终还是希望大家能够秉着学习的心态阅读此文。
寻找点击事件
信息展示页是com.tencent.mm.plugin.profile.ui.ContactInfoUI,jadx打开并查找类ContactInfoUI,但代码中并找不到相关的点击跳转代码,所以换个思路。
点击添加好友按钮后跳转到验证申请页面SayHiWithSnsPermissionUI,直接搜索intent跳转中用到的 SayHiWithSnsPermissionUI.class
可以看到有三个方法使用到,简单查看后,进行简单hook
只有EF方法执行
打印如下:
2019-02-27 16:57:24.959 3772-3772/? I/Xposed: com.a85.wechatplugin:[16:57:24]: onClick——1contact_profile_add_contact
确定走的是com.tencent.mm.plugin.profile.a中的EF方法。参数打印是 contact_profile_add_contact
直接在EF方法中扔出异常:
findAndHookMethod("com.tencent.mm.plugin.profile.a", mlpparam.classLoader,
"EF", String.class,new XC_MethodHook() {
@Override
protected void beforeHookedMethod(final MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
log("onClick------1" + param.args[0]);
throw new NullPointerException();
}
});
查看日志:
很容易发现它的调用过程,先是一个item点击事件,然后回调给ContactInfoUI中a方法,最后调用到EF方法
1.item点击事件
首先看com.tencent.mm.ui.base.preference.MMPreference$2这个OnItemClickListener
主要是对adapter中item数据的判断处理
打印onItemClick方法中adapterView.getAdapter().getItem(i)的对象实例的class与mKey的值
indAndHookMethod("com.tencent.mm.ui.base.preference.MMPreference$2", mlpparam.classLoader,
"onItemClick", AdapterView.class, View.class, int.class, long.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(final MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Object preference= ((AdapterView)param.args[0]).getAdapter().getItem((int)param.args[2]);
log("onItemClick------" + preference.getClass().getSimpleName() + "=="+
XposedHelpers.findField(XposedHelpers.findClass("com.tencent.mm.ui.base.preference.Preference",mlpparam.classLoader),"mKey").get(preference)
);
}
});
log日志如下:
2019-03-01 14:05:06.815 5718-5718/? I/Xposed: com.a85.wechatplugin:[14:05:06]: onItemClick——ButtonPreference==contact_profile_add_contact
可以看到getItem的数据类是ButtonPreference,对于preference类的不同可以参考以下:
可以参考这个页面,不管加没加好友,联系人信息页面都是ContactInfoUI,顶部是一个头视图,下面的View是ListView,不过每个Item的Preference类不相同,发消息、音视频通话、添加好友都是ButtonPreference,朋友圈是SnsPreference,电话号码是PhoneNumPreference。
通过log数据,判断后只走了 MMPreference.this.mo15244a(MMPreference.this.xOS, preference); 这个就是回调的ContactInfoUI中的a方法
2.ContactInfoUI中a方法
根据之前打印的EF方法的参数是contact_profile_add_contact,所以preference.mKey=”contact_profile_add_contact”,而且上一步的打印结果preference的类是ButtonPreference,所以整个回调只会执行 this.oHt.mo15424EF(str); 这段代码,mo15424EF方法就是一开始找到的EF方法。
3.EF方法
大致浏览后EF方法是根据传过来的String来判断点击的是哪个按钮,是发消息按钮,还是查看朋友圈按钮,还是添加通讯录按钮
根据上一步的打印数据,EF方法的参数是contact_profile_add_contact,这部分代码如下。
可以看到代码量还是很多,简单分析主要是得到一些变量的获取与判断,然后设置好c41857a中的回调方法,mo12226a方法与mo12227vr方法,一个是不需要验证执行的方法,一个是需要验证执行的方法。
至此整个点击过程结束
其实到此我们已经能从这已有的三个方法来实现自动点击了。
Xposed编写实现
我们可以从ContactInfoUI中a方法的主要代码this.oHt.mo15424EF(str); 入手来实现自动点击,代码如下:
findAndHookMethod(ContactInfoUIClass,
"onCreate", Bundle.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(final MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (!isFromAddFriend) {
return;
}
try {
Object oHt = XposedHelpers.findField(ContactInfoUIClass, "oHt").get(param.thisObject);
XposedHelpers.callMethod(oHt, "EF", "contact_profile_add_contact");
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}, 1000);
}
});
我们在显示账号信息页面的时候自动执行this.oHt.mo15424EF(str); 这个方法
运行截图如下:
可以看到成功跳转到验证页面。
至此本文结束,其实一开始我是想要找到intent跳转的回调是哪一个发出的,但中间的分析实在是过于复杂,大致过程是点击后生成一个提示窗,然后生成一个请求,后台查询这个用户是不是需要验证,然后解析数据进行回调,然后取消弹窗,然后跳转到验证页或者直接加好友。涉及到十几个类的分析,我也一直在钻牛角尖,一直想找到网络请求生成这一部分的代码再自己xposed进行实现,导致找的头昏脑胀,但其实最简单的方式就是代码实现点击的方法,后续处理才会直接接连调用,不用自己去构造那些过于复杂的方法和变量。
至此自动添加好友的功能只差最后一步发送验证了,下篇再做分析实现吧。
因为本文以微信7.0.3分析,部分代码和上篇不同,所以在GitHub给出完整代码
https://github.com/hjw45611/WechatPlugin/blob/master/WXMain.java