微信机器人 DIY 从 0 到 1

这标题多少有点儿不恰当——本文重点其实是介绍微信机器人的一个传输通道,机器人部分不会涉及太多。不过话说回来,哪怕只能机械应答,其实也是可以称为机器人的。

本文打算从动机、基本原理、关键技术、具体实现以及应用示例五方面来展开介绍。

代码已经开源:WeChatFerry,动手达人们,搞起来了(支持 Python 哦!)。
微信安装包也建了个仓库,可以去下载对应版本的微信安装包:WeChatSetup。

ℹ️ WeChatFerry 是基于 PC 微信的一个工具,如果你没有 Windows 电脑,可以通过虚拟机来玩儿。

动机

最初的时候,一位大佬有个需求,希望通过微信群发通知。我当时找到了 ichat,一个基于微信 Web 版的框架。可是没用几天,我的微信网页版就被封了。

可能是因为微信 Web 协议被破解得差不多了,后来基本微信 Web 版都上不去了。没办法了,只好再找轮子。

借助伟大的互联网,我终于又找到了一个基于 PC 微信的轮子。但这轮子支持的版本有点儿老,等我把项目调试好,发布到服务器上的时候出故障了——服务器是个新系统,旧版本的微信不能用。

这时候,我有两个选择:一个是把开发环境打个镜像,装到服务器上,继续使用旧版本的微信;一个是造轮子,自己适配最版本的微信。

出于对技术的热爱,我选择了造轮子。这个轮子现在已经实现的功能包括:

  • 获取登录状态
  • 发送文本消息(群聊可 @)
  • 发送图片消息
  • 接收所有类型消息
  • 获取联系人(基于内存,也可以通过 SQL)
  • 通过好友验证
  • 查询数据库,获取库、表
  • 执行 SQL

已经支持的客户端包括:

  • CPP
  • Java
  • Python

基本原理

本质上,就是写了个工具,“劫持”了微信:

  • 当微信收到消息时,抢在微信处理(显示到页面)前,先让工具处理,处理完之后再交还给原来的处理模块;
  • 需要发送消息时,模拟微信发送消息,组装好消息体,调用微信发送消息的模块;
  • 获取联系人,则是遍历一块特定的内存空间;
  • 通过好友验证,则是组装好验证信息,调用微信的验证模块;
  • 数据库相关功能,则是通过获取到数据库句柄,参考 sqlite3 的接口,来执行。
    Overview

更形象一点,我们派一个间谍(Spy.DLL)打入微信内部,通过电报(RPC)和外部特工(C++ 应用Java 应用Python 应用)进行消息交换:

  • 当微信收到消息时,Spy.DLL 把消息通过 RPC 传给 C++ 应用 或者 Python 应用
  • C++ 应用 或者 Python 应用 需要发送消息时,通过 RPC 传递给 Spy.DLL “假传圣旨”发送出去。

到现在为止,还有一个问题:间谍是怎么混进去的?这就需要借助注入技术。下面介绍一下本项目涉及到的几个关键技术点。

关键技术

根据前面的介绍:

  • Spy.DLL 负责拦截、伪装,这就需要拦截技术(Hook);
  • RPC 负责传送消息,涉及到跨进程间通信,本项目使用的是远程过程调用(Remote Procedure Call);
  • SDK.DLL 负责把 Spy.DLL(间谍)打入微信内部,涉及到注入技术。
  • C++ 应用Java 应用Python 应用 等客户端用于实现应用功能。

这也是我乐于其中的原因,因为项目虽小,但涉及到的技术点还挺多,非常有趣。

注入

首先介绍一下注入(Inject)技术。

注入技术通常都跟恶意软件有关,一般是为了在目标进程中执行自定义代码。注入技术有很多,本项目选取了最经典的一种:将 Spy.DLL 的路径写入微信进程的虚拟地址空间,然后通过在微信进程中创建一个远程线程来加载 Spy.DLL
Inject

参考实现如下:

    HANDLE hThread;SIZE_T cszDLL = (wcslen(dllPath) + 1) * sizeof(WCHAR);// 1. 打开目标进程HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);if (hProcess == NULL) {MessageBox(NULL, L"打开进程失败", L"InjectDll", 0);return NULL;}// 2. 在目标进程的内存里开辟空间LPVOID pRemoteAddress = VirtualAllocEx(hProcess, NULL, cszDLL, MEM_COMMIT, PAGE_READWRITE);if (pRemoteAddress == NULL) {MessageBox(NULL, L"DLL 路径写入失败", L"InjectDll", 0);return NULL;}// 3. 把 dll 的路径写入到目标进程的内存空间中WriteProcessMemory(hProcess, pRemoteAddress, dllPath, cszDLL, NULL);// 3. 创建一个远程线程,让目标进程调用 LoadLibraryhThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibrary, pRemoteAddress, 0, NULL);if (hThread == NULL) {MessageBox(NULL, L"LoadLibrary 调用失败", L"InjectDll", 0);return NULL;}WaitForSingleObject(hThread, -1);GetExitCodeThread(hThread, (LPDWORD)injectedBase);CloseHandle(hThread);VirtualFreeEx(hProcess, pRemoteAddress, 0, MEM_RELEASE);CloseHandle(hProcess);

拦截伪装

通过注入技术,成功将 Spy.DLL(间谍)打入了微信内部,下一步要做的事情便是让 Spy.DLL(间谍)能“劫持”微信消息和“假传圣旨”,这需要使用拦截、伪装技术。

拦截

拦截技术通常被称为 Hook

为了介绍拦截技术,需要先说一说程序从编码到运行的流程。以 C/C++ 为例,程序从产生到运行大体需要经历:

  1. 编码
  2. 预编译、编译、汇编、链接
  3. 创建程序进程,加载程序代码、数据,创建、映射虚拟地址空间
  4. 创建主线程,运行程序

在编译阶段,编译器便把代码里的指令安放到代码段。当程序被加载到虚拟地址空间的时候,代码段便被映射过去。于是,我们程序里的函数,便可以用一个地址(是不是想起了指针?)代替。

当微信接收到一条新消息,需要展示给用户的时候,可以想象,肯定会调用某个函数,把消息展示出来。如果我们把这个函数换成咱们的函数,就可以拦截微信的消息了。前面提到,在程序运行的时候,所谓函数不过是个地址指向,所以我们只要把这个地址指向咱们自己的函数,便实现了拦截。

下面举个例子:

# 经研究发现,当微信收到消息的时候,会调用下面的函数
# 地址       机器码            反汇编
0F7F0F4C    E8 FF535400     call WeChatWi.0FD36350

我们只要把 0F7F0F4C 里的 call WeChatWi.0FD36350,替换成 call 咱们自己的函数,便可以对消息进行拦截了。同时,为了不影响原有的功能,我们还需要在 咱们自己的函数 的最后,调用 WeChatWi.0FD36350

我们把 0F7F0F4C 叫做 Hook 地址,把 WeChatWi.0FD36350 叫做 Call 地址。这里 0F7F0F4C0FD36350 都是“相对”地址——相对 WeChatWin.dll 的地址;而 WeChatWin.dll 的地址称为 基址Base)。

本例中,WeChatWin.dll 的基址为:0F2A0000,所以:

Hook = 0x0F7F0F4C - 0x0F2A0000 = 0x550F4C
Call = 0x0FD36350 - 0x0F2A0000 = 0xA96350

假设我们写了一个函数 RecieveMsgHook 来处理拦截的消息,下面的代码可以实现消息拦截:

    // 把 Hook 和 Call 的地址算出来DWORD hookAddress   = g_WeChatWinDllAddr + g_WxCalls.recvMsg.hook;recvMsgCallAddr     = g_WeChatWinDllAddr + g_WxCalls.recvMsg.call;recvMsgJumpBackAddr = hookAddress + 5;// 组装机器码BYTE jmpCode[5] = { 0 };jmpCode[0]      = 0xE9;  // 原来函数调用,机器码 E8,现在要改成跳转 E9// 把原来的 WeChatWi.0FD36350 替换成 RecieveMsgHook 的地址*(DWORD *)&jmpCode[1] = (DWORD)RecieveMsgHook - hookAddress - 5;// 0F7F0F4C    E8 FF535400     call WeChatWi.0FD36350WriteProcessMemory(GetCurrentProcess(), (LPVOID)hookAddress, jmpCode, 5, 0);

伪装

当我们需要在微信接上发送一条新消息的时候,可以想象,微信肯定会调用某个函数,把消息发送出去。如果我们找到这个函数,组装好发送内容,调用它,就可以发送微信的消息了。

下面举个例子:

0F44FBF3    8D46 38         lea eax,dword ptr ds:[esi+0x38]
0F44FBF6    6A 01           push 0x1
0F44FBF8    50              push eax                                 ; At members
0F44FBF9    57              push edi                                 ; Message
0F44FBFA    8D55 90         lea edx,dword ptr ss:[ebp-0x70]          ; Receiver wxid
0F44FBFD    8D8D 50FCFFFF   lea ecx,dword ptr ss:[ebp-0x3B0]         ; Buffer
# 经研究发现,当微信发送消息的时候,使用下面的函数
0F44FC03    E8 28213700     call WeChatWi.0F7C1D30                   ; Send Msg
0F44FC08    83C4 0C         add esp,0xC
0F44FC0B    C645 FC 05      mov byte ptr ss:[ebp-0x4],0x5
0F44FC0F    8B85 70FCFFFF   mov eax,dword ptr ss:[ebp-0x390]
0F44FC15    0B85 74FCFFFF   or eax,dword ptr ss:[ebp-0x38C]
0F44FC1B    75 10           jnz short WeChatWi.0F44FC2D

于是,当我们需要发送消息的时候,只要调用 0x521D30(0x0F7C1D30 - 0x0F2A0000)即可。

RPC

前面我们成功打入微信内部,并且也可以拦截消息并“假传圣旨”,那么,我们怎么把消息传出去或者传进来呢?

微信和我们的应用,在不同的进程。如果我们的应用需要和微信通信,则涉及到进程间通信(Inter Process Communication)。

Windows 支持的 IPC 方式包括:

  • 剪贴板
  • COM
  • 数据复制
  • DDE
  • 文件映射
  • Mailslots
  • 管道
  • RPC
  • Windows 套接字

RPC 指远程过程调用(Remote Procedure Call)。这里的远程指的是不在同一个进程,可以是一台电脑上的不同进程;也可以是不个电脑上的不同进程。使用 RPC,可以创建高性能紧密耦合的分布式应用程序。

本项目选择了 RPC,结果惹了一身麻烦。但是通过 RPC,进程间通信就变得很简单。RPC 工具使用户看起来就像客户端直接调用位于远程服务器程序中的过程一样。 客户端和服务器各自有自己的地址空间;也就是说,每个资源都有自己的内存资源分配给过程使用的数据。 下图说明了 RPC 体系结构:
RPC

Yet Another Demo for Windows RPC 是对 Windows 下 RPC 使用的一些总结。项目现在已经转到了gRPC,可以参考 A gRPC Demo。

混合编程

最初的版本,使用了 Windows 原生的 RPC 导致可以拦截消息也可以“假传圣旨”——只限于自己人(C++)。那怎么能让 Python 也可以拦截消息、“假传圣旨”呢?这就涉及到了混合编程,具体而言是 Python 调用 C++ 的 SDK。

下面是微软文档上介绍的实现方式:

ApproachVintageRepresentative users
C/C++ extension modules for CPython1991Standard Library
PyBind11 (recommended for C++)2015
Cython (recommended for C)2007gevent, kivy
HPy2019
mypyc2017
ctypes2003oscrypto
cffi2013cryptography, pypy
SWIG1996crfsuite
Boost.Python2002
cppyy2017

本项目最开始的时候选择了 ctypes,无它,唯简单而。但后来随着功能变得复杂,ctypes 不太好搞,于是便转向了 PyBind11。

现在换成了 gRPC,可以不需要混合了!

具体实现

前面已经把关键技术介绍完了,具体实现就比较好理解了。

工程结构

WeChatFerry
├── LICENSE
├── README.MD
├── TEQuant.jpeg
├── WeChatFerry.sln
├── cpp/
├── java/
├── proto/
├── python/
├── sdk/
└── spy/

spy

这部分就是前面举例的拦截消息和“假传圣旨”的实现部分,目前实现了:

  • 接受好友申请(accept_new_friend
  • 执行 SQL(exec_sql
  • 获取联系人(get_contacts
  • 接收消息(receive_msg
  • 发送消息(send_msg

sdk

完成 spy.DLL(间谍)的注入和初始化。

proto

RPC 服务、接口、消息的定义文件。

cpp

C++ 应用,可以是个对话机器人,可以是个定时消息发送器,还可以是个群发机器。这里提供了 spy 的功能示例。

python

Python 应用,可以是个对话机器人,可以是个定时消息发送器,还可以是个群发机器。这里提供了 spy 的功能示例。

java

Java 应用,可以是个对话机器人,可以是个定时消息发送器,还可以是个群发机器。这里提供了 spy 的功能示例。

应用

最初,就是因为有需求而造的轮子,不料轮子造出来需求却没了,现在只好做些无用的东西。欢迎进群体验。

天气播报机器人

每天 7 点准时在群里发布天气预报:

天气播报机器人

智障机器人

只能回答天气问询:
Chatbot
为了做天气播报机器人,写了个天气爬虫,把天气数据抓回来了。代码也开源了:WeatherScrapy。
这个应用使用了 RASA,自己造了些语料简单训练了一下。

成语解释、接龙

团建作弊可用:
在这里插入图片描述

To Be Continued…

  • 统计好友分布情况
  • 计算好友之间的亲密度(点赞占比、共同群聊数量、聊天频度……)
  • 羊毛群机器人
  • 清除群僵尸
  • ……

欢迎 Star、PR:WeChatFerry,后续再介绍一个基于 Python 的机器人框架,就可以更愉快地玩耍了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/3802.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信机器人ipad

首先我们要先了解下ipad协议是什么 ,ipad协议又叫微信协议 是基于微信IPad协议的智能控制系统帮助企业快速连接客户,创造营销氛围,实现自动获客、自动传播、自动转化、智能营销等分布式营销服务。 通过API 实现 个性化微信功能 (例…

微信机器人接入Midjourney

Midjourney 今天下午研究了一下Midjourney,发现画图确实厉害,于是懂了小心思,为了方便使用,直接把他搞到微信上来用用,话不多说,先上图: 为了方便使用,里面还接入了百度翻译的api&a…

搭建微信机器人的方案都在这了!

大家好,我是鸟哥。一个半路出家的程序员。 最近ChatGPT又把微信机器人带火了!我也算是微信机器人的资深玩家,今天也和大家聊聊这个知识点。之前就有小伙伴经常问 搭建微信机器人有哪些框架? 怎么把ChatGPT接入个人微信&#xff…

拂晓·微信机器人

前言 本项目是基于千寻微信框架进行的功能开发,采用SpringBoot青云客机器人进行开发。 千寻初衷是想开源一个框架的写法,并不是为了用来运营,因此功能不全,所以使用和适配前请查看是否与自己需求匹配。 因此本文主要通过千寻客…

别再折腾ChatGpt的微信机器人了,你看到的全是假的

别再折腾ChatGpt的微信机器人了,你看到的全是假的 ChatGPT去年先是在程序员圈子里小众出圈,当时本拐还写了两篇文章: 跟着ChatGPT手把实现一个websocket连接管理器!毛骨悚然 我当PM,把ChatGPT玩冒(b)烟(gōng)了 2023年后&#xf…

0 代码,十分钟搞定微信版 ChatGPT,轻松拥有个性化 AI 助手教程!

大家好,我是贺同学。 最近一周多的时间,只要不是生活在火星,只要你是个正常刷手机的打工人,一定都被 OpenAI 的 ChatGPT 给刷屏了。 看到别人玩的不亦乐乎,想要自己搭建一个机器人玩玩?最好是可私信&#x…

ChatGPT写论文能发表吗?权威期刊回应了!

最近,ChatGPT在社交网络可太太太火了!有关ChatGPT写论文这事也是频频上热搜。依靠ChatGPT强大的语言理解和学习能力,不少网友产生了一个大胆的想法——用ChatGPT来写作业、发论文,岂不美哉!还真有人这么做了。 图片来源…

2023第十三届中国数字营销与电商创新峰会

峰会背景 展望2023年,尽管整体市场环境复杂多变,中国消费市场可能会持续波动,但是,随着防疫政策优化,消费者信心将逐步恢复,中国消费市场依然展现出强劲韧性。 中国的消费者正经历一场前所未有的变革&…

关于AIGC企业出海案例

随着人工智能技术的不断发展,跨境电商行业也开始受到了智能化技术的影响。越来越多的跨境电商企业开始借助生成式AI工具来提升自身的运营效率和竞争力。 下面分享一个AIGC企业出海案例: verycloud与一家国内领先AI技术团队的跨境出海AI内容应用客户达成…

亚马逊云科技跨境电商峰会:重构跨境想象力,赋能出海新机遇

随着数字技术的不断发展和全球市场的快速变化,跨境电商市场呈现出越来越多的机遇和挑战。市场竞争加剧,流量红利减弱,后疫情时代,技术驱动下的创新发展成为企业转型的核心。如何借助数字技术重构跨境电商的想象力,抓住…

GPT-4震撼发布,跨境电商怎么用?带你直观了解GPT-4的升级作用

相信大家今天打开各个平台,大家都在讨论的就是GPT-4了,可谓是又一次刷屏大家的社交平台。东哥今天就来跟大家唠唠Open-AI 刚刚公布的ChatGPT最新版本 ——GPT-4。 GPT-4 的作用以及优缺点 GPT-4确实拥有多模态能力,可以接受图像输入并理解图像…

亚马逊云科技跨境电商峰会,让AI重构跨境想象力

随着数字技术的不断发展和全球市场的快速变化,跨境电商市场呈现出越来越多的机遇和挑战。市场竞争加剧,流量红利减弱,后疫情时代,技术驱动下的创新发展成为企业转型的核心。如何借助数字技术重构跨境电商的想象力,抓住…

集成ChatGPT多商户跨境电商平台WordPress主题提供定制开发

WordPress主题WMart汉化版是一个多商户系统购物网站WooCommerce主题,集成了OpenAl/ChatGPT内容生成系统,适用于构建类似亚马逊、eBay等市场。 WMart提供了大量元素和强大的功能,可以为多供应商市场配置您想要的一切。相比其他市场主题的一般…

跨境电商账号矩阵运营方法论

人在布宜诺斯艾利斯,旅游结束,开始看看商业机会,最近其实不少人跟我聊跨境电商、游戏出海的事情,出海营销的人越来越多了。做投放买量的朋友跟我吐槽,海外平台的审核越来越严格,买量到底还值不值得做&#…

跨境电商必读,WhatsApp营销入门指南!

关键词:WhatsApp营销、跨境电商营销 现在,跨境社交媒体和Messengers不仅仅是私人交流的渠道了。很多跨境电商已经找到了在WhatsApp营销的秘诀,如果你还没开始,你可能已经落后了。同时,与其他平台相比,在 W…

外贸是什么意思?和跨境电商的区别是什么?

最近看到网上不少朋友在问,外贸是什么意思?和跨境电商的区别是什么?今天我们小编就给大家简单讲解一下。 外贸是什么意思? 外贸是对外贸易的简称,又称为国外贸易” 或“进出口贸易”;是指一个国家&#xf…

跨境电商API接口,Lazada商品详情,按关键词搜索,商品评论等数据的采集获取

item_review-获得lazada商品评论列表 请求参数 请求参数:num_iid267690734&nationco.th参数说明:num_iid:lazada商品ID(是对应国家不同国家的ID不能通用) nation:国家 国家域名后缀可选值如下:co.id、com.my、com.ph、sg、co.th、vn 请…

什么是跨境电商?

跨境电商,全称为跨境电子商务,是指处于不同地区,不同国家的交易主体,通过电商平台进行交易,支付结算,并通过跨境物流将产品送到指定客户手中。在2014年,伴随海关56号和57号文的推出,…

shopee虾皮跨境电商怎么样,虾皮跨境电商的优势和劣势

本人,算是一个入行不到几年的虾皮跨境电商卖家。在下不才,之前刚接触跨境是准备去做亚马逊的,准备搞FBA海外仓,但是中途看,做亚马逊遍地后,就止步不前。 后来遇到一个超级大神,给我说了条明路,说东南亚shopee虾皮没什么人做,所以让我可以尝试一下。 刚开始当然也不是…

英国主要跨境电商平台简单介绍

小伙伴都知道,要想卖得好,首先就要选对平台,针对相应用户群体卖货。今天我们小编就给大家简单介绍一下英国主要跨境电商平台,这样大家心里就都有一个判断!这是因为英国不仅是全球第三大电商市场,同时英国电…