提交 b19b9654 编写于 作者: L ljc545w

添加DWeChatRobot代码说明

上级 46acba91
#include "pch.h"
// 检查好友状态CALL1偏移
#define CheckFriendStatusCall1Offset 0x78861210 - 0x787A0000
// 检查好友状态CALL2偏移
#define CheckFriendStatusCall2Offset 0x03521CD0 - 0x02E20000
// 检查好友状态CALL3偏移
#define CheckFriendStatusCall3Offset 0x03521DC0 - 0x02E20000
// 检查好友状态CALL4偏移
#define CheckFriendStatusCall4Offset 0x0321FB90 - 0x02E20000
// 检查好友状态参数偏移
#define CheckFriendStatusParamOffset 0x0504F3BC - 0x02E20000
// 好友状态码HOOK地址偏移
#define CheckFriendStatusHookOffset 0x5E0830B3 - 0x5DB60000
// HOOK的CALL偏移
#define CheckFriendStatusNextCallOffset 0x5E083150 - 0x5DB60000
// HOOK跳转的地址偏移
#define CheckFriendStatusHookJmpBackOffset 0x5E0830B8 - 0x5DB60000
// HOOK的CALL地址
DWORD CheckFriendStatusNextCallAddress = GetWeChatWinBase() + CheckFriendStatusNextCallOffset;
// HOOK跳转的地址
DWORD CheckFriendStatusHookJmpBackAddress = GetWeChatWinBase() + CheckFriendStatusHookJmpBackOffset;
// 保存HOOK前的字节码,用于恢复
char OldAsmCode[5] = { 0 };
// 是否HOOK标志
BOOL CheckFriendStatusHooked = false;
// 保存好友状态码并作为调用返回
DWORD LocalFriendStatus = 0x0;
/*
* 用于内存中平衡堆栈
*/
struct FriendStatusParamStruct {
DWORD fill0 = 0x0;
DWORD fill1 = 0x0;
......@@ -28,12 +43,20 @@ struct FriendStatusParamStruct {
char nullbuffer[0xC] = { 0 };
};
/*
* 处理函数,参数不在状态码范围则不处理
* result:好友状态码
* return:void
*/
void dealVerifyUserResult(DWORD result) {
if (result < 0xB0 || result > 0xB5)
return;
LocalFriendStatus = result;
}
/*
* HOOK的具体实现,记录状态码并跳转到处理函数
*/
__declspec(naked) void doHookVerifyUserResult() {
__asm {
pushfd;
......@@ -49,6 +72,10 @@ __declspec(naked) void doHookVerifyUserResult() {
}
}
/*
* 开始HOOK好友状态
* return:void
*/
VOID HookFriendStatusCode(){
if (CheckFriendStatusHooked)
return;
......@@ -58,6 +85,10 @@ VOID HookFriendStatusCode(){
CheckFriendStatusHooked = true;
}
/*
* 取消HOOK好友状态
* return:void
*/
VOID UnHookFriendStatusCode() {
if (!CheckFriendStatusHooked)
return;
......@@ -67,19 +98,37 @@ VOID UnHookFriendStatusCode() {
CheckFriendStatusHooked = false;
}
/*
* 供外部调用的检查好友状态接口1,启动HOOK
* return:void
*/
VOID CheckFriendStatusInitRemote() {
HookFriendStatusCode();
}
/*
* 供外部调用的检查好友状态接口2,检查并返回状态码
* lparameter:要检查的联系人wxid保存地址
* return:DWORD,好友状态码
*/
DWORD CheckFriendStatusRemote(LPVOID lparameter) {
CheckFriendStatus((wchar_t*)lparameter);
return LocalFriendStatus;
}
/*
* 供外部调用的检查好友状态接口3,取消HOOK
* return:void
*/
VOID CheckFriendStatusFinishRemote() {
UnHookFriendStatusCode();
}
/*
* 检查好友状态的具体实现
* wxid:要检查的联系人wxid
* return:void
*/
VOID __stdcall CheckFriendStatus(wchar_t* wxid) {
LocalFriendStatus = 0x0;
DWORD WeChatWinBase = GetWeChatWinBase();
......
......@@ -34,7 +34,6 @@
#define IDA_BASE 0x10000000
BOOL SQLite3_Backup_Init_Patched = FALSE;
DWORD lpAddressBackupDB = 0x0;
typedef int(__cdecl* Sqlite3_open)(const char*, DWORD*);
typedef DWORD(__cdecl* Sqlite3_backup_init)(DWORD, const char*, DWORD, const char*);
......@@ -50,6 +49,10 @@ DWORD OffsetFromIdaAddr(DWORD idaAddr) {
return idaAddr - IDA_BASE;
}
/*
* 数据库备份函数
* return:int,无异常返回`0`,有异常返回非0值
*/
int __cdecl backupDb(
DWORD pDb, /* Database to back up */
const char* zFilename, /* Name of file to back up to */
......@@ -102,6 +105,9 @@ int __cdecl backupDb(
return rc;
}
/*
* 绕过加密数据库备份限制
*/
VOID PatchSQLite3_Backup_Init() {
if (SQLite3_Backup_Init_Patched)
return;
......@@ -118,6 +124,9 @@ VOID PatchSQLite3_Backup_Init() {
return;
}
/*
* 备份回调函数
*/
void XProgress(int a, int b)
{
#ifdef _DEBUG
......@@ -126,6 +135,12 @@ void XProgress(int a, int b)
return;
}
/*
* 数据库在线备份入口
* DbHandle:要备份的数据库句柄
* BackupFile:备份保存位置
* return:int,无异常返回`0`,有异常返回非0值
*/
int BackupSQLiteDB(DWORD DbHandle,const char* BackupFile)
{
DWORD wxBaseAddress = GetWeChatWinBase();
......@@ -163,7 +178,12 @@ int BackupSQLiteDB(DWORD DbHandle,const char* BackupFile)
return rc;
}
BOOL BackupSQLiteDBRemote(LPVOID lpParameter) {
/*
* 供外部调用的数据库在线备份接口
* lpParameter:`BackupStruct`类型结构体指针
* return:int,无异常返回`0`,有异常返回非0值
*/
int BackupSQLiteDBRemote(LPVOID lpParameter) {
BackupStruct* param = (BackupStruct*)lpParameter;
int rc = BackupSQLiteDB(param->DbHandle,(const char*)param->BackupFile);
return rc;
......
#pragma once
#include<windows.h>
/*
* 外部调用时传递的参数类型
* DbHandle:要备份的数据库句柄
* BackupFile:备份的保存位置
*/
struct BackupStruct {
DWORD DbHandle;
char* BackupFile;
};
int BackupSQLiteDB(DWORD DbHandle, const char* BackupFile);
extern "C" __declspec(dllexport) BOOL BackupSQLiteDBRemote(LPVOID lpParameter);
\ No newline at end of file
extern "C" __declspec(dllexport) int BackupSQLiteDBRemote(LPVOID lpParameter);
\ No newline at end of file
#include "pch.h"
// sqlite3_exec函数偏移
#define sqlite3_execOffset 0x66176570 - 0x64E20000
// sqlite3_callback函数指针
typedef int(*sqlite3_callback)(
void*,
int,
......@@ -9,6 +11,7 @@ typedef int(*sqlite3_callback)(
char**
);
// sqlite3_exec函数指针
typedef int(__cdecl* Sqlite3_exec)(
DWORD, /* The database on which the SQL executes */
const char*, /* The SQL to be executed */
......@@ -18,13 +21,24 @@ typedef int(__cdecl* Sqlite3_exec)(
);
DWORD WeChatWinBase = GetWeChatWinBase();
// sqlite3_exec函数地址
DWORD sqlite3_execAddr = WeChatWinBase + sqlite3_execOffset;
/*
* 外部调用时传递的参数结构
* ptrDb:数据库句柄
* ptrSql:保存sql的地址
*/
struct executeParams {
DWORD ptrDb;
DWORD ptrSql;
};
/*
* 保存查询结果的结构
* ColName:字段名;l_ColName:`ColName`字符数
* content:字段值;l_content:`content`字符数
*/
struct SQLResultStruct {
char* ColName;
DWORD l_ColName;
......@@ -32,14 +46,24 @@ struct SQLResultStruct {
DWORD l_content;
};
/*
* 外部调用时的返回类型
* SQLResultAddr:`SQLResult`首成员地址
* length:查询结果条数
*/
struct executeResult {
DWORD SQLResultAddr;
DWORD length;
};
// 外部调用时的具体返回对象
executeResult result = { 0 };
// 保存查询结果的二维动态数组
vector <vector<SQLResultStruct>> SQLResult;
/*
* 获取数据库信息的回调函数
*/
int GetDbInfo(void* data,int argc,char** argv,char** azColName) {
DbInfoStruct* pdata = (DbInfoStruct*)data;
TableInfoStruct tb = { 0 };
......@@ -84,6 +108,9 @@ int GetDbInfo(void* data,int argc,char** argv,char** azColName) {
return 0;
}
/*
* DLL内部查询用的回调函数,直接显示查询结果,用处不大
*/
int query(void* data, int argc, char** argv, char** azColName) {
for (int i = 0; i < argc; i++) {
string content = argv[i] ? UTF8ToGBK(argv[i]) : "NULL";
......@@ -93,6 +120,10 @@ int query(void* data, int argc, char** argv, char** azColName) {
return 0;
}
/*
* 外部调用时使用的回调函数,将结果存入`SQLResult`中
* return:int,执行成功返回`0`,执行失败返回非0值
*/
int select(void* data, int argc, char** argv, char** azColName) {
executeResult* pdata = (executeResult*)data;
vector<SQLResultStruct> tempStruct;
......@@ -118,6 +149,10 @@ int select(void* data, int argc, char** argv, char** azColName) {
return 0;
}
/*
* 清空查询结果,释放内存
* return:void
*/
void ClearResultArray() {
if (SQLResult.size() == 0)
return;
......@@ -140,12 +175,25 @@ void ClearResultArray() {
result.length = 0;
}
/*
* 执行SQL的入口函数
* ptrDb:数据库句柄
* sql:要执行的SQL
* callback:回调函数地址
* data:传递给回调函数的参数
* return:BOOL,执行成功返回`1`,执行失败返回`0`
*/
BOOL ExecuteSQL(DWORD ptrDb,const char* sql,DWORD callback,void* data) {
Sqlite3_exec p_Sqlite3_exec = (Sqlite3_exec)sqlite3_execAddr;
int status = p_Sqlite3_exec(ptrDb,sql, (sqlite3_callback)callback,data,0);
return status == 0;
}
/*
* 供外部调用的执行SQL接口
* lpParameter:`executeParams`类型结构体指针
* return:DWORD,如果SQL执行成功,返回`SQLResult`首成员地址,否则返回0
*/
DWORD ExecuteSQLRemote(LPVOID lpParameter){
ClearResultArray();
executeParams* sqlparam = (executeParams*)lpParameter;
......
......@@ -6,4 +6,4 @@ int select(void* data, int argc, char** argv, char** azColName);
int query(void* data, int argc, char** argv, char** azColName);
extern "C" __declspec(dllexport) DWORD ExecuteSQLRemote(LPVOID lpParameter);
BOOL ExecuteSQL(DWORD ptrDb, const char* sql, DWORD callback, void* data);
BOOL ExecuteSQL(DWORD ptrDb, const char* sql, DWORD callback, void* data);
\ No newline at end of file
#include "pch.h"
#include <vector>
using namespace std;
#define LeftTreeOffset 0x222F3BC
// 通讯录左树偏移
#define LeftTreeOffset 0x222F3BC
/*
* 保存单个好友信息的结构体
* wxIdAddr:wxid保存地址
* wxNumberAddr:微信号保存地址
* wxNickNameAddr:昵称保存地址
* wxRemarkAddr:备注保存地址
* WxFriendStructW:默认构造函数
*/
struct WxFriendStructW {
DWORD wxIdAddr;
DWORD wxNumberAddr;
......@@ -17,8 +25,13 @@ struct WxFriendStructW {
}
};
// 保存所有好友信息的动态数组
vector<WxFriendStructW> WxFriendList;
/*
* 供外部调用的获取好友列表接口1
* return:int,联系人数量
*/
int GetFriendListInit() {
GetFriendList();
#ifdef _DEBUG
......@@ -27,6 +40,10 @@ int GetFriendListInit() {
return WxFriendList.size();
}
/*
* 供外部调用的获取好友列表接口2
* return:DWORD,WxFriendList第一个成员地址
*/
DWORD GetFriendListRemote() {
if (WxFriendList.size() == 0)
return 0;
......@@ -37,11 +54,19 @@ DWORD GetFriendListRemote() {
return (DWORD)&WxFriendList[0].wxIdAddr;
}
/*
* 供外部调用的获取好友列表接口3,清空缓存
* return:void
*/
void GetFriendListFinish() {
WxFriendList.clear();
cout << WxFriendList.size() << endl;
}
/*
* 获取好友列表的具体实现
* return:void
*/
void __stdcall GetFriendList() {
#ifdef _DEBUG
wcout.imbue(locale("chs"));
......
#include "pch.h"
// 获取群成员CALL1偏移
#define GetChatRoomMembersCall1Offset 0x6246BBB0 - 0x61E20000
// 获取群成员CALL2偏移
#define GetChatRoomMembersCall2Offset 0x61EDF550 - 0x61E20000
// 获取群成员CALL3偏移
#define GetChatRoomMembersCall3Offset 0x622046D0 - 0x61E20000
// 清空缓存CALL偏移
#define DeleteGetChatRoomMembersCacheCallOffset 0x6246BDD0 - 0x61E20000
/*
* 外部调用的返回类型
* members:群成员wxid字符串,以`^`分隔
* length:members字符串长度
*/
struct ChatRoomInfoStruct {
wchar_t* members = NULL;
DWORD length = 0;
};
/*
* 外部调用时的具体返回对象
*/
ChatRoomInfoStruct chatroominfo = { 0 };
/*
* 供外部调用的获取群成员列表接口
* lparameter:保存群聊ID的地址
* return:DWORD,调用成功且群成员数量不为0,返回`chatroominfo`首地址,否则返回0
*/
DWORD GetChatRoomMembersRemote(LPVOID lparameter) {
wchar_t* chatroomid = (WCHAR*)lparameter;
if (chatroominfo.members != NULL) {
......@@ -31,6 +48,11 @@ DWORD GetChatRoomMembersRemote(LPVOID lparameter) {
return 0;
}
/*
* 获取群成员列表的具体实现
* chatroomid:群聊ID
* return:BOOL,成功返回`1`,失败返回`0`
*/
BOOL __stdcall GetChatRoomMembers(wchar_t* chatroomid) {
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD GetChatRoomMembersCall1 = WeChatWinBase + GetChatRoomMembersCall1Offset;
......
#include "pch.h"
// 联系人相关库
// 联系人相关库偏移
#define SqlHandleMicroMsgOffset 0x222F3FC
// 公众号相关库
// 公众号相关库偏移
#define SqlHandlePublicMsgOffset 0x22553D0
// 保存数据库信息的容器
vector<DbInfoStruct> dbs;
/*
* 根据数据库名从`dbs`中检索数据库句柄
* dbname:数据库名
* return:DWORD,如果检索成功,返回数据库句柄,否则返回`0`
*/
DWORD GetDbHandleByDbName(wchar_t* dbname) {
if (dbs.size() == 0)
GetDbHandles();
......@@ -17,12 +23,20 @@ DWORD GetDbHandleByDbName(wchar_t* dbname) {
return 0;
}
/*
* 供外部调用的获取数据库信息接口
* return:DWORD,`dbs`首个成员地址
*/
DWORD GetDbHandlesRemote() {
if (dbs.size() == 0)
GetDbHandles();
return (DWORD)dbs.data() ;
}
/*
* 获取数据库信息的具体实现
* return:void
*/
void GetDbHandles() {
dbs.clear();
DWORD WeChatWinBase = GetWeChatWinBase();
......
......@@ -2,6 +2,13 @@
#include<windows.h>
#include<vector>
/*
* 保存数据库单个表信息的结构体
* name:表名;l_name:`name`字符数
* tbl_name:表名;l_tbl_name:`tbl_name`字符数
* sql:建表语句;l_sql:`sql`字符数
* rootpage:表编号;l_rootpage:`rootpage`字符数
*/
struct TableInfoStruct {
char* name;
DWORD l_name;
......@@ -13,6 +20,14 @@ struct TableInfoStruct {
DWORD l_rootpage;
};
/*
* 保存数据库信息的结构体
* handle:数据库句柄
* dbname:数据库名
* l_dbname:`dbname`字符数
* tables:保存库中所有表信息的容器
* count:库中表的数量
*/
struct DbInfoStruct {
DWORD handle;
wchar_t* dbname;
......
#include "pch.h"
// 微信日志HOOK地址偏移
#define HookLogMsgInfoAddrOffset 0x103408A4 - 0x0FC40000
// HOOK的CALL偏移
#define HookLogMsgInfoNextCallOffset 0x11586DFC - 0x0FC40000
// HOOK的跳转地址偏移
#define HookLogMsgJmpBackOffset 0x103408A9 - 0x0FC40000
// 微信日志HOOK地址
DWORD HookLogMsgInfoAddr = GetWeChatWinBase() + HookLogMsgInfoAddrOffset;
// HOOK的CALL地址
DWORD NextCallAddr = GetWeChatWinBase() + HookLogMsgInfoNextCallOffset;
// HOOK的跳转地址
DWORD JmpBackAddr = GetWeChatWinBase() + HookLogMsgJmpBackOffset;
// 是否开启日志HOOK标志
BOOL LogMsgHooked = false;
// 保存HOOK前的指令用于恢复
char LogOldAsmCode[5] = { 0 };
/*
* 处理函数,打印日志信息
* msg:日志信息
* return:void
*/
VOID PrintMsg(DWORD msg) {
if (!msg)
return;
......@@ -19,6 +32,9 @@ VOID PrintMsg(DWORD msg) {
return;
}
/*
* HOOK的具体实现,拦截日志并调用处理函数
*/
__declspec(naked) void doprintmsg(){
__asm {
pushad;
......@@ -33,6 +49,10 @@ __declspec(naked) void doprintmsg(){
}
}
/*
* 开始HOOK微信日志
* return:void
*/
VOID HookLogMsgInfo() {
if (LogMsgHooked)
return;
......@@ -40,6 +60,10 @@ VOID HookLogMsgInfo() {
LogMsgHooked = true;
}
/*
* 停止HOOK微信日志
* return:void
*/
VOID UnHookLogMsgInfo() {
if (!LogMsgHooked)
return;
......
#include "pch.h"
#include <vector>
// 接收消息的HOOK地址偏移
#define ReceiveMessageHookOffset 0x034A4F60 - 0x02FE0000
// HOOK的CALL偏移
#define ReceiveMessageNextCallOffset 0x034A0CE0 - 0x02FE0000
/*
* 保存单条信息的结构
* messagetype:消息类型
* sender:发送者wxid;l_sender:`sender`字符数
* wxid:如果sender是群聊id,则此成员保存具体发送人wxid,否则与`sender`一致;l_wxid:`wxid`字符数
* message:消息内容,非文本消息是xml格式;l_message:`message`字符数
* filepath:图片、文件及其他资源的保存路径;l_filepath:`filepath`字符数
*/
struct messageStruct {
DWORD messagetype;
wchar_t* sender;
......@@ -16,16 +26,27 @@ struct messageStruct {
DWORD l_filepath;
};
// 保存多条信息的动态数组
vector<messageStruct> messageVector;
// 是否开启接收消息HOOK标志
BOOL ReceiveMessageHooked = false;
// 保存HOOK前的字节码,用于恢复
char OldReceiveMessageAsmCode[5] = { 0 };
// 接收消息HOOK地址
DWORD ReceiveMessageHookAddress = GetWeChatWinBase() + ReceiveMessageHookOffset;
// HOOK的CALL地址
DWORD ReceiveMessageNextCall = GetWeChatWinBase() + ReceiveMessageNextCallOffset;
// HOOK的跳转地址
DWORD JmpBackAddress = ReceiveMessageHookAddress + 0x5;
/*
* 消息处理函数,根据消息缓冲区组装结构并存入容器
* messageAddr:保存消息的缓冲区地址
* return:void
*/
VOID ReceiveMessage(DWORD messageAddr) {
// 此处用于区别是发送的还是接收的消息,发送的消息会被过滤
DWORD isSendMessage = *(DWORD*)(messageAddr + 0x3C);
if (isSendMessage)
return;
......@@ -67,12 +88,20 @@ VOID ReceiveMessage(DWORD messageAddr) {
messageVector.push_back(message);
}
/*
* 供外部调用的获取消息接口,优先返回较早消息
* return:DWORD,messageVector第一个成员地址
*/
DWORD GetHeadMessage() {
if (messageVector.size() == 0)
return 0;
return (DWORD)&messageVector[0].messagetype;
}
/*
* 供外部调用的删除消息接口,用于删除messageVector第一个成员,每读一条需要执行一次
* return:void
*/
VOID PopHeadMessage() {
if (messageVector.size() == 0)
return;
......@@ -88,6 +117,9 @@ VOID PopHeadMessage() {
messageVector.erase(k);
}
/*
* HOOK的具体实现,接收到消息后调用处理函数
*/
_declspec(naked) void dealReceiveMessage() {
__asm {
pushad;
......@@ -103,6 +135,10 @@ _declspec(naked) void dealReceiveMessage() {
}
}
/*
* 开始接收消息HOOK
* return:void
*/
VOID HookReceiveMessage() {
if (ReceiveMessageHooked)
return;
......@@ -110,6 +146,10 @@ VOID HookReceiveMessage() {
ReceiveMessageHooked = TRUE;
}
/*
* 停止接收消息HOOK
* return:void
*/
VOID UnHookReceiveMessage() {
if (!ReceiveMessageHooked)
return;
......
#include "pch.h"
#include <vector>
// 保存个人信息的字符串
wstring selfinfo = L"";
/*
* 外部调用时的返回类型
* message:selfinfo.c_str()
* length:selfinfo字符串长度
*/
struct SelfInfoStruct {
DWORD message;
DWORD length;
} ret;
/*
* 供外部调用的获取个人信息接口
* return:DWORD,ret的首地址
*/
DWORD GetSelfInfoRemote() {
DWORD WeChatWinBase = GetWeChatWinBase();
vector<DWORD> SelfInfoAddr = {
......@@ -90,6 +99,10 @@ DWORD GetSelfInfoRemote() {
return (DWORD)&ret;
}
/*
* 删除个人信息缓存
* return:void
*/
VOID DeleteSelfInfoCacheRemote() {
if (ret.length) {
ZeroMemory((wchar_t*)ret.message, ret.length*2 + 2);
......
#include "pch.h"
// 发送文章CALL1偏移
#define SendArticleCall1Offset 0x0F7454F0 - 0x0F6B0000
// 发送文章CALL2偏移
#define SendArticleCall2Offset 0x0FA41F80 - 0x0F6B0000
// 发送文章CALL3偏移
#define SendArticleCall3Offset 0x0F7794A0 - 0x0F6B0000
// 发送文章CALL4偏移
#define SendArticleCall4Offset 0x0FA42150 - 0x0F6B0000
// 发送文章CALL参数偏移
#define SendArticleParamOffset 0x118EEC34 - 0x0F6B0000
// 清空缓存CALL1偏移
#define SendArticleClearCacheCall1Offset 0x0FCEB4F0 - 0x0F6B0000
// 清空缓存CALL2偏移
#define SendArticleClearCacheCall2Offset 0x0F744200 - 0x0F6B0000
/*
* 外部调用时传递的参数结构
* wxid:接收人的保存地址
* title:文章标题的保存地址
* abstract:文章摘要的保存地址
* url:文章链接的保存地址
*/
struct SendArticleStruct {
DWORD wxid;
DWORD title;
......@@ -16,6 +30,11 @@ struct SendArticleStruct {
DWORD url;
};
/*
* 供外部调用的发送文章消息接口
* lparameter:SendArticleStruct类型结构体指针
* return:void
*/
VOID SendArticleRemote(LPVOID lparameter) {
SendArticleStruct* sas = (SendArticleStruct*)lparameter;
wchar_t* wxid = (wchar_t*)sas->wxid;
......@@ -25,6 +44,10 @@ VOID SendArticleRemote(LPVOID lparameter) {
SendArticle(wxid,title,abstract,url);
}
/*
* 获取自己的wxid保存地址
* return:DWORD,个人wxid保存地址
*/
DWORD GetSelfWxIdAddr() {
DWORD baseAddr = GetWeChatWinBase() + 0x222EB3C;
char wxidbuffer[0x100] = { 0 };
......@@ -41,6 +64,14 @@ DWORD GetSelfWxIdAddr() {
return SelfWxIdAddr;
}
/*
* 发送文章消息的具体实现
* wxid:消息接收人wxid
* title:文章标题
* abstract:文章摘要
* url:文章链接
* return:BOOL,成功返回`1`,失败返回`0`
*/
BOOL __stdcall SendArticle(wchar_t* wxid,wchar_t* title, wchar_t* abstract, wchar_t* url) {
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD SendArticleCall1 = WeChatWinBase + SendArticleCall1Offset;
......
#include "pch.h"
// 发送艾特消息CALL偏移
#define SendAtTextCallOffset 0x6782E7B0 - 0x67370000
// 清空缓存CALL偏移
#define DeleteAtTextCacheCallOffset 0x67404200 - 0x67370000
/*
* 外部调用时传递的参数结构
* chatroomid:群聊ID的保存地址
* wxidlist:艾特列表的保存地址,真实类型应当是`wchar_t**`
* wxmsg:发送的内容保存地址
* length:艾特的人数量,用于指示wxidlist长度
*/
struct SendAtTextStruct
{
DWORD chatroomid;
DWORD wxid;
DWORD wxidlist;
DWORD wxmsg;
DWORD length;
};
/*
* 内存中使用的参数结构
* 构造与Release版本vector动态数组相仿
* 成员类型:`WxString`
* AtUser:类似`vector`的`data`方法,保存数组首个成员的地址
* addr_end1:数组尾地址
* addr_end2:数组尾地址
*/
struct AtStruct {
DWORD AtUser;
DWORD addr_end1;
DWORD addr_end2;
};
/*
* 供外部调用的发送艾特消息接口
* lpParameter:SendAtTextStruct类型结构体指针
* return:void
*/
void SendAtTextRemote(LPVOID lpParameter) {
SendAtTextStruct* rp = (SendAtTextStruct*)lpParameter;
wchar_t* wsChatRoomId = (WCHAR*)rp->chatroomid;
......@@ -24,12 +46,21 @@ void SendAtTextRemote(LPVOID lpParameter) {
if (rp->length == 0)
return;
else if(rp->length == 1)
SendAtText(wsChatRoomId, (DWORD*)&rp->wxid, wsTextMsg,rp->length);
SendAtText(wsChatRoomId, (DWORD*)&rp->wxidlist, wsTextMsg,rp->length);
else
SendAtText(wsChatRoomId, (DWORD*)rp->wxid, wsTextMsg, rp->length);
SendAtText(wsChatRoomId, (DWORD*)rp->wxidlist, wsTextMsg, rp->length);
}
/*
* 发送艾特消息的具体实现
* wsChatRoomId:群聊ID
* wsWxId:艾特的人列表
* wsTextMsg:发送的消息内容
* length:艾特的人数量
* return:void
*/
void __stdcall SendAtText(wchar_t* wsChatRoomId, DWORD wsWxId[], wchar_t* wsTextMsg,int length) {
// +1的作用是补充一个空结构体,将`AtStruct`尾地址设定为空结构的首地址即可
WxString* AtUsers = new WxString[length + 1];
wstring AtMessage = L"";
int querySuccess = 0;
......
#include "pch.h"
// 发送名片的CALL偏移
#define SendCardCallOffset 0x644FE7B0 - 0x64040000
// 清空缓存的CALL偏移
#define DeleteCardCacheCallOffset 0x640D4200 - 0x64040000
/*
* 外部调用时提供的参数结构
* receiver:名片消息接收人wxid保存地址
* sharedwxid:被推荐人的wxid保存地址
* nickname:名片显示的昵称保存地址
*/
struct SendCardStruct {
DWORD receiver;
DWORD sharedwxid;
DWORD nickname;
};
/*
* 供外部调用的发送名片接口
* lparameter:SendCardStruct类型结构体指针
* return:void
*/
VOID SendCardRemote(LPVOID lparameter) {
SendCardStruct* scs = (SendCardStruct*)lparameter;
wchar_t* receiver = (WCHAR*)scs->receiver;
......@@ -17,6 +30,13 @@ VOID SendCardRemote(LPVOID lparameter) {
SendCard(receiver,sharedwxid,nickname);
}
/*
* 发送名片消息的具体实现
* receiver:消息接收人wxid
* sharedwxid:被推荐人wxid
* nickname:名片显示的昵称
* return:BOOL,发送成功返回`0`,发送失败返回`1`
*/
BOOL __stdcall SendCard(wchar_t* receiver, wchar_t* sharedwxid, wchar_t* nickname) {
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD SendCardCall = WeChatWinBase + SendCardCallOffset;
......
#include "pch.h"
// 发送文件CALL1偏移
#define SendFileCall1Offset (0x67A71DC0 - 0x67370000)
// 发送文件CALL2偏移
#define SendFileCall2Offset (0x68D81C83 - 0x67370000)
// 发送文件CALL3偏移
#define SendFileCall3Offset (0x68D8047A - 0x67370000)
// 发送文件CALL4偏移
#define SendFileCall4Offset (0x67702260 - 0x67370000)
// 发送文件参数偏移
#define SendFileParamsOffset (0x6959F170 - 0x67370000)
// 清空缓存CALL偏移
#define DeleteSendFileCacheCallOffset (0x67404200 - 0x67370000)
/*
* 外部调用时传递的参数结构
* wxid:wxid的保存地址
* filepath:文件绝对路径的保存地址
*/
struct FileParamStruct {
DWORD wxid;
DWORD filepath;
};
/*
* 内存中使用的参数结构
* type:消息类型,文件消息为3
* buffer:文件绝对路径
* length:绝对路径字符数
* maxLength:绝对路径最大字节数
* fill:占位用空缓冲区
* WxFileStruct:默认构造函数
*/
struct WxFileStruct {
int type = 3;
wchar_t* buffer;
......@@ -27,11 +46,22 @@ struct WxFileStruct {
}
};
/*
* 供外部调用的发送文件消息接口
* lpParamStruct:FileParamStruct类型结构体指针
* return:void
*/
void SendFileRemote(LPVOID lpParamStruct) {
FileParamStruct* params = (FileParamStruct*)lpParamStruct;
SendFile((WCHAR*)params->wxid, (WCHAR*)params->filepath);
}
/*
* 发送文件消息的具体实现
* receiver:接收人wxid
* FilePath:文件绝对路径
* return:void
*/
void __stdcall SendFile(wchar_t* receiver, wchar_t* FilePath) {
WxBaseStruct pReceiver(receiver);
WxBaseStruct pFilePath(FilePath);
......
#include "pch.h"
// 发送图片CALL1偏移
#define SendImageCall1Offset (0x6740A1C0 - 0x67370000)
// 发送图片CALL2偏移
#define SendImageCall2Offset (0x67A71DC0 - 0x67370000)
// 发送图片CALL3偏移
#define SendImageCall3Offset (0x6782E160 - 0x67370000)
// 清空缓存的CALL偏移
#define DeleteSendImageCacheCallOffset (0x67404200 - 0x67370000)
/*
* 外部调用时传递的参数结构
* wxid:保存wxid的地址
* imagepath:保存图片绝对路径的地址
*/
struct ImageParamStruct {
DWORD wxid;
DWORD imagepath;
};
/*
* 供外部调用的发送图片消息接口
* lpParamStruct:ImageParamStruct类型结构体指针
* return:void
*/
void SendImageRemote(LPVOID lpParamStruct) {
ImageParamStruct* params = (ImageParamStruct*)lpParamStruct;
SendImage((WCHAR*)params->wxid, (WCHAR*)params->imagepath);
}
/*
* 发送图片消息的具体实现
* receiver:接收人wxid
* ImagePath:图片绝对路径
* return:void
*/
void __stdcall SendImage(wchar_t* receiver, wchar_t* ImagePath) {
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD SendImageCall1 = WeChatWinBase + SendImageCall1Offset;
......
#include "pch.h"
// 发送文本消息的CALL偏移
#define SendTextCallOffset 0x6782E7B0 - 0x67370000
// 清空缓存的CALL偏移
#define DeleteTextCacheCallOffset 0x67404200 - 0x67370000
/*
* 外部调用时传递的参数结构
* wxid:wxid保存地址
* wxmsg:发送的内容保存地址
*/
struct SendTextStruct
{
DWORD wxid;
DWORD wxmsg;
};
/*
* 供外部调用的发送文本消息接口
* lpParameter:SendTextStruct类型结构体指针
* return:void
*/
void SendTextRemote(LPVOID lpParameter) {
SendTextStruct* rp = (SendTextStruct*)lpParameter;
wchar_t* wsWxId = (WCHAR*)rp->wxid;
......@@ -16,6 +28,12 @@ void SendTextRemote(LPVOID lpParameter) {
SendText(wsWxId, wsTextMsg);
}
/*
* 发送文本消息的具体实现
* wsWxId:接收人wxid
* wsTextMsg:发送的消息内容
* return:void
*/
void __stdcall SendText(wchar_t* wsWxId, wchar_t* wsTextMsg) {
WxBaseStruct wxWxid(wsWxId);
WxBaseStruct wxTextMsg(wsTextMsg);
......
......@@ -3,22 +3,40 @@
#include <string>
#include <vector>
// 获取好友信息CALL0偏移
#define GetUserInfoCall0Offset 0x6740A000 - 0x67370000
// 获取好友信息CALL1偏移
#define GetUserInfoCall1Offset 0x679C9840 - 0x67370000
// 获取好友信息CALL2偏移
#define GetUserInfoCall2Offset 0x67A71DC0 - 0x67370000
// 获取好友信息CALL3偏移
#define GetUserInfoCall3Offset 0x677724A0 - 0x67370000
// 清空缓存CALL1偏移
#define DeleteUserInfoCacheCall1Offset 0x67775990 - 0x67370000
// 清空缓存CALL2偏移
#define DeleteUserInfoCacheCall2Offset 0x679CA340 - 0x67370000
/*
* 外部调用时的返回类型
* message:wUserInfo.c_str()
* length:wUserInfo字符串长度
*/
struct GetUserInfoStruct {
DWORD message;
DWORD length;
};
// 保存好友信息的字符串
wstring wUserInfo = L"";
// 外部调用时的具体返回对象
GetUserInfoStruct ret = { 0 };
/*
* 根据缓冲区内容拼接好友信息
* address:缓冲区地址
* return:void
*/
VOID WxUserInfo(DWORD address) {
vector<DWORD> InfoType{
address + 0x10,
......@@ -64,7 +82,11 @@ VOID WxUserInfo(DWORD address) {
#endif
}
/*
* 供外部调用的获取好友信息接口
* lparamter:保存好友wxid的地址
* return:DWORD,`ret`的首地址
*/
DWORD GetWxUserInfoRemote(LPVOID lparamter) {
wchar_t* userwxid = (wchar_t*)lparamter;
......@@ -76,6 +98,10 @@ DWORD GetWxUserInfoRemote(LPVOID lparamter) {
return (DWORD)&ret;
}
/*
* 供外部调用的清空好友信息缓存的接口
* return:void
*/
VOID DeleteUserInfoCacheRemote() {
if (ret.length) {
ZeroMemory((wchar_t*)ret.message, ret.length * 2 + 2);
......@@ -84,6 +110,11 @@ VOID DeleteUserInfoCacheRemote() {
}
}
/*
* 根据wxid获取好友信息的具体实现
* wxid:好友wxid
* return:BOOL,成功返回`1`,失败返回`0`
*/
BOOL __stdcall GetUserInfoByWxId(wchar_t* wxid) {
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD WxGetUserInfoCall0 = WeChatWinBase + GetUserInfoCall0Offset;
......@@ -131,6 +162,11 @@ BOOL __stdcall GetUserInfoByWxId(wchar_t* wxid) {
return isSuccess;
}
/*
* 根据wxid获取联系人昵称,主要用于发送艾特消息接口
* wxid:联系人wxid
* return:wchar_t*,获取到的wxid
*/
wchar_t* __stdcall GetUserNickNameByWxId(wchar_t* wxid) {
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD WxGetUserInfoCall0 = WeChatWinBase + GetUserInfoCall0Offset;
......
......@@ -3,6 +3,11 @@
#include "pch.h"
// 当使用预编译的头时,需要使用此源文件,编译才能成功。
/*
* 创建一个控制台窗口
* return:BOOL,成功返回`0`,失败返回`1`
*/
BOOL CreateConsole(void) {
if (AllocConsole()) {
AttachConsole(GetCurrentProcessId());
......@@ -16,10 +21,17 @@ BOOL CreateConsole(void) {
return 1;
}
/*
* 获取`WeChatWin.dll`基址
* return:DWORD,`WeChatWin.dll`模块基址
*/
DWORD GetWeChatWinBase() {
return (DWORD)GetModuleHandleA("WeChatWin.dll");
}
/*
* 将宽字节字符串转换成`std::string`
*/
void Wchar_tToString(std::string& szDst, wchar_t* wchar)
{
wchar_t* wText = wchar;
......@@ -31,6 +43,9 @@ void Wchar_tToString(std::string& szDst, wchar_t* wchar)
delete[]psText;// psText的清除
}
/*
* 将UTF8编码数据转换为GBK编码
*/
string UTF8ToGBK(const std::string& strUTF8)
{
int len = MultiByteToWideChar(CP_UTF8, 0, strUTF8.c_str(), -1, NULL, 0);
......@@ -49,6 +64,13 @@ string UTF8ToGBK(const std::string& strUTF8)
return strTemp;
}
/*
* 对任意地址添加HOOK
* dwHookAddr:HOOK的目标地址
* dwJmpAddress:跳转到的地址
* originalRecieveCode:保存旧指令的数组
* return:void
*/
void HookAnyAddress(DWORD dwHookAddr, LPVOID dwJmpAddress,char* originalRecieveCode)
{
//组装跳转数据
......@@ -72,6 +94,12 @@ void HookAnyAddress(DWORD dwHookAddr, LPVOID dwJmpAddress,char* originalRecieveC
VirtualProtect((LPVOID)dwHookAddr, 5, OldProtext, &OldProtext);
}
/*
* 对任意地址取消HOOK
* dwHookAddr:HOOK的目标地址
* originalRecieveCode:保存旧指令的数组
* return:void
*/
void UnHookAnyAddress(DWORD dwHookAddr, char* originalRecieveCode)
{
DWORD OldProtext = 0;
......@@ -80,11 +108,23 @@ void UnHookAnyAddress(DWORD dwHookAddr, char* originalRecieveCode)
VirtualProtect((LPVOID)dwHookAddr, 5, OldProtext, &OldProtext);
}
/*
* 取消所有HOOK
* return:void
*/
void UnHookAll() {
UnHookLogMsgInfo();
UnHookReceiveMessage();
return;
}
/*
* 将单字符替换为指定的字符串
* source:源字符串
* replaced:被替换的单字符
* replaceto:替换成的字符串
* return:std::wstring,替换后的字符串
*/
wstring wreplace(wstring source, wchar_t replaced, wstring replaceto) {
wstring temp = L"";
wchar_t* buffer = (wchar_t*)source.c_str();
......
......@@ -31,8 +31,18 @@
#endif //PCH_H
using namespace std;
// 对于导出函数,需要使用此宏修饰
#define DLLEXPORT extern "C" __declspec(dllexport)
/*
* 微信中的基础数据结构
* buffer:UNICODE字符串
* length:`buffer`字符数
* maxLength:`buffer`最大字符数
* fill1:占位成员1,默认为0
* fill2:占位成员2,默认为0
* WxBaseStruct:默认构造函数
*/
struct WxBaseStruct
{
wchar_t* buffer;
......@@ -50,6 +60,9 @@ struct WxBaseStruct
}
};
/*
* 不使用构造函数的微信基础数据结构,使用频率较低
*/
struct WxString
{
wchar_t* buffer = NULL;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册