今天我们介绍一款基于易语言开发的微信HOOK框架DaenWxHook
。相关说明:https://www.apifox.cn/apidoc/project-1222856/doc-1046131
所需的dll和微信安装包见上述链接,文末个人也提供了网盘下载地址。
DaenWxHook.dll
基于易语言开发,注入到微信后并启动即可hook微信,目前hook成功的最后一个版本是[3.6.0.18]。文末的下载地址,下载完毕后会提供如下四个文件:
我们先安装该版本的微信,不需要卸载之前的版本,直接选择之前的安装目录即可。安装完成后,定位到对应版本微信的安装目录,将HPSocket4C.dll文件复制到该目录下:
然后我们可以通过Daen注入器
来启动被hook的微信:
点击注入并启动即可启动微信。
注意:callBackUrl和port参数,callBackUrl是一个用于接收微信数据的服务器,DaenWxHook.dll
会向其推送数据,根据port参数DaenWxHook.dll
会启动一个用于获取微信操作指令的http服务器。
callBackUrl=http://localhost:8089/wechat/&port=8055
那么我们需要编写一个端口为8089的的服务器来获取微信的数据。如果我们需要启动多个被hook的微信,可以修改port参数来表示不同的微信。
更多参数说明可以查看:https://www.apifox.cn/apidoc/project-1222856/doc-1012539
在通过注入器启动微信时,DaenWxHook.dll
已经启动了一个http服务器,我们可以根据文档复制代码,例如获取个人信息的接口:
直接复制的代码端口与上述启动参数不符需要修改,我们可以直接改成最简化的形式:
import requests
url = "http://127.0.0.1:8055/DaenWxHook/client/"
payload = {"type": "Q0003", "data": {}}
res = requests.post(url, json=payload)
data = res.json()["result"]
print(data)
其他接口的测试也是同理。
最终我所需要的接口如下:
import requests
url = 'http://127.0.0.1:8055/DaenWxHook/client/'
def fetch_group(flush=False):
payload = {"type": "Q0006", "data": {"type": "2" if flush else "1"}}
res = requests.post(url, json=payload)
data = res.json()
wxid2nick = {}
nick2wxid = {}
for row in data["result"]:
wxid2nick[row["wxid"]] = row["nick"]
nick2wxid[row["nick"]] = row["wxid"]
return wxid2nick, nick2wxid
def fetch_firends(flush=False):
payload = {"type": "Q0005", "data": {"type": "2" if flush else "1"}}
res = requests.post(url, json=payload)
data = res.json()
wxid2nick = {}
for row in data["result"]:
wxid2nick[row["wxid"]] = (row["nick"], row["wxNum"])
return wxid2nick
def fetch_group_member(wxid):
payload = {"type": "Q0008", "data": {"wxid": wxid}}
res = requests.post(url, json=payload)
data = res.json()
return data["result"]
def fetch_obj_info(wxid):
payload = {"type": "Q0004", "data": {"wxid": wxid}}
res = requests.post(url, json=payload)
data = res.json()
return data["result"]
def send_mag(wxid, msg):
payload = {"type": "Q0001", "data": {"wxid": wxid, "msg": msg}}
res = requests.post(url, json=payload)
data = res.json()
return data["result"]
下面我们根据DaenWxHook发送数据的标准编码一个http服务器,这里我使用flask,编码如下:
"""
小小明的代码
CSDN主页:https://blog.csdn.net/as604049322
"""
__author__ = '小小明'
__time__ = '2022/8/16'
import datetime
import json
import time
from flask import Flask, request, jsonify
import send_wx_msg
wxid2nick_group, nick2wxid_group = send_wx_msg.fetch_group(True)
wxid2nick = send_wx_msg.fetch_firends(True)
app = Flask(__name__)
def receive_group_msg(from_wxid, wxid, date, msg):
if wxid:
if wxid not in wxid2nick:
row = send_wx_msg.fetch_obj_info(wxid)
wxid2nick[wxid] = (row["nick"], row["wxNum"])
nick, wxNum = wxid2nick[wxid]
print(f"收到来自 {wxid2nick_group[from_wxid]} 群 {nick} 的消息,时间:{date},微信号:{wxNum},内容:{msg}")
else:
print(f"{wxid2nick_group[from_wxid]} 群{date} 发生{msg}")
def receive_friend_msg(from_wxid, date, msg):
nick, wxNum = wxid2nick[from_wxid]
print("收到私聊消息", nick, date, wxNum, msg)
@app.route('/wechat/', methods=['get', 'post'])
def wechat():
data = json.loads(request.data.decode('u8'))
date = datetime.datetime.fromtimestamp(int(data["timestamp"]) // 1000)
if data['type'] == 'D0003':
data = data['data']
msg = data['msg']
from_wxid = data['fromWxid']
finalFromWxid = data['finalFromWxid']
# 消息类型:1|文本 3|图片 34|语音 42|名片 43|视频 47|动态表情 48|地理位置 49|分享链接或附件 2001|红包 2002|小程序 2003|群邀请 10000|系统消息
if data["msgType"] == 1:
if "@chatroom" in from_wxid:
if "暴富" in wxid2nick_group[from_wxid]:
receive_group_msg(from_wxid, finalFromWxid, date, msg)
else:
receive_friend_msg(from_wxid, date, msg)
return jsonify({"code": 200, "msg": "ok", "timestamp": str(int(time.time()))})
if __name__ == '__main__':
app.run(debug=True, port=8089)
这里我测试了群名包含暴富两字的群消息:
可以看到顺利的打印了相应的信息,后续我们可以决定将这些文字数据保存或制作自动回复机器人都可以。
可以看到注入器也是主要调用了别人写好的模块,并没有多少代码,个人觉得每次手动填写DaenWxHook.dll的位置有些麻烦,所以额外增加了编辑框3.内容 = 取当前目录 () + “\DaenWxHook.dll”
这行代码,只需要注入器和dll在同一目录下,自动填写的位置就是正确的。
接收消息的主要源码如下:
具体的读取都是读取内存指定位置:
这些存储位置都是通过之前在windows逆向中找到。
下载链接:https://pan.baidu.com/s/1pox5HmhHktga2C7xRSpeag?pwd=z28w
联系客服