谁偷偷删了你的微信?别慌!Python 帮你都揪出来了!

微信HOOK+协议 协同开发 微信直播 视频号场控 开发过程不是很顺利,以往都是直接使用HOOK接口来进行功能操作,这是首次使用HOOK组包,所以绕了很多弯路,其接口本身的使用,也是比较稍复杂。因此需要通过PB组协议包,然后利用PC的HOOK接口,进行执行。在朋友给了一部分c#代码参考后,我开始了场控软件的开发。和朋友聊了一下,主要功能是通过PC微信的接口实现的。开发了半月左右,才将理想中的场控工具开发出。有学习交流的需求,可以点击我的头像查看简介。近期,很多微信直播场控的功能软件出现。目前各种功能测试也是达到了理想的效果。但是部分功能是PC接口没有的。 阅读详情


1

目 标 场 景

不知道你有没有经历过,想联系一位很长时间没有联系的朋友,发现对方很早以前已经把你删除了,而你还一无所知。

Python资源共享群:484031800

相信每个人的微信通信录里都存在一些 「僵尸粉」 ,他们默默地躺在联系人列表中,你以为对方还是朋友,那就真是太年轻、太天真的;实际上,对方早就把从好友列表中删了,那如何来筛选出这群人呢?

网上的很大量检测僵尸粉的工具,检测的时候会给微信通信录内的每一个好友发送一条检测信息,严重 「打扰」到对方 ; 另外一部分软件在检测的时候,会植入一些代码病毒,暗箱操作显得很不安全。

 

 

 

本篇文章的目的是自动化操作微信 App,通过 「模拟给好友转账」 来筛选出所有的僵尸粉,并一键删除它们。

2

准 备 工 作

在开始编写脚本之前,需要做好如下准备工作

一部 Root 后的 Android 手机或者模拟器,如果没有 Root 的设备,推荐使用网易 MuMu 模拟器

Android 开发环境、Android Studio

sqlcipher 图形化工具

自动化工具:Python 虚拟环境下安装 pocoui

3

编 写 脚 本

整个操作分为 3 步骤,分别是破解微信数据库筛选出通信录中的好友、模拟给好友转账得到僵尸粉数据、删除所有僵尸粉。

第 1 步,我们需要破解微信 App 的数据库。

ps: 这里只是简单的说一下破解流程,想一键破解微信通信录数据,可以跳过这一步,直接使用文末提供的 APK。

首先,我们使用 Android Studio 新建一个项目,在项目初始化的时候, 授予应用管理员权限以及修改微信目录的读写权限。

//微信 App 的目录

public static final String WX_ROOT_PATH = "/data/data/com.tencent.mm/";

/**

* 执行linux指令

*

* @param paramString

*/

public static void execRootCmd(String paramString)

{

    try

    {

        Process localProcess = Runtime.getRuntime().exec("su");

        Object localObject = localProcess.getOutputStream();

        DataOutputStream localDataOutputStream = new DataOutputStream((OutputStream) localObject);

        String str = String.valueOf(paramString);

        localObject = str + "\n";

        localDataOutputStream.writeBytes((String) localObject);

        localDataOutputStream.flush();

        localDataOutputStream.writeBytes("exit\n");

        localDataOutputStream.flush();

        localProcess.waitFor();

        localObject = localProcess.exitValue();

    } catch (Exception localException)

    {

        localException.printStackTrace();

    }

}

//获取权限

RootUtils.execRootCmd("chmod 777 -R " + WX_ROOT_PATH);

然后,获取微信数据库的密码。

微信数据库的密码是由设备的 imei 和微信的 uid 进过 md5 算法生成的。

/**

* 根据imei和uin生成的md5码,获取数据库的密码(去前七位的小写字母)

*

* @param imei

* @param uin

* @return

*/

public static String getDbPassword(String imei, String uin)

{

    if (TextUtils.isEmpty(imei) || TextUtils.isEmpty(uin))

    {

        Log.d("xag", "初始化数据库密码失败:imei或uid为空");

        return "密码错误";

    }

    String md5 = MD5Utils.md5(imei + uin);

    assert md5 != null;

    return md5.substring(0, 7).toLowerCase();

}

接着,就可以使用 SQLCipher 依赖库来对微信数据库进行查询,我们需要为项目 添加 如下依赖,方便操作数据库。

//我们需要对项目增加依赖

implementation 'net.zetetic:android-database-sqlcipher:3.5.4@aar'

利用上面得到的密码打开加密数据库,然后查询 「rcontact」 表 获取微信通讯录内所 有的好友的微信号、昵称、用户名等数据。

/**

* 连接数据库

* <p>

* 常用库介绍:【rcontact】联系人表,【message】聊天消息表

*

* @param dbFile

*/

private void openWxDb(File dbFile, String db_pwd)

{

    //所有联系人

    List<Contact> contacts = new ArrayList<>();

    SQLiteDatabase.loadLibs(this);

    SQLiteDatabaseHook hook = new SQLiteDatabaseHook()

    {

        public void preKey(SQLiteDatabase database)

        {

        }

        public void postKey(SQLiteDatabase database)

        {

            atabase.rawExecSQL("PRAGMA cipher_migrate;"); //兼容2.0的数据库

        }

    };

    try

    {

        //打开数据库连接

        SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbFile, db_pwd, null, hook);

        //查询所有联系人

        //过滤掉本人、群聊、公众号、服务号等一些联系人

        //verifyFlag != 0:公众号、服务号

        //注意黑名单用户,我-设置-隐私-通讯录黑名单

        Cursor c1 = db.rawQuery(

                    "select * from rcontact where verifyFlag =0 and type not in (2,4,8,9,33,35,256,258,512,2051,32768,32770,32776,33024,65536,65792,98304) and username not like \"%@app\" and username not like \"%@qqim\" and username not like \"%@chatroom\" and encryptUsername!=\"\"",

                    null);

        while (c1.moveToNext())

        {

            String userName = c1.getString(c1.getColumnIndex("username"));

            String alias = c1.getString(c1.getColumnIndex("alias"));

            String nickName = c1.getString(c1.getColumnIndex("nickname"));

            int type = c1.getInt(c1.getColumnIndex("type"));

            contacts.add(new Contact(userName, alias, nickName));

          }

          Log.d("xag", "微信通讯录中,联系人数目:" + contacts.size() + "个");

          for (int i = 0; i < contacts.size(); i++)

          {

            Log.d("xag", contacts.get(i).getNickName());

          }

          c1.close();

          db.close();

    } catch (Exception e)

    {

          Log.e("xag", "读取数据库信息失败" + e.toString());

          Toast.makeText(this, "读取微信通信录失败!", Toast.LENGTH_SHORT).show();

    }

    Toast.makeText(this, "读取微信通信录成功!", Toast.LENGTH_SHORT).show();

}

需要注意的是,数据库中 rcontact 表的数据比较杂乱,除了正常的好友数据,黑名单好友、已删除好友、公众号、微信群等数据也包含在内,需要我们通过 type 和 verifyFlag 字段进行筛选。

 

 

 

为了便于 Python 操作,最后将查询的好友数据写入到 csv 文件中。

/***

* 写入数据到csv中

* @param output_path

* @param contacts

*/

public static void writeCsvFile(String output_path, List<Contact> contacts)

{

    try

    {

        File file = new File(output_path);

        //删除之前保存的文件

        if (file.exists())

        {

            file.delete();

        }

        BufferedWriter bw = new BufferedWriter(new FileWriter(file, true));

        // 添加头部名称

        bw.write("userName" + "," + "alias" + "," + "nickName");

        bw.newLine();

        for (int i = 0; i < contacts.size(); i++)

        {

            bw.write(contacts.get(i).getUserName() + "," + contacts.get(i).getAlias() + "," + contacts.get(i).getNickName());

            bw.newLine();

        }

        bw.close();

    } catch (IOException e)

    {

        e.printStackTrace();

    }

}

第 2 步,我们需要模拟给好友转账,来判断这个好友关系是否正常。

首先,我们需要初始化 Airtest,然后利用 adb 把第 1 步生成的数据从手机里导出到本地。

def __init_airtest(self):

        """

        初始化Airtest

        :return:

        """

        device_1 = Android('822QEDTL225T7')

        # device_1 = Android('emulator-5554')

        connect_device("android:///")

        self.poco = AndroidUiautomationPoco(device_1, screenshot_each_action=False)

        auto_setup(__file__)

def export_wx_db_from_phone(target_path):

    """

    从手机中导出通信录数据

    :param target_path:

    :return:

    """

    # 微信通信录数据

    wx_db_source_path = "/data/data/com.xingag.crack_wx/wx_data.csv"

    # 导出到本地

    os.popen('adb pull %s %s' % (wx_db_source_path, target_path))

然后就是一系列自动化操作。

打开微信,遍历好友列表,拿到每一个好友的微信号去搜索好友,跳转到好友的聊天界面。

def __to_friend_chat_page(self, weixin_id):

        """

        点击到一个好友的聊天界面

        :param weixin_id:

        :param weixin_name:

        :return:

        """

        # 1、点击搜索

        element_search = self.__wait_for_element_exists(self.id_search)

        element_search.click()

        print('点击搜索')

        # 2、搜索框

        element_search_input = self.__wait_for_element_exists(self.id_search_input)

        element_search_input.set_text(weixin_id)

        # 3、搜索列表

        element_search_result_list = self.__wait_for_element_exists(self.id_search_result_list)

        # 3.1 是否存在对应的联系人,如果存在就在第一个子View布局下

        # 注意:可能出现最常用的聊天列表,这里需要进行判断

        index_tips = 0

        for index, element_search_result in enumerate(element_search_result_list.children()):

            # 联系人的Tips

            # if element_search_result_list.children()[0].offspring(self.id_contact_tips).exists():

            if element_search_result.offspring(text=self.text_contact_tips).exists():

                index_tips = index

                break

        # 4、点击第一个联系人进入聊天界面

        element_search_result_list.children()[index_tips + 1].click()

接着尝试着给对方转账,如果好友关系正常,就会跳出一个支付页面让输入密码。

def __judge_is_friend(self, weixin_id, weixin_name):

        """

        判断是不是微信好友

        :param weixin_id: 微信号

        :return:

        """

        # 尝试给好友转账,设置一个小额度,以防止刷脸直接支付了

        # 如果对方是你的好友,接下来会让你输入密码,关掉页面就行了

        # 如果对方不是你的好友,会提示不是你的好友,不能继续操作了

        # 5、点击好友界面的+按钮

        self.poco(self.id_chat_more_button).click()

        # 6、点击转账按钮

        self.poco(self.id_chat_more_container).offspring(text=self.text_chat_transfer_account_text).click()

        # 7、输入金额

        self.poco(self.id_transfer_account_input).set_text(self.money)

        # 8、点击转账按钮

        self.poco(self.id_transfer_account_container).offspring(text=self.text_chat_transfer_account_text).click()

如果是僵尸粉,应用会弹出一个警告对话框,提示你不是收款方好友,没法完成转账的操作。

 

 

 

通过警告对话框是否存在,就可以判断好友关系是否正常。  非正常的好友关系,包含:僵尸粉、对方账号异常等。

# 10.弹出警告对话框

# 弹出好友关系不正常

if element_transfer_account_result_button:

    # 提示内容

    ransfer_account_result_tips = self.poco(self.id_transfer_account_result_tips).get_text()

    if self.text_friend_no_tips in transfer_account_result_tips:

        print('注意!%s已经把你拉黑了!!!' % weixin_name)

        self.friend_black_list.append({

                    'id': weixin_id,

                    'nickName': weixin_name

                })

        write_to_file(self.path_black_list, 'id:%s,nickName:%s' % (weixin_id, weixin_name))

    elif self.text_friend_limit_tips in transfer_account_result_tips:

        print('%s账号收到限制!!!' % weixin_name)

        write_to_file(self.path_account_limit, 'id:%s,nickName:%s' % (weixin_id, weixin_name))

    elif self.text_friend_is_norm in transfer_account_result_tips:

        print('%s好友关系不正常!!!' % weixin_name)

        write_to_file(self.path_relationship_unnormal, 'id:%s,nickName:%s' % (weixin_id, weixin_name))

    # 点击确认按钮

    element_transfer_account_result_button.click()

    # 返回到主页面

    self.__back_to_home()

else:

    # 包含正常好友关系和对方账号限制的情况

    print('好友关系正常')

    self.__back_to_home()

最后,模拟点击手机的返回键,一直回退到微信主界面。

def __back_to_home(self):

        """

        回退到主界面

        :return:

        """

        print('准备回退到主界面')

        home_tips = ['微信', '通讯录', '发现', '我']

        while True:

            keyevent('BACK')

            is_home = False

            # 判断是否到达首页

            if self.poco(text=home_tips[0]).exists() and self.poco(text=home_tips[1]).exists() and self.poco(

                    text=home_tips[2]).exists() and self.poco(text=home_tips[3]).exists():

                is_home = True

            if is_home:

                print('已经回到微信首页~')

                break

循环上面的操作,就可以判断出哪些是僵尸粉,哪些好友的账号被限制,哪些是正常的好友关系。

第 3 步,删除上面获取到的僵尸粉列表。

拿到上面的僵尸粉数据列表,就可以利用上面的方式进行一系列自动化UI 操作,删除掉这些好友。

def del_friend_black(self, weixin_id):

        """

        删除黑名单好友

        :return:

        """

        # 到好友聊天界面

        self.__to_friend_chat_page(weixin_id)

        # 点击聊天界面右上角,进入到好友的详细信息界面

        self.poco(self.id_person_msg_button).click()

        # 点击好友头像

        self.poco(self.id_person_head_url).click()

        # 点击个人名片的右上角,弹出好友操作菜单

        self.poco(self.id_person_manage_menu).click()

        # 查找删除操作栏

        # 注意:对于目前主流的手机,都需要滑动到最底部才能出现【删除】这一操作栏

        self.poco.swipe([0.5, 0.9], [0.5, 0.3], duration=0.2)

        # 点击删除,弹出删除对话框

        self.poco(self.id_person_del, text=self.text_person_del).click()

        # 确定删除好友【确定删除】

        # 界面会直接回到主界面

        self.poco(self.id_person_del_sure, text=self.text_person_del).click()

4

结 果 结 论

编译 Android 项目或者直接运行 APK 就能将微信通信录的好友数据保存到项目文件目录下。

然后运行 Python 程序会遍历通讯录好友数据,自动化去操作微信 App,接着将所有的僵尸粉写入到本地文件中,最后可以选择将这些僵尸粉全部删除掉。

我已经将全部源码 上传到后台上,关注公众号后回复「僵尸粉 」即可获得,文中的 APK 可以直接回复 「730 」获取下载链接。

如果你觉得文章还不错,请大家点赞分享下。你的肯定是我最大的鼓励和支持。

微信3.9.8.25机器人(Hook注入)搭建教程文档 开源地址 https://github.com/ttttupup/wxhelper 微信破解dll https://github.com/nefarius/Injector 注入工具 https://github.com/tom-snow/wechat-windows-versions/releases 微信历史版本 基本原理 启动指定版本PC微信以后,利用注入程序将dll文件注入到... 阅读详情

相关推荐

wxhook接口参数wxhook接口参数

wxhook接口参数

易语言使用hook逆向技术实现WX常用功能操作专题课程

本课程主要是讲解了WX的PC版中使用hook技术来达到目前一些流行需求的目的。主要用的工具是ce,od,易语言,本课程只做技术分享交流,请勿用于非法用途。

HOOK、微信机器人wxhook,数据库解密微信公众号采集微信公众号爬虫,企业微信HOOK.zip

HOOK、微信机器人wxhook,数据库解密微信公众号采集微信公众号爬虫,企业微信HOOK.zip

微信HOOK 协议接口 实战开发篇 3.收发文本消息 附详细步骤

本次文章附带详细的HOOK步骤,使用了之前文章提到的字符搜索法。

q750936486的博客 7303

最新微信hook2.6.3.78源码

最新版WxHook2.6.3.78源码,亲测可以使用。下载后,需要安装pc2.6.3.78,就能使用。

微信HOOK、微信机器人wxhook,数据库解密微信公众号采集微信公众号爬虫,企业微信HOOK.zip

注PC微信hook源码,初学者学习,请不要用于商业、违法途径,本人不因此造成源码的违法责任!当前项目搭载的微信版本为3.2.1.154本项目为演示版本,初学者学习参考。QQ群795681068点击链接加入群聊【鬼手逆向交流群】https://qm.qq.com/q/TXCiMFxgsO说明此仅限学习和交流,无其他用处更新说明显示二维码退程序解决方案安装VS2017勾选使用C++的桌面开发。问题即可解决2019-7-26添加艾特群成员功能——好友列表->右键->查看群成员->右键->艾特群成员添加删除群成员功能——好友列表->右键->查看群成员->右键->删除群成员针对编译不过的问题剥离解密数据库功能请使用VS2017进行编译如果编译不过请求平台工具集和SDK版本修改为机器上的最新版本需要数据库解密功能请使用带解密数据库功能的成品2019-7-29修复bug新增微信重要呼叫的特征码有参数注释和可用于 OD 搜索十六烷特征码2019-8-3优化自动聊天功能2019-9-5新增功能打开本程序自动启动微信 消耗先启动微信再打开本程序

谁偷偷删了你的微信?别慌!Python 帮你都揪出来了

点击上方“AirPython”,选择“置顶公众号”第一时间获取 Python 技术干货!阅读文本大概需要 18 分钟。1目 标 场 景不知道你有没有经历过,想联系一位很长...

AirPython的博客 2360

【可不卸载重装】VS2019新建项目里没有CUDA选项

问题:VS2019 新建项目里没有CUDA选项,vs也属性没有cuda。这是因为你在Visual Studio 2019安装之前,先安装了CUDA Toolkit。

qq_62844901的博客 1319

有人偷偷删了你的微信?别慌!Python 帮你揪出来

相信每个人的微信通信录里都存在一些 「 僵尸粉 」 ,他们默默地躺在联系人列表中,你以为对方还是朋友,那就真是太年轻、太天真的;实际上,对方早就把从好友列表中删了,那如何来筛选出这群人呢? 本篇文章的目的是自动化操作微信 App,通过 「 模拟给好友转账 」 来筛选出所有的僵尸粉,并一键删除它们。 准 备 工 作 在开始编写脚本之前,需要做好如下准备工作 一部 Root 后的 Androi...

人生苦短, 还不用Python? 693

硬全桥副边钳位管Vds电压凸台揭秘——寄生参数引发的导通异常

本文深入分析了硬全桥副边钳位管Vds电压凸台现象,揭示了寄生参数如何引发导通异常。通过波形分析和工程实践,详细解析了走线电感的蓄能效应和体二极管的接力作用,并提供了PCB布局优化、元件选型和驱动电路调整等解决方案,帮助工程师有效应对这一常见问题。

weixin_30825581的博客 429

海康威视摄像头CVE-2017-7921漏洞复现:从零到一的实战指南(含解密工具下载)

本文详细解析了海康威视摄像头CVE-2017-7921漏洞的技术原理与复现方法,提供从环境搭建到实战利用的完整指南。通过认证绕过漏洞,攻击者可获取敏感信息并执行高权限操作,文章还包含解密工具下载与防御建议,助力安全研究人员深入理解物联网设备安全风险。

weixin_29325515的博客 810
上一篇: Python 网络爬虫之模拟登陆合集 !
下一篇: Python协程详解!
普通网友
博客等级 码龄7年 438粉丝 263原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值