吾爱破解 - LCG - LSG |安卓破解|病毒分析|破解软件|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

领取今日签到奖励
查看: 20634|回复: 264
上一主题 下一主题

[Android 原创] Xposed-微信自动加好友功能实现

    [复制链接]
跳转到指定楼层
楼主
发表于 2019-2-18 22:58 回帖奖励
本帖最后由 hjw45611 于 2019-3-14 15:23 编辑
严重声明
本文的意图只有一个就是通过分析app学习更多的逆向技术,如果有人利用本文知识和技术进行非法操作进行牟利,带来的任何法律责任都将由操作者本人承担,和本文作者无任何关系,最终还是希望大家能够秉着学习的心态阅读此文。

前两天有人想让我做一个微信自动加好友的功能,今天就想试一试。
微信6.6.7版本为例,手机root与Xposed框架安装本文不做讨论,如有需要查看论坛内其他帖子,本文只用于Xposed模块编写。


经坛友提醒,使用文本存储手机号,在进行读取for循环添加时,10个以上的时候就会产生操作过于频繁的提醒,而且这个提醒大概一个小时才能解除。
经过优化后,增加了线程的sleep时间,可实现自动循环查看好友信息,但在运行到25个左右时也会触发操作过于频繁的提醒。
并且如果加好友的功能也增加上的话,也会由于加好友频繁而被限制,所以最好是通过ContentProvider把大量手机号批量写入到手机通讯录数据库中,然后使用微信的添加通讯录好友的方式来添加好友,但有网友反应可用,也有网友反应加的多了收不到验证信息,我也并未实验, 以下分析流程就仅做参考吧。

至今(2019-03-14)微信自动加好友的分析已经完成,主要分三步
1.查找好友(本文)
2.自动点击添加好友按钮进入验证页面
https://www.52pojie.cn/thread-886190-1-1.html
3.自动发送验证信息
https://www.52pojie.cn/thread-897346-1-1.html
希望喜欢Xposed的朋友能交流学习,从中获益。

1.首先查看微信加好友的页面
是FTSAddFriendUI这个Activity。
2.使用jadx打开app,查找FTSAddFriendUI
3.寻找突破点

大体浏览后没有类似EditView的实例对象,但发现一个内部类FTSAddFriendUI$5

-1通过简单分析,确定这个内部类是搜索好友后的结果显示
成功的话就intent跳转,失败的话就显示该用户不存在等错误信息
-2直接查找它的使用
是CM方法使用到它了,分析可得这个方法的参数就是输入框的字符串,字符串不为空后进行查询,并显示一个正在查询的Dialog,有结果后回调OnCancelListener,并且触发内部类FTSAddFriendUI$5中的结果显示方法。

Hook CM方法,打印string参数,发现就是输入框的文本数据,确认CM方法就是要找的方法
-3xposed直接使用
[Java] 纯文本查看 复制代码
final Class FTSAddFriendUIClass=loadPackageParam.classLoader.loadClass("com.tencent.mm.plugin.fts.ui.FTSAddFriendUI");
                     findAndHookMethod(FTSAddFriendUIClass,
                            "onCreate",Bundle.class,
                            new XC_MethodHook() {
                                @Override
                                protected void afterHookedMethod(final MethodHookParam param) throws Throwable {
                                    super.afterHookedMethod(param);
                                   new Handler().postDelayed(new Runnable() {
                                       @Override
                                       public void run() {
                                           XposedHelpers.callMethod(param.thisObject,"CM","微信号/QQ号/手机号");
                                       }
                                   },1000);
                                }
                            });



-4解决问题
结果可以看到只有dialog,dialog结束后并没有反应,但dialog能显示说明代码执行了,那就来看一下FTSAddFriendUI$5这个结果处理类里的方法有没有执行吧。
[Java] 纯文本查看 复制代码
findAndHookMethod("com.tencent.mm.plugin.fts.ui.FTSAddFriendUI$5",loadPackageParam.classLoader,
       "a",int .class, int .class,String.class,XposedHelpers.findClass("com.tencent.mm.ab.l",loadPackageParam.classLoader) ,
       new XC_MethodHook() {
           @Override
           protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
               super.beforeHookedMethod(param);

               log("FTSAddFriendUI$5--0="+param.args[0]+"=1="+param.args[1]+
                       "=2="+param.args[2]);
           }
           
       });

打印结果如下:
2019-02-18 17:55:19.347 3872-3872/? I/Xposed: [17:55:19]:  FTSAddFriendUI$5--0=0=1=0=2=Everything is OK
搜索结果处理的方法执行了,说明问题不在CM方法,而是在处理方法中因为某个问题而停止了。
那就来分析一下这个a方法里的哪段代码是有问题的吧。a方法完整代码如下,
[Java] 纯文本查看 复制代码
 public final void mo2331a(int i, int i2, String str, C0879l c0879l) {
            C1261g.m2963DF().mo8629b(106, (C0874e) this);
            FTSAddFriendUI.this.aQA();
            if (i == 0 && i2 == 0) {
                FTSAddFriendUI.this.iJw = ((C9339f) c0879l).bcS();
                if (FTSAddFriendUI.this.iJw.rHb > 0) {
                    if (FTSAddFriendUI.this.iJw.rHc.isEmpty()) {
                        C35785h.m67602a(FTSAddFriendUI.this, C8733g.search_contact_not_found, 0, true, null);
                        return;
                    }
                    Intent intent = new Intent();
                    intent.putExtra("add_more_friend_search_scene", 3);
                    if (FTSAddFriendUI.this.iJw.rHc.size() > 1) {
                        try {
                            intent.putExtra("result", FTSAddFriendUI.this.iJw.toByteArray());
                            C36379d.m70344b(FTSAddFriendUI.this.mController.tml, "subapp", ".ui.pluginapp.ContactSearchResultUI", intent);
                            return;
                        } catch (Throwable e) {
                            C3327x.printErrStackTrace("MicroMsg.FTS.FTSAddFriendUI", e, "", new Object[0]);
                            return;
                        }
                    }
                    ((C33521h) C1261g.m2977l(C33521h.class)).mo24028a(intent, (biy) FTSAddFriendUI.this.iJw.rHc.getFirst(), FTSAddFriendUI.this.jvZ);
                }
                FTSAddFriendUI.this.jvX = 1;
                FTSAddFriendUI.m48692g(FTSAddFriendUI.this);
            } else {
                switch (i2) {
                    case DownloadResult.CODE_CONNECTION_EXCEPTION /*-24*/:
                        C29477a eV = C29477a.m50825eV(str);
                        if (eV == null) {
                            FTSAddFriendUI.this.jvQ.setText(C8733g.no_contact_result);
                            break;
                        } else {
                            FTSAddFriendUI.this.jvQ.setText(eV.desc);
                            break;
                        }
                    case -4:
                        if (i != 4) {
                            FTSAddFriendUI.this.jvQ.setText(FTSAddFriendUI.this.getString(C8733g.search_contact_err_no_code));
                            break;
                        }
                    default:
                        FTSAddFriendUI.this.jvQ.setText(C8733g.no_contact_result);
                        break;
                }
                FTSAddFriendUI.this.jvX = -1;
                FTSAddFriendUI.this.jvY = 1;
            }
            FTSAddFriendUI.m48693h(FTSAddFriendUI.this);
        }

因为上面打印log时前两个参数都是0,所以精简后如下
[Java] 纯文本查看 复制代码
 public final void mo2331a(int i, int i2, String str, C0879l c0879l) {
            C1261g.m2963DF().mo8629b(106, (C0874e) this);
            FTSAddFriendUI.this.aQA();
            if (i == 0 && i2 == 0) {
                FTSAddFriendUI.this.iJw = ((C9339f) c0879l).bcS();
                if (FTSAddFriendUI.this.iJw.rHb > 0) {
                    if (FTSAddFriendUI.this.iJw.rHc.isEmpty()) {
                        C35785h.m67602a(FTSAddFriendUI.this, C8733g.search_contact_not_found, 0, true, null);
                        return;
                    }
                    Intent intent = new Intent();
                    intent.putExtra("add_more_friend_search_scene", 3);
                    if (FTSAddFriendUI.this.iJw.rHc.size() > 1) {
                        try {
                            intent.putExtra("result", FTSAddFriendUI.this.iJw.toByteArray());
                            C36379d.m70344b(FTSAddFriendUI.this.mController.tml, "subapp", ".ui.pluginapp.ContactSearchResultUI", intent);
                            return;
                        } catch (Throwable e) {
                            C3327x.printErrStackTrace("MicroMsg.FTS.FTSAddFriendUI", e, "", new Object[0]);
                            return;
                        }
                    }
                    ((C33521h) C1261g.m2977l(C33521h.class)).mo24028a(intent, (biy) FTSAddFriendUI.this.iJw.rHc.getFirst(), FTSAddFriendUI.this.jvZ);
                }
                FTSAddFriendUI.this.jvX = 1;
                FTSAddFriendUI.m48692g(FTSAddFriendUI.this);
            } 
            FTSAddFriendUI.m48693h(FTSAddFriendUI.this);
        }

前面代码分析后无问题,但 if (FTSAddFriendUI.this.iJw.rHb > 0) 判断时不知rHb的值,此处需要hook一下。
[Java] 纯文本查看 复制代码
findAndHookMethod("com.tencent.mm.plugin.fts.ui.FTSAddFriendUI$5",loadPackageParam.classLoader,
                            "a",int .class, int .class,String.class,XposedHelpers.findClass("com.tencent.mm.ab.l",loadPackageParam.classLoader) ,
                            new XC_MethodHook() {
                                @Override
                                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                                    super.beforeHookedMethod(param);
                                    log("FTSAddFriendUI$5--0="+param.args[0]+"=1="+param.args[1]+
                                            "=2="+param.args[2]+                                    "=rHb="+XposedHelpers.findField(XposedHelpers.findClass("com.tencent.mm.protocal.c.bja",loadPackageParam.classLoader),"rHb").get(XposedHelpers.callMethod((param.args[3]),"bcS"))
                                    );
                                }

打印得知rHb=0,所以不会走if语句内的代码,只有两个方法m48692g与m48693h有可能有问题,按顺序检查参数

最终发现是这两个方法中使用了FTSAddFriendUI的变量bWm,而在输入框使用addTextChangedListener进行绑定后,bWm存储了输入的字符串,所以如果直接调用CM方法的话,导致bWm变量为空,所以解决方法如下:

[Java] 纯文本查看 复制代码
final Class FTSAddFriendUIClass=loadPackageParam.classLoader.loadClass("com.tencent.mm.plugin.fts.ui.FTSAddFriendUI");
                     findAndHookMethod(FTSAddFriendUIClass,
                            "onCreate",Bundle.class,
                            new XC_MethodHook() {
                                @Override
                                protected void afterHookedMethod(final MethodHookParam param) throws Throwable {
                                    super.afterHookedMethod(param);
                                   new Handler().postDelayed(new Runnable() {
                                       @Override
                                       public void run() {
                                           XposedHelpers.setObjectField(param.thisObject,"bWm","微信号/QQ号/手机号");
                                           XposedHelpers.callMethod(param.thisObject,"CM","微信号/QQ号/手机号");
                                       }
                                   },1000);
                                }
                            });


可以看到进入加好友界面后不需要输入,直接进入好友详情界面。

当然如果输入数据搜索不到好友,结果处理方法的参数是
2019-02-18 17:58:34.082 3872-3872/? I/Xposed: [17:58:34]:  FTSAddFriendUI$5--0=4=1=-4=2=User do not exist


点评

有点意思啊  发表于 2019-3-11 15:50
谢谢分享。  发表于 2019-2-24 11:56
我前几个月也研究过自动加人,用的是appium,但是基本不可能"实用化",因为一个微信号一天只能加20个人左右,然后就有会各种验证,各种限制,而且不一定是20个,会有IP、机型、频率等验证。所以只能用于dome演示   发表于 2019-2-19 14:15

免费评分

参与人数 49吾爱币 +42 热心值 +44 收起 理由
anmin_you + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
俗子 + 1 热心回复!
52Sql1920 + 1 + 1 我很赞同!
52pj8089 + 1 + 1 我很赞同!
一切为装逼 + 1 + 1 谢谢@Thanks!
高高再高点 + 1 + 1 我很赞同!
woaiwutian + 1 谢谢@Thanks!
zwtrees + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
lnylny321 + 1 我很赞同!
小屌丝 + 1 感谢您的宝贵建议,我们会努力争取做得更好!
gbp19821010 + 1 + 1 我很赞同!
放人的羊 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
冰吻啊 + 1 用心讨论,共获提升!
1732501894 + 1 我上次给出的通讯录好友思路看来管用哈
Big0g0 + 1 + 1 我很赞同!
Kevinz + 1 + 1 主动触发下一步动作的执行大楷分为哪几类方式呢? 求指导一下,谢谢
sbgyth + 1 + 1 我很赞同!
GOESD + 1 + 1 谢谢@Thanks!
mengsiyiren + 1 + 1 我很赞同!
crazygunbond + 1 + 1 我很赞同!
阿甘兔否 + 1 + 1 热心回复!
zhg52011 + 1 + 1 我很赞同!
zxl往事如昔 + 1 + 1 用心讨论,共获提升!
刘杠杠 + 1 聊天中定向自动转发消息怎么用模块?原来的自动转发已经不更新了,老微信不.
vince991 + 1 + 1 我很赞同!
Mr.wens + 1 我很赞同!
a15233511642 + 1 + 1 我很赞同!
等一个束岳潮生 + 1 + 1 我很赞同!
没事到处逛 + 1 + 1 我很赞同!
wangfengha + 1 + 1 我很赞同!
carl_zhang + 1 + 1 热心回复!
ken1qq + 1 + 1 用心讨论,共获提升!
laughingsir38 + 1 + 1 热心回复!
月还哎 + 1 谢谢@Thanks!
362238000 + 1 + 1 热心回复!
小红帽的帽子 + 1 + 1 我很赞同!
古垛村丶 + 1 + 1 谢谢@Thanks!
魔术师_ + 1 + 1 谢谢@Thanks!
LvMou + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
machunx + 1 + 1 谢谢@Thanks!
独行风云 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
wahson + 1 + 1 谢谢@Thanks!
etkane + 1 + 1 功能很好,等待成品~~
kitt-xf + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
狐狼 + 1 + 1 用心讨论,共获提升!
aipanpann + 1 + 1 热心回复!
qwe694698196 + 1 + 1 用心讨论,共获提升!
shaojingtao + 1 用心讨论,共获提升!
anfu092 + 1 + 1 热心回复!

查看全部评分

本帖被以下淘专辑推荐:

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

推荐
 楼主| 发表于 2019-2-19 09:41 |楼主
s87386696 发表于 2019-2-18 23:43
看不太懂,这个用途是批量加好友还是批量查看好友信息用的。

这个功能是自动查看好友信息,是最基础的功能,在此基础上拓展的话,很容易就能做一个批量查看好友信息或者批量加好友的功能。
例如在下载一个上万手机号的文本存放在手机上,打开加好友界面后,自动读取文本,生成for循环,很容易就可以筛选出哪些手机号是有微信号的,对于使用微信营销的人来说省略了一步步输入,搜索好友的繁琐步骤。
3#
发表于 2019-2-18 23:27
4#
发表于 2019-2-18 23:42 来自手机
5#
发表于 2019-2-18 23:43
看不太懂,这个用途是批量加好友还是批量查看好友信息用的。
6#
发表于 2019-2-19 00:11
Mark下留着
7#
发表于 2019-2-19 03:27
学习! 收藏了  多发布
8#
发表于 2019-2-19 08:41
大侠。厉害,学习
9#
发表于 2019-2-19 08:43
谢谢分享
10#
发表于 2019-2-19 08:52
欢迎分析讨论交流,吾爱破解论坛有你更精彩!
11#
发表于 2019-2-19 08:59
看不懂,我还是 慢慢学吧
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则


免责声明:
吾爱破解所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。

Mail To:Service@52PoJie.Cn

快速回复 收藏帖子 返回列表 搜索

RSS订阅|手机版|小黑屋|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2019-3-20 15:16

Powered by Discuz!

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表