提交 b19b9654 编写于 作者: L ljc545w

添加DWeChatRobot代码说明

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