微信助手的开发思路及作品

开发初衷

微信当今成为现代国人离不开的通讯的工具,已然成为了作为人的"一部分",随之弊端也愈演愈烈,工作、社交、日常生活都渗透在微信中,一时间不关注它就生怕错过了什么。我便思考:有没有什么助手可以帮助我托管微信,就像玩斗地主或者打游戏,我不得不离开电脑或手机时,它可以临时的替代我机械的"在线"。我在网上找各种各样的助手,但是没有合适的,我便想着能不能自己做一款。

思路

微信软件本身的思路非常简单,信息的接收无非是通讯消息,这一块的处理方式我们只需要劫持通讯信息,获取通讯信息后再将信息放回原来的通讯即可;难点就在于发送消息,发送消息该如何做?这一定要渗透到微信的内存和进程内部才行,就不得不使用注入技术。

探寻底层原理

如果要做获取微信本身信息的操作,则一定是获取微信占用的内存进行读取,比如:

  • 获取联系人,则是遍历一块特定的内存空间;
  • 获取当前登录微信信息,则是获取一块特定的内存空间;
  • 获取当前微信的设置项,也是获取一块特别的内存空间;
  • ...

如果要做一些"行为",则一定是获取微信的进程,调用进程中的模块,比如:

  • 需要发送消息时,模拟微信发送消息,组装好消息体,调用微信发送消息的模块;
  • 通过好友验证,则是组装好验证信息,调用微信的验证模块;
  • 转发信息,则是拿到劫持的信息获取指定ID,组装转发信息,调用微信转发模块;
  • ...

如果要做一些需要调用微信协议获取的信息,依然是调用模块,自然会通过模块触发协议,比如:

  • 获取指定好友的全部信息,需要组装好请求体,直接调用获取好友详情模块即可。

打个比方,这就需要我们派一个间谍打入微信内部,通过电报(RPC)和间谍(DLL)对外进行消息交换:

DLL 负责拦截、伪装,这就需要拦截技术(Hook);
RPC 负责传送消息,涉及到跨进程间通信,本项目使用的是远程过程调用(Remote Procedure Call);

当微信收到消息时,间谍(DLL)把消息通过 RPC 传给 外部;

需要发送消息时,会将信息通过 RPC 传递给间谍(DLL) "假传圣旨"发送出去

这一切的实现都要基于注入技术,也就是进入微信的进程才能达到目的。

注入原理

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

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

复制代码
 // 1. 获取目标进程,并在目标进程的内存里开辟空间
    HANDLE hProcess       = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    LPVOID pRemoteAddress = VirtualAllocEx(hProcess, NULL, 1, MEM_COMMIT, PAGE_READWRITE);

    // 2. 把 dll 的路径写入到目标进程的内存空间中
    if (pRemoteAddress) {
        WriteProcessMemory(hProcess, pRemoteAddress, dllPath, wcslen(dllPath) * 2 + 2, &dwWriteSize);
    } else {
        MessageBox(NULL, L"DLL 路径写入失败", L"InjectDll", 0);
        return -1;
    }

    // 3. 创建一个远程线程,让目标进程调用 LoadLibrary
    hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibrary, pRemoteAddress, NULL, NULL);
    if (hThread) {
        WaitForSingleObject(hThread, -1);
    } else {
        MessageBox(NULL, L"LoadLibrary 调用失败", L"InjectDll", 0);
        return -2;
    }
    CloseHandle(hThread);
    VirtualFreeEx(hProcess, pRemoteAddress, 0, MEM_RELEASE);
    CloseHandle(hProcess);

拦截伪装

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

拦截

拦截技术通常被称为 Hook。

为了介绍拦截技术,需要先说一说运行的流程。运行大体需要经历:

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

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

举个例子:

复制代码
# 打个比方,当微信收到消息的时候,假设调用下面的函数
# 地址       机器码            反汇编
0F8F0F6C    E8 FF525200     call WeChatWi.0FD26250

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

我们把 0F8F0F6C 叫做 Hook 地址,把 WeChatWi.0FD26250 叫做 Call 地址。这里 0F8F0F6CFF525200 都是"相对"地址------相对 WeChatWin.dll 的地址;而 WeChatWin.dll 的地址称为 基址(Base)

伪装

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

下面举个例子:

复制代码
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 工具使用户看起来就像客户端直接调用位于远程服务器程序中的过程一样。客户端和服务器各自有自己的地址空间;也就是说,每个资源都有自己的内存资源分配给过程使用的数据。

于是,我拿来开发一款软件,适配微信版本3.9.11.25,功能丰富,目前支持如下功能:

  1. **关键词回复,**即对指定好友的指定消息回复预设的消息。

  2. 消息转发,即将好友A的指定消息转发至好友B。

  3. **定时群发,**即在指定时间向指定的好友或群聊发送指定消息。

  4. 进群欢迎语,当群聊有新人加入时,发送指定的消息,且可选Excel统计邀请人数。

  5. 自动收款,当有好友向您转账时,自动收款,并回复指定消息。

  6. 自动通过好友申请,当有新好友申请时,自动同意通过,可选回复指定消息,可选邀请加入群聊。

  7. 关键词进群,当有好友发送指定关键词的消息时,可邀请好友加入指定群聊。

  8. 关键词踢人,当指定群聊中有成员发送指定关键词的消息时,可将该群成员移出这个群聊。

  9. 群成员去重,对指定的几个群聊进行群成员去重,确保每个群成员仅存在一个群聊。

  10. 公众号文章转发,当指定公众号发布新文章时,第一时间将文章转发至指定群聊或好友,从而实现群聊文章自动推送。

  11. 群聊积分签到,对指定的几个群聊进行签到积分管理,即设定指定的签到时间,群成员发送指定口令为签到成功,可在"群签到积分.xlsx"文件中查看群成员、签到积分。

  12. 群成员消息转发,将指定群聊中的指定群成员发送的消息转发至好友或群聊。

  13. 退群监测,对指定的几个群聊进行群成员退群监测。

  14. 批量加好友,对设定好的微信号列表,批量添加好友。

  15. 添加群成员为好友,添加指定群聊中的指定群聊成员。

  16. 定时娱乐,在指定时间向指定的好友或群聊发送娱乐信息。

  17. 群活跃,好友或群聊以关键词的方式触发工具使用。


界面美观易用,例如关键词回复功能界面:

且每个功能模块都适配了使用说明,点击"帮助"即可获得使用方式:


软件安装完成后就可立即使用,开发这款软件的初衷就是为了方便有这方面需求的朋友。

网站:oss.zuoyu.top

网站内有详细的安装说明,和软件的下载地址。