今天来讲一下PC微信HOOK生成彩色二维码,HOOK端使用vc++,生成二维端用的是QT,协议使用Socket+Protobuf(你们可以使用其它协议),先看二维码效果:
Protobuf文件内容:
syntax = "proto3";
package WeChatHelper;
//通用数据包
message Packet{
int32 cmdId=1;//指令ID
int32 len=2;//数据长度
bytes data=3;//数据
}
//字符串数据包
message PacketString{
string stringOne=1;//字符
string stringTwo=2;//字符
}
//字符串数和数字据包
message PacketStringInt{
string stringOne=1;//字符
int32 intOne=2;//数字
}
//个人信息
message Information
{
string wxid=1; //微信ID
string account=2; //自定义账号
bytes remark=3;
bytes nickname=4; //昵称
string device=5; //登陆设备
string phone=6; //绑定手机号
string email=7; //绑定邮箱
string sex=8; //性别
string nation=9; //国籍
string province=10; //省份
string city=11; //城市
bytes signName=12; //签名
string headerBig=13; //大头像
string headerSmall=14; //小头像
}
// 发送回服务器端的消息
message ChatRecordInfo
{
int64 msgId =1;//消息ID
int32 isOwner = 2; // 是否自己发的消息:0=否,1=是
int32 msgType = 3; // 消息类型
int32 msgSource = 4; // 消息来源:0=好友消息,1=群消息
string wxid =5; // 发送人微信ID
string sender =6 ; // 群ID
bytes content=7; // 消息内容
string md5 =8 ;//md5值
string thumb =9 ; // 缩微图
string image =10 ; // 大图
}
//微信好友结构体
message FriendInfo
{
string wxid=1;//微信Id
string alias=2;//微信号
bytes nickName=3;//昵称
bytes remark=4;//备注
string pySort=5;//拼音排序
int32 type=6;//类型
int32 reserved2=7;//
int32 reserved5=8;//
string imgSmall=9;//
string imgBig=10;//
string chatRoomNames=11;//
bytes chatRoomNicks=12;//
}
//群At消息结构
message AtMsg
{
string chatRoomId=1;//群ID
string memberId=2;//@的成员Id
bytes memberNick=3;//成员昵称
string content=4;//@信息内容
}
//XML消息结构体
message XmlMessage
{
int32 type = 1;// 0x5是链接分享,0x21是小程序分享
string recverWxid=2;// 接收的微信ID
string fromWxid=3;//自己的微信ID
string url=4;//链接
string title=5;//标题
string des=6;//描述
string thumbUrl=7; //缩微图
}
二维码是由网址生成的,HOOK端获取网址的代码(VC++):
#define WX_QRCODE_URL_CODE 0x1874FA0//二维码URL值
#define GOTO_QRCODE_1 0x2552D0 //跳转到二维码
#define GOTO_QRCODE_2 0x385100 //跳转到二维码
// 函数说明: 获取WeChatWin基址
DWORD GetWeChatWinBase()
{
return (DWORD)GetModuleHandle(TEXT("WeChatWin.dll"));
}
/*
跳转到微信登陆二维码窗口
*/
void GotoQrCode()
{
// 获取微信基址
DWORD winAddress = GetWeChatWinBase();
DWORD dwIsLogin = winAddress + LoginSign_Offset;
if (*(DWORD*)dwIsLogin == 1) {
return; // 已经登陆,不再跳转
}
//二维码跳转CALL1
DWORD dwCallAddr1 = winAddress + GOTO_QRCODE_1;
//二维码跳转CALL2
DWORD dwCallAddr2 = winAddress + GOTO_QRCODE_2;
__asm {
pushad
call dwCallAddr1;
mov ecx, eax;
call dwCallAddr2;
popad
}
}
//发送二维码网址
void SendQrCodeUrl()
{
GotoQrCode();
// 获取二维码值
CHAR qrCodeUrl[0x100] = { 0 };
DWORD pCode = 0;
while (TRUE) {
pCode = *((DWORD *)(GetWeChatWinBase() + WX_QRCODE_URL_CODE));
if (pCode && strlen((CHAR*)pCode) > 0) {
sprintf_s(qrCodeUrl, "http://weixin.qq.com/x/%s", (CHAR*)pCode);
break;
}
}
//向服务器发送二维网址
WeChatHelper::Packet packet;
packet.set_cmdid(WM_ShowQrPicture);
packet.set_data(qrCodeUrl);
packet.set_len(strlen(qrCodeUrl));
mTcpClientSocket->sendPack(packet);
}
QT端生成二维码要用到QrCode库,下载地址:https://download.csdn.net/download/keepmoving0407/13183413
QT端生成二维码代码:
//接收二维码数据包
WeChatHelper::Packet packet;
packet.ParseFromArray(data, len);
int cmdid = packet.cmdid();
switch(cmdid)
{
case WM_ShowQrPicture:
{
QString qrcUrl=QString::fromUtf8(packet.data().c_str());
qDebug()<<"qrcode:"<0)
{
mqrcodeWidget->qrcodeImg->setImage(pix);
mqrcodeWidget->show();
mqrcodeWidget->raise();
}
break;
}
}
生成二维码函数:
#include "QRCode/qrencode.h"
//通过网址创建二维码图像
QPixmap createQRCode(const QString &text)
{
int margin = 2;
if (text.length() == 0)
{
return QPixmap();
}
QRcode *qrcode = QRcode_encodeString(text.toLocal8Bit(), 2, QR_ECLEVEL_H, QR_MODE_8, 0);
if (qrcode == NULL) {
return QPixmap();
}
unsigned char *p, *q;
p = NULL;
q = NULL;
int x, y, bit;
int realwidth;
realwidth = qrcode->width;
QPixmap pix(realwidth, realwidth);
QPainter painter;
painter.begin(&pix);
painter.fillRect(QRect(0,0,realwidth,realwidth),QColor(245,245,245));
p = qrcode->data;
//二维码色彩模板图像
QImage image(":/images/base/qrcode_bg.png");
image=image.scaledToWidth(qrcode->width);
//qDebug()<<"qrcode_width"<width;
for(y=0; ywidth; y++)
{
bit = 3;
q += margin / 4;
bit = 3 - (margin % 4);
for(x=0; xwidth; x++)
{
QColor color=image.pixelColor(x,y);
if ((*p & 1) << bit)
{
//黑点从图像中取色
painter.fillRect(QRect(x, y, 1,1),color);
}
else
{
//白色区域
painter.fillRect(QRect(x, y, 1,1),QColor(245,245,245));
}
bit--;
if(bit < 0)
{
q++;
bit = 3;
}
p++;
}
}
free(qrcode);
painter.end();
//二维码边框
QPixmap qrcodeFrame(":/images/base/qrcode_frame.png");
//二维码Logo
QPixmap qrcodeLogo(":/images/base/qrc_logo.png");
qrcodeFrame=qrcodeFrame.scaled(280,280, Qt::KeepAspectRatio,
Qt::SmoothTransformation);
pix=pix.scaledToWidth(200);
QPixmap returnPix(280,280);
painter.begin(&returnPix);
painter.fillRect(QRect(0,0,280,280),QColor(245,245,245));
painter.drawPixmap(QRect(0,0,280,280),qrcodeFrame,QRect(0,0,280,280));
painter.drawPixmap(QRect(40,40,200,200),pix,QRect(0,0,200,200));
int logoPos=(280-64)/2;
painter.drawPixmap(QRect(logoPos,logoPos,64,64),qrcodeLogo,QRect(0,0,64,64));
painter.end();
return returnPix.scaledToWidth(280);
}
代码中用到的三个图像在QrCode库中。
技术交流QQ:150311852