'feat:base'

This commit is contained in:
ttttupup 2024-04-06 11:45:10 +08:00
parent a90d667799
commit c2367968ec
20 changed files with 1084 additions and 0 deletions

6
.gitmodules vendored
View File

@ -2,3 +2,9 @@
path = app/3rdparty/spdlog path = app/3rdparty/spdlog
url = https://github.com/gabime/spdlog.git url = https://github.com/gabime/spdlog.git
branch = v1.x branch = v1.x
[submodule "app/3rdparty/json"]
path = app/3rdparty/json
url = https://github.com/nlohmann/json
[submodule "app/3rdparty/Detours"]
path = app/3rdparty/Detours
url = https://github.com/microsoft/Detours

1
app/3rdparty/Detours vendored Submodule

@ -0,0 +1 @@
Subproject commit 4b8c659f549b0ab21cf649377c7a84eb708f5e68

1
app/3rdparty/json vendored Submodule

@ -0,0 +1 @@
Subproject commit 199dea11b17c533721b26249e2dcaee6ca1d51d3

View File

@ -0,0 +1,11 @@
#ifndef BASE_NONCOPYABLE_H_
#define BASE_NONCOPYABLE_H_
class NonCopyable {
protected:
NonCopyable() {}
~NonCopyable() {}
NonCopyable(const NonCopyable&) = delete;
NonCopyable& operator=(const NonCopyable&) = delete;
};
#endif

View File

@ -0,0 +1,22 @@
#include "chat_controller.h"
namespace wxhelper {
std::string ChatController::SendTextMsg(std::string, std::string) {
return std::string();
}
std::string ChatController::SendImageMsg(std::string, std::string) {
return std::string();
}
std::string ChatController::SendFileMsg(std::string, std::string) {
return std::string();
}
std::string ChatController::SendAtText(std::string, std::string) {
return std::string();
}
std::string ChatController::SendMultiAtText(std::string, std::string) {
return std::string();
}
std::string ChatController::ForwardMsg(std::string, std::string) {
return std::string();
}
} // namespace wxhelper

View File

@ -0,0 +1,28 @@
#ifndef WXHELPER_CHAT_CONTROLLER_H_
#define WXHELPER_CHAT_CONTROLLER_H_
#include "http_controller.h"
#include "spdlog/spdlog.h"
#include <Windows.h>
namespace wxhelper {
class ChatController : public http::HttpController<ChatController> {
public:
PATHS_BEGIN
ADD_PATH("/api/sendTextMsg", SendTextMsg);
ADD_PATH("/api/sendImagesMsg", SendImageMsg);
ADD_PATH("/api/sendFileMsg", SendFileMsg);
ADD_PATH("/api/sendAtText", SendAtText);
ADD_PATH("/api/sendMultiAtText", SendMultiAtText);
ADD_PATH("/api/forwardMsg", ForwardMsg);
PATHS_END
public:
static std::string SendTextMsg(std::string, std::string);
static std::string SendImageMsg(std::string, std::string);
static std::string SendFileMsg(std::string, std::string);
static std::string SendAtText(std::string, std::string);
static std::string SendMultiAtText(std::string, std::string);
static std::string ForwardMsg(std::string, std::string);
};
} // namespace wxhelper
#endif

View File

@ -0,0 +1,70 @@
#include "client_socket.h"
#include <WS2tcpip.h>
#include <Winsock2.h>
#include "spdlog/spdlog.h"
namespace wxhelper {
SocketInit::SocketInit() {
WSADATA was_data = {0};
if (WSAStartup(MAKEWORD(2, 2), &was_data)) {
valid_ = true;
}
}
SocketInit::~SocketInit() {
if (valid_) {
WSACleanup();
}
}
TcpClient::TcpClient(std::string ip, int port) : ip_(ip), port_(port) {}
void TcpClient::SendAndCloseSocket(std::string& content) {
SOCKET client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (client_socket < 0) {
SPDLOG_ERROR("socket init fail");
return;
}
BOOL status = false;
sockaddr_in client_addr;
memset(&client_addr, 0, sizeof(client_addr));
client_addr.sin_family = AF_INET;
client_addr.sin_port = htons((u_short)port_);
InetPtonA(AF_INET, ip_.c_str(), &client_addr.sin_addr.s_addr);
if (connect(client_socket, reinterpret_cast<sockaddr*>(&client_addr),
sizeof(sockaddr)) < 0) {
SPDLOG_ERROR("socket connect fail. host:{} , port:{},", ip_, port_);
closesocket(client_socket);
return;
}
char recv_buf[1024] = {0};
int ret =
send(client_socket, content.c_str(), static_cast<int>(content.size()), 0);
if (ret < 0) {
SPDLOG_ERROR("socket send fail ,ret:{}", ret);
closesocket(client_socket);
return;
}
ret = shutdown(client_socket, SD_SEND);
if (ret == SOCKET_ERROR) {
SPDLOG_ERROR("shutdown failed with erro:{}", ret);
closesocket(client_socket);
return;
}
do {
ret = recv(client_socket, recv_buf, sizeof(recv_buf), 0);
if (ret > 0) {
} else if (ret == 0) {
SPDLOG_INFO("Connection closed");
closesocket(client_socket);
return;
} else {
SPDLOG_ERROR("recv failed with error:{}", WSAGetLastError());
closesocket(client_socket);
return;
}
} while (ret > 0);
}
} // namespace wxhelper

View File

@ -0,0 +1,30 @@
#ifndef WXHELPER_CLIENT_SOCKET_H_
#define WXHELPER_CLIENT_SOCKET_H_
#include <string>
#include "noncopyable.h"
namespace wxhelper {
class SocketInit : public NonCopyable {
public:
SocketInit();
~SocketInit();
bool valid_{false};
};
static SocketInit kSocketInit;
class TcpClient : public NonCopyable {
public:
TcpClient()=default;
TcpClient(std::string ip, int port);
void SendAndCloseSocket(std::string& content);
private:
std::string ip_;
int port_;
};
} // namespace wxhelper
#endif

145
app/wxhelper/src/hook.cc Normal file
View File

@ -0,0 +1,145 @@
#include <WinSock2.h>
#include "hook.h"
#include "base64.h"
#include "client_socket.h"
#include "config.h"
#include "detours.h"
#include "http_client.h"
#include "nlohmann/json.hpp"
#include "offset.h"
#include "spdlog/spdlog.h"
#include "thread_pool.h"
#include "utils.h"
#include "wechat_interface.h"
#include "wxutils.h"
namespace hook {
VOID SendTcpMsgCallback(PTP_CALLBACK_INSTANCE instance, PVOID context,
PTP_WORK Work) {
wechat::InnerMessageStruct *msg = (wechat::InnerMessageStruct *)context;
if (msg == NULL) {
SPDLOG_INFO("add work:msg is null");
return;
}
std::unique_ptr<wechat::InnerMessageStruct> sms(msg);
nlohmann::json j_msg = nlohmann::json::parse(
msg->buffer, msg->buffer + msg->length, nullptr, false);
if (j_msg.is_discarded() == true) {
return;
}
std::string jstr = j_msg.dump() + "\n";
std::string ip =wxhelper::Config::GetInstance().GetRecvTcpIp();
int port = wxhelper::Config::GetInstance().GetRecvTcpPort();
wxhelper::TcpClient client{ip,port};
client.SendAndCloseSocket(jstr);
}
VOID SendHttpMsgCallback(PTP_CALLBACK_INSTANCE instance, PVOID context,
PTP_WORK Work) {
wechat::InnerMessageStruct *msg = (wechat::InnerMessageStruct *)context;
if (msg == NULL) {
SPDLOG_INFO("http msg is null");
return;
}
std::unique_ptr<wechat::InnerMessageStruct> sms(msg);
nlohmann::json j_msg = nlohmann::json::parse(
msg->buffer, msg->buffer + msg->length, nullptr, false);
if (j_msg.is_discarded() == true) {
return;
}
std::string jstr = j_msg.dump() + "\n";
std::string url =wxhelper::Config::GetInstance().GetRecvHttpUrl();
int timeout = wxhelper::Config::GetInstance().GetRecvHttpTimeout();
http::HttpClient client{url,timeout};
client.SendRequest(jstr);
}
BaseHook::BaseHook(void *origin, void *detour)
: origin_(origin), detour_(detour) {}
int BaseHook::Hook() {
if (hook_flag_) {
SPDLOG_INFO("hook already called");
return 2;
}
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach((PVOID *)origin_, (PVOID *)detour_);
LONG ret = DetourTransactionCommit();
if (ret == NO_ERROR) {
hook_flag_ = true;
}
return ret;
}
int BaseHook::Unhook() {
if (!hook_flag_) {
SPDLOG_INFO("hook already called");
return NO_ERROR;
}
UINT64 base = wxhelper::wxutils::GetWeChatWinBase();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach((PVOID *)origin_, (PVOID *)detour_);
LONG ret = DetourTransactionCommit();
if (ret == NO_ERROR) {
hook_flag_ = false;
}
return ret;
}
SyncMsgHook::SyncMsgHook(void *origin, void *detour)
: BaseHook(origin, detour) {}
void SyncMsgHook::HandleSyncMsg(INT64 param1, INT64 param2, INT64 param3) {
nlohmann::json msg;
msg["pid"] = GetCurrentProcessId();
msg["fromUser"] =
wxhelper::wxutils::ReadSKBuiltinString(*(INT64 *)(param2 + 0x18));
msg["toUser"] =
wxhelper::wxutils::ReadSKBuiltinString(*(INT64 *)(param2 + 0x28));
msg["content"] =
wxhelper::wxutils::ReadSKBuiltinString(*(INT64 *)(param2 + 0x30));
msg["signature"] =
wxhelper::wxutils::ReadWeChatStr(*(INT64 *)(param2 + 0x48));
msg["msgId"] = *(INT64 *)(param2 + 0x60);
msg["msgSequence"] = *(DWORD *)(param2 + 0x5C);
msg["createTime"] = *(DWORD *)(param2 + 0x58);
msg["displayFullContent"] =
wxhelper::wxutils::ReadWeChatStr(*(INT64 *)(param2 + 0x50));
DWORD type = *(DWORD *)(param2 + 0x24);
msg["type"] = type;
if (type == 3) {
int a = 1;
std::string img =
wxhelper::wxutils::ReadSKBuiltinBuffer(*(INT64 *)(param2 + 0x40));
SPDLOG_INFO("encode size:{}", img.size());
msg["base64Img"] = base64_encode(img);
a = 2;
}
std::string jstr = msg.dump() + '\n';
wechat::InnerMessageStruct *inner_msg = new wechat::InnerMessageStruct;
inner_msg->buffer = new char[jstr.size() + 1];
memcpy(inner_msg->buffer, jstr.c_str(), jstr.size() + 1);
inner_msg->length = jstr.size();
std::string mode = wxhelper::Config::GetInstance().GetRecvMessageMode();
if (mode == "http") {
bool add =
base::ThreadPool::GetInstance().AddWork(SendHttpMsgCallback, inner_msg);
SPDLOG_INFO("add http msg work:{}", add);
} else if (mode == "tcp") {
bool add =
base::ThreadPool::GetInstance().AddWork(SendTcpMsgCallback, inner_msg);
SPDLOG_INFO("add tcp msg work:{}", add);
}
int64_t addr =
wxhelper::wxutils::GetWeChatWinBase() + wechat::offset::kDoAddMsg;
wechat::function::__DoAddMsg addMsg = (wechat::function::__DoAddMsg)addr;
addMsg(param1, param2, param3);
}
} // namespace hook

32
app/wxhelper/src/hook.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef WXHELPER_HOOK_H_
#define WXHELPER_HOOK_H_
#include "noncopyable.h"
#include <Windows.h>
namespace hook {
static void SendHttpMsgCallback(PTP_CALLBACK_INSTANCE instance, PVOID context,
PTP_WORK Work);
static void SendTcpMsgCallback(PTP_CALLBACK_INSTANCE instance, PVOID context,
PTP_WORK Work);
class BaseHook : public NonCopyable {
public:
BaseHook(void* origin, void* detour);
int Hook();
int Unhook();
protected:
bool hook_flag_;
void* origin_;
void* detour_;
};
class SyncMsgHook : public BaseHook {
public:
explicit SyncMsgHook(void* origin, void* detour);
private:
static void HandleSyncMsg(INT64 param1, INT64 param2, INT64 param3);
};
} // namespace hook
#endif

View File

@ -0,0 +1,42 @@
#ifndef WXHELPER_HTTP_CONTROLLER_H_
#define WXHELPER_HTTP_CONTROLLER_H_
#include <Windows.h>
#include "http_router.h"
namespace http {
#define PATHS_BEGIN static void AddPath() {
#define ADD_PATH(path, method) RegisterPath(path, &method)
#define PATHS_END }
class BaseHttpController {
public:
virtual ~BaseHttpController() {}
};
template <typename T>
class HttpController : public BaseHttpController {
public:
virtual ~HttpController() {}
protected:
HttpController() {}
static void RegisterPath(const std::string &path, HttpHandler function) {
HttpRouter::GetInstance().AddPathRouting(path, function);
}
private:
struct Registrator {
public:
Registrator() { T::AddPath(); }
};
static Registrator registrator_;
virtual void *GetRegistrator() { return &registrator_; }
};
template <typename T>
typename HttpController<T>::Registrator HttpController<T>::registrator_;
} // namespace http
#endif

View File

@ -0,0 +1,24 @@
#include "http_router.h"
#include <iostream>
#include "nlohmann/json.hpp"
#include "spdlog/spdlog.h"
namespace http {
void HttpRouter::AddPathRouting(const std::string &path, HttpHandler handler) {
route_table_[path] = handler;
SPDLOG_INFO("1route table size={}", route_table_.size());
}
std::string HttpRouter::HandleHttpRequest(const std::string &path,
const std::string &param) {
SPDLOG_INFO("route table size={}", route_table_.size());
auto it = route_table_.find(path);
if (it != route_table_.end()) {
return it->second(path, param);
} else {
nlohmann::json ret_data = {
{"code", 200}, {"data", {}}, {"msg", "the url is not supported"}};
return ret_data.dump();
}
}
} // namespace http

View File

@ -0,0 +1,23 @@
#ifndef WXHELPER_HTTP_ROUTER_H_
#define WXHELPER_HTTP_ROUTER_H_
#include <functional>
#include <map>
#include <string>
#include "singleton.h"
namespace http {
typedef std::function<std::string(std::string, std::string)> HttpHandler;
class HttpRouter : public base::Singleton<HttpRouter> {
public:
void HttpRouter::AddPathRouting(const std::string &path, HttpHandler handler);
std::string HandleHttpRequest(const std::string &path,
const std::string &param);
private:
std::unordered_map<std::string, HttpHandler> route_table_{};
};
} // namespace http
#endif

136
app/wxhelper/src/offset.h Normal file
View File

@ -0,0 +1,136 @@
#ifndef WXHELPER_OFFSET_H_
#define WXHELPER_OFFSET_H_
#include <cstdint>
namespace wechat {
#define V_3_9_8_25 39825
#ifndef WECHAT_VERSION
#error " WECHAT_VERSION not defined ."
#endif
namespace offset {
#if WECHAT_VERSION == V_3_9_8_25
const uint64_t kGetAccountServiceMgr = 0x94e510;
const uint64_t kSyncMsg = 0xc39680;
const uint64_t kSyncMsgNext = 0xc39680;
const uint64_t kGetCurrentDataPath = 0x101a920;
const uint64_t kGetAppDataSavePath = 0x13a5b90;
const uint64_t kGetSendMessageMgr = 0x94cd10;
const uint64_t kSendTextMsg = 0x1091F70;
const uint64_t kFreeChatMsg = 0x94e590;
const uint64_t kDoAddMsg = 0x10d9450;
const uint64_t kSendImageMsg = 0x1087950;
const uint64_t kChatMsgInstanceCounter = 0x956e00;
const uint64_t kSendFileMsg = 0xea0850;
const uint64_t kGetAppMsgMgr = 0x951cb0;
const uint64_t kGetContactMgr = 0x93a570;
const uint64_t kGetContactList = 0xf6cb70;
const uint64_t k_sqlite3_exec = 0x26e4f20;
const uint64_t k_sqlite3_prepare = 0x26ecaa0;
const uint64_t k_sqlite3_open = 0x27242a0;
const uint64_t k_sqlite3_step = 0x26a8f30;
const uint64_t k_sqlite3_column_count = 0x26a9750;
const uint64_t k_sqlite3_column_name = 0x26aa150;
const uint64_t k_sqlite3_column_type = 0x26a9fa0;
const uint64_t k_sqlite3_column_blob = 0x26a9780;
const uint64_t k_sqlite3_column_bytes = 0x26a9870;
const uint64_t k_sqlite3_finalize = 0x26a7fe0;
const uint64_t kGPInstance = 0x3d8b4f8;
const uint64_t kMicroMsgDB = 0xb8;
const uint64_t kChatMsgDB = 0x2c8;
const uint64_t kMiscDB = 0x5f0;
const uint64_t kEmotionDB = 0x888;
const uint64_t kMediaDB = 0xF48;
const uint64_t kBizchatMsgDB = 0x1AC0;
const uint64_t kFunctionMsgDB = 0x1b98;
const uint64_t kDBName = 0x28;
const uint64_t kStorageStart = 0x0;
const uint64_t kStorageEnd = 0x0;
const uint64_t kMultiDBMgr = 0x3e00910;
const uint64_t kPublicMsgMgr = 0x3dfe098;
const uint64_t kFavoriteStorageMgr = 0x3e01478;
const uint64_t kChatRoomMgr = 0x8e9d30;
const uint64_t kGetChatRoomDetailInfo = 0xe73590;
const uint64_t kNewChatRoomInfo = 0x12006b0;
const uint64_t kFreeChatRoomInfo = 0x1200890;
const uint64_t kDoAddMemberToChatRoom = 0xe63c70;
const uint64_t kDoModChatRoomMemberNickName = 0xe6db00;
const uint64_t kDelMemberFromChatRoom = 0xe64290;
const uint64_t kGetMemberFromChatRoom = 0xe74de0;
const uint64_t kNewChatRoom = 0x11fde50;
const uint64_t kFreeChatRoom = 0x11fe030;
const uint64_t kTopMsg = 0xa5e4f0;
const uint64_t kRemoveTopMsg = 0xe787b0;
const uint64_t kInviteMember = 0xe63650;
const uint64_t kHookLog = 0x1304e60;
const uint64_t kCreateChatRoom = 0xe63340;
const uint64_t kQuitChatRoom = 0xe6e3b0;
const uint64_t kForwardMsg = 0x1091660;
const uint64_t kOnSnsTimeLineSceneFinish = 0x1a73150;
const uint64_t kSNSGetFirstPage = 0x1a51dd0;
const uint64_t kSNSGetNextPageScene = 0x1a77240;
const uint64_t kSNSDataMgr = 0xeebda0;
const uint64_t kSNSTimeLineMgr = 0x19e83a0;
const uint64_t kGetMgrByPrefixLocalId = 0xf0ea60;
const uint64_t kAddFavFromMsg = 0x1601520;
const uint64_t kGetChatMgr = 0x97e4d0;
const uint64_t kGetFavoriteMgr = 0x8c69b0;
const uint64_t kAddFavFromImage = 0x160b920;
const uint64_t kGetContact = 0xf67060;
const uint64_t kNewContact = 0x12e01f0;
const uint64_t kFreeContact = 0x12e08a0;
const uint64_t kNewMMReaderItem = 0x8c79a0;
const uint64_t kFreeMMReaderItem = 0x8c6da0;
const uint64_t kForwordPublicMsg = 0xddc6c0;
const uint64_t kParseAppMsgXml = 0x11b0a70;
const uint64_t kNewAppMsgInfo = 0x91a550;
const uint64_t kFreeAppMsgInfo = 0x8fd1a0;
const uint64_t kGetPreDownLoadMgr = 0x9996f0;
const uint64_t kPushAttachTask = 0x9c0080;
const uint64_t kGetCustomSmileyMgr = 0x915c00;
const uint64_t kSendCustomEmotion = 0xec0a40;
const uint64_t kNewJsApiShareAppMessage = 0x13be1a0;
const uint64_t kInitJsConfig = 0x137bc00;
const uint64_t kSendApplet = 0x13c0920;
const uint64_t kSendAppletSecond = 0x13c1150;
const uint64_t kGetAppInfoByWaid = 0x13c5790;
const uint64_t kCopyShareAppMessageRequest = 0x13c0670;
const uint64_t kNewWAUpdatableMsgInfo = 0x919ca0;
const uint64_t kFreeWAUpdatableMsgInfo = 0x8fc230;
const uint64_t kSendPatMsg = 0x195f340;
const uint64_t kGetOCRManager = 0x999780;
const uint64_t kDoOCRTask = 0x190b2a0;
const uint64_t kGetLockWechatMgr = 0xa727b0;
const uint64_t kRequestLockWechat = 0xa2cc70;
const uint64_t kRequestUnLockWechat = 0xa2cf10;
const uint64_t kOnLoginBtnClick = 0xe0cf70;
const uint64_t kGetQRCodeLoginMgr = 0xdff6d0;
const uint64_t kUpdateMsg = 0xf15c40;
const uint64_t kGetVoiceMgr = 0xbf78f0;
const uint64_t kChatMsg2NetSceneSendMsg = 0x96e8d0;
const uint64_t kTranslateVoice = 0x11217e0;
const uint64_t kNewWebViewPageConfig = 0x9512f0;
const uint64_t kFreeWebViewPageConfig = 0x951520;
const uint64_t kGetWebViewMgr = 0x9412d0;
const uint64_t kShowWebView = 0x1d236b0;
const uint64_t kSetUrl = 0x13dd410;
#elif WECHAT_VERSION == V_3_9_8_25
#else
#ifdef WECHAT_VERSION
#error "Unsupported WeChat version."
#endif
#endif
} // namespace offset
} // namespace wxhelper
#endif

View File

@ -0,0 +1,120 @@
#ifndef WXHELPER_SQLITE_FUNCTION_H_
#define WXHELPER_SQLITE_FUNCTION_H_
#include <cstdint>
#include "offset.h"
namespace sqlite3 {
namespace offset = wechat::offset;
#define SQLITE_OK 0 /* Successful result */
/* beginning-of-error-codes */
#define SQLITE_ERROR 1 /* Generic error */
#define SQLITE_INTERNAL 2 /* Internal logic error in SQLite */
#define SQLITE_PERM 3 /* Access permission denied */
#define SQLITE_ABORT 4 /* Callback routine requested an abort */
#define SQLITE_BUSY 5 /* The database file is locked */
#define SQLITE_LOCKED 6 /* A table in the database is locked */
#define SQLITE_NOMEM 7 /* A malloc() failed */
#define SQLITE_READONLY 8 /* Attempt to write a readonly database */
#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/
#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */
#define SQLITE_CORRUPT 11 /* The database disk image is malformed */
#define SQLITE_NOTFOUND 12 /* Unknown opcode in sqlite3_file_control() */
#define SQLITE_FULL 13 /* Insertion failed because database is full */
#define SQLITE_CANTOPEN 14 /* Unable to open the database file */
#define SQLITE_PROTOCOL 15 /* Database lock protocol error */
#define SQLITE_EMPTY 16 /* Internal use only */
#define SQLITE_SCHEMA 17 /* The database schema changed */
#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */
#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */
#define SQLITE_MISMATCH 20 /* Data type mismatch */
#define SQLITE_MISUSE 21 /* Library used incorrectly */
#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */
#define SQLITE_AUTH 23 /* Authorization denied */
#define SQLITE_FORMAT 24 /* Not used */
#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */
#define SQLITE_NOTADB 26 /* File opened that is not a database file */
#define SQLITE_NOTICE 27 /* Notifications from sqlite3_log() */
#define SQLITE_WARNING 28 /* Warnings from sqlite3_log() */
#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */
#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */
/* end-of-error-codes */
#define SQLITE_INTEGER 1
#define SQLITE_FLOAT 2
#define SQLITE_BLOB 4
#define SQLITE_NULL 5
#define SQLITE_TEXT 3
typedef int (*sqlite3_callback)(void *, int, char **, char **);
typedef int(__cdecl *sqlite3_exec)(uint64_t, /* An open database */
const char *sql, /* SQL to be evaluated */
sqlite3_callback, /* Callback function */
void *, /* 1st argument to callback */
char **errmsg /* Error msg written here */
);
typedef int(__cdecl *sqlite3_prepare)(
uint64_t db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
int nByte, /* Maximum length of zSql in bytes. */
uint64_t **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */
);
typedef int(__cdecl *sqlite3_open)(const char *filename, uint64_t **ppDb);
typedef int(__cdecl *sqlite3_sleep)(int);
typedef int(__cdecl *sqlite3_errcode)(uint64_t *db);
typedef int(__cdecl *sqlite3_close)(uint64_t *);
typedef int(__cdecl *sqlite3_step)(uint64_t *);
typedef int(__cdecl *sqlite3_column_count)(uint64_t *pStmt);
typedef const char *(__cdecl *sqlite3_column_name)(uint64_t *, int N);
typedef int(__cdecl *sqlite3_column_type)(uint64_t *, int iCol);
typedef const void *(__cdecl *sqlite3_column_blob)(uint64_t *, int iCol);
typedef int(__cdecl *sqlite3_column_bytes)(uint64_t *, int iCol);
typedef int(__cdecl *sqlite3_finalize)(uint64_t *pStmt);
/***************************sqlite3 end*************************************/
struct SqliteFunction {
SqliteFunction(uint64_t base_addr) {
sqlite3_exec =
reinterpret_cast<sqlite3::sqlite3_exec>(base_addr + offset::k_sqlite3_exec);
sqlite3_prepare = reinterpret_cast<sqlite3::sqlite3_prepare>(
base_addr + offset::k_sqlite3_prepare);
sqlite3_open =
reinterpret_cast<sqlite3::sqlite3_open>(base_addr + offset::k_sqlite3_open);
sqlite3_step =
reinterpret_cast<sqlite3::sqlite3_step>(base_addr + offset::k_sqlite3_step);
sqlite3_column_count = reinterpret_cast<sqlite3::sqlite3_column_count>(
base_addr + offset::k_sqlite3_column_count);
sqlite3_column_name = reinterpret_cast<sqlite3::sqlite3_column_name>(
base_addr + offset::k_sqlite3_column_name);
sqlite3_column_type = reinterpret_cast<sqlite3::sqlite3_column_type>(
base_addr + offset::k_sqlite3_column_type);
sqlite3_column_blob = reinterpret_cast<sqlite3::sqlite3_column_blob>(
base_addr + offset::k_sqlite3_column_blob);
sqlite3_column_bytes = reinterpret_cast<sqlite3::sqlite3_column_bytes>(
base_addr + offset::k_sqlite3_column_bytes);
sqlite3_finalize = reinterpret_cast<sqlite3::sqlite3_finalize>(
base_addr + offset::k_sqlite3_finalize);
}
sqlite3_exec sqlite3_exec;
sqlite3_prepare sqlite3_prepare;
sqlite3_open sqlite3_open;
sqlite3_sleep sqlite3_sleep;
sqlite3_errcode sqlite3_errcode;
sqlite3_close sqlite3_close;
sqlite3_step sqlite3_step;
sqlite3_column_count sqlite3_column_count;
sqlite3_column_name sqlite3_column_name;
sqlite3_column_type sqlite3_column_type;
sqlite3_column_blob sqlite3_column_blob;
sqlite3_column_bytes sqlite3_column_bytes;
sqlite3_finalize sqlite3_finalize;
};
} // namespace sqlite3
#endif

View File

@ -0,0 +1,27 @@
#include "wechat_db.h"
#include "wechat_interface.h"
namespace wechat {
void WeChatDb::init(uint64_t base) {
base_addr_ = base;
func_ = sqlite3::SqliteFunction(base);
dbmap_ = {};
dbs_ = {};
}
int WeChatDb::ExecuteSQL(uint64_t db, const char *sql,
sqlite3::sqlite3_callback callback, void *data) {
return func_.sqlite3_exec(db, sql, callback, data, 0);
}
} // namespace wechat

View File

@ -0,0 +1,28 @@
#ifndef WXHELPER_WECHAT_DB_H_
#define WXHELPER_WECHAT_DB_H_
#include <map>
#include <string>
#include <vector>
#include "singleton.h"
#include "sqlite_function.h"
#include "wechat_interface.h"
namespace wechat {
class WeChatDb : public base::Singleton<WeChatDb> {
public:
void init(uint64_t base);
int ExecuteSQL(uint64_t db, const char *sql,
sqlite3::sqlite3_callback callback, void *data);
private:
std::map<std::wstring,DatabaseInfo> dbmap_;
std::vector<DatabaseInfo> dbs_;
sqlite3::SqliteFunction func_;
uint64_t base_addr_;
};
} // namespace wechat
#endif

View File

@ -0,0 +1,296 @@
#ifndef WXHELPER_WECHAT_INNER_H_
#define WXHELPER_WECHAT_INNER_H_
#include <string>
#include <vector>
#include <cstdint>
namespace wechat {
struct TableInfo {
char *name;
int64_t name_len;
char *table_name;
int64_t table_name_len;
char *sql;
int64_t sql_len;
char *rootpage;
int64_t rootpage_len;
};
struct DatabaseInfo {
uint64_t handle = 0;
wchar_t *db_name = NULL;
int64_t db_name_len = 0;
std::vector<TableInfo> tables;
int64_t count = 0;
int64_t extrainfo = 0;
};
struct SqlResult {
char *column_name;
int64_t column_name_len;
char *content;
int64_t content_len;
bool is_blob;
};
struct InnerMessageStruct {
char *buffer;
int64_t length;
~InnerMessageStruct() {
if (this->buffer != NULL) {
delete[] this->buffer;
this->buffer = NULL;
}
}
};
struct SelfInfoInner {
std::string name;
std::string city;
std::string province;
std::string country;
std::string account;
std::string wxid;
std::string mobile;
std::string head_img;
std::string data_save_path;
std::string signature;
std::string current_data_path;
std::string db_key;
std::string public_key;
std::string private_key;
};
struct ContactInner {
std::string wxid;
std::string custom_account;
std::string encrypt_name;
std::string nickname;
std::string pinyin;
std::string pinyin_all;
std::string remark;
std::string remark_pinyin;
std::string remark_pinyin_all;
std::string label_ids;
int32_t type;
int32_t verify_flag;
int32_t reserved1;
int32_t reserved2;
ContactInner() {
wxid = "";
custom_account = "";
encrypt_name = "";
nickname = "";
pinyin = "";
pinyin_all = "";
remark = "";
remark_pinyin = "";
remark_pinyin_all = "";
label_ids = "";
type = -1;
verify_flag = -1;
reserved1 = -1;
reserved2 = -1;
}
};
struct ChatRoomInfoInner {
std::string chat_room_id;
std::string notice;
std::string admin;
std::string xml;
ChatRoomInfoInner() {
chat_room_id = "";
notice = "";
admin = "";
xml = "";
}
};
struct VectorInner {
#ifdef _DEBUG
int64_t head;
#endif
int64_t start;
int64_t finsh;
int64_t end;
};
struct ChatRoomMemberInner {
std::string chat_room_id;
std::string admin;
std::string admin_nickname;
std::string member_nickname;
std::string member;
ChatRoomMemberInner()
: chat_room_id(""),
admin(""),
admin_nickname(""),
member_nickname(""),
member("") {}
};
struct ContactProfileInner {
std::string wxid;
std::string account;
std::string v3;
std::string nickname;
std::string head_image;
ContactProfileInner()
: wxid(""), account(""), v3(""), nickname(""), head_image("") {}
};
namespace function {
//hook
typedef uint64_t(*__DoAddMsg)(uint64_t, uint64_t, uint64_t);
//hook end
typedef uint64_t (*__GetAccountService)();
typedef uint64_t (*__GetDataSavePath)(uint64_t);
typedef uint64_t (*__GetCurrentDataPath)(uint64_t);
typedef uint64_t (*__GetSendMessageMgr)();
typedef uint64_t (*__SendTextMsg)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,
uint64_t, uint64_t);
typedef uint64_t (*__FreeChatMsg)(uint64_t);
typedef uint64_t (*__SendImageMsg)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
typedef uint64_t (*__NewChatMsg)(uint64_t);
typedef uint64_t (*__SendFile)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,
uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
typedef uint64_t (*__GetAppMsgMgr)();
typedef uint64_t (*__OperatorNew)(uint64_t);
typedef uint64_t (*__Free)();
typedef uint64_t (*__GetContactMgr)();
typedef uint64_t (*__GetContactList)(uint64_t, uint64_t);
typedef uint64_t (*__GetChatRoomMgr)();
typedef uint64_t (*__NewChatRoomInfo)(uint64_t);
typedef uint64_t (*__FreeChatRoomInfo)(uint64_t);
typedef uint64_t (*__GetChatRoomDetailInfo)(uint64_t, uint64_t, uint64_t, uint64_t);
typedef uint64_t (*__DoAddMemberToChatRoom)(uint64_t, uint64_t, uint64_t, uint64_t);
typedef uint64_t (*__DoModChatRoomMemberNickName)(uint64_t, uint64_t, uint64_t, uint64_t);
typedef uint64_t (*__DoDelMemberFromChatRoom)(uint64_t, uint64_t, uint64_t);
typedef uint64_t (*__GetMemberFromChatRoom)(uint64_t, uint64_t, uint64_t);
typedef uint64_t (*__NewChatRoom)(uint64_t);
typedef uint64_t (*__FreeChatRoom)(uint64_t);
typedef uint64_t (*__DoTopMsg)(uint64_t, uint64_t);
typedef uint64_t (*__RemoveTopMsg)(uint64_t, uint64_t, uint64_t);
typedef uint64_t (*__InviteMemberToChatRoom)(uint64_t, uint64_t, uint64_t, uint64_t);
typedef uint64_t (*__CreateChatRoom)(uint64_t, uint64_t, uint64_t);
typedef uint64_t (*__QuitChatRoom)(uint64_t, uint64_t, uint64_t);
typedef uint64_t (*__ForwardMsg)(uint64_t, uint64_t, uint64_t, uint64_t);
typedef uint64_t (*__GetSNSFirstPage)(uint64_t, uint64_t, uint64_t);
typedef uint64_t (*__GetSNSNextPageScene)(uint64_t, uint64_t);
typedef uint64_t (*__GetSNSDataMgr)();
typedef uint64_t (*__GetSnsTimeLineMgr)();
typedef uint64_t (*__GetMgrByPrefixLocalId)(uint64_t, uint64_t);
typedef uint64_t (*__AddFavFromMsg)(uint64_t, uint64_t);
typedef uint64_t (*__GetChatMgr)();
typedef uint64_t (*__GetFavoriteMgr)();
typedef uint64_t (*__AddFavFromImage)(uint64_t, uint64_t, uint64_t);
typedef uint64_t (*__GetContact)(uint64_t, uint64_t, uint64_t);
typedef uint64_t (*__NewContact)(uint64_t);
typedef uint64_t (*__FreeContact)(uint64_t);
typedef uint64_t (*__NewMMReaderItem)(uint64_t);
typedef uint64_t (*__FreeMMReaderItem)(uint64_t);
typedef uint64_t (*__ForwordPublicMsg)(uint64_t, uint64_t, uint64_t);
typedef uint64_t (*__NewAppMsgInfo)(uint64_t);
typedef uint64_t (*__FreeAppMsgInfo)(uint64_t);
typedef uint64_t (*__ParseAppMsgXml)(uint64_t, uint64_t, uint64_t);
typedef uint64_t (*__GetPreDownLoadMgr)();
typedef uint64_t (*__PushAttachTask)(uint64_t, uint64_t, uint64_t, uint64_t);
typedef uint64_t (*__GetCustomSmileyMgr)();
typedef uint64_t (*__SendCustomEmotion)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,
uint64_t, uint64_t, uint64_t);
typedef uint64_t (*__JsApiShareAppMessage)(uint64_t);
typedef uint64_t (*__InitJsConfig)(uint64_t, uint64_t);
typedef uint64_t (*__SendApplet)(uint64_t, uint64_t, uint64_t, uint64_t);
typedef uint64_t (*__SendAppletSecond)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,
uint64_t);
typedef uint64_t (*__GetAppInfoByWaid)(uint64_t, uint64_t);
typedef uint64_t (*__CopyShareAppMessageRequest)(uint64_t, uint64_t);
typedef uint64_t (*__NewWAUpdatableMsgInfo)(uint64_t);
typedef uint64_t (*__FreeWAUpdatableMsgInfo)(uint64_t);
typedef uint64_t (*__SendPatMsg)(uint64_t, uint64_t);
typedef uint64_t (*__GetOCRManager)();
typedef uint64_t (*__DoOCRTask)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
typedef uint64_t (*__GetLockWechatMgr)();
typedef uint64_t (*__RequestLockWechat)(uint64_t);
typedef uint64_t (*__RequestUnLockWechat)(uint64_t);
typedef uint64_t (*__OnLoginBtnClick)(uint64_t);
typedef uint64_t (*__GetQRCodeLoginMgr)();
typedef uint64_t (*__UpdateMsg)(uint64_t,uint64_t,uint64_t);
typedef uint64_t (*__GetVoiceMgr)();
typedef uint64_t (*__ChatMsg2NetSceneSendMsg)(uint64_t,uint64_t);
typedef uint64_t (*__TranslateVoice)(uint64_t,uint64_t,uint64_t);
typedef uint64_t (*__ShowWebView)(uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
typedef uint64_t (*__NewWebViewPageConfig)(uint64_t);
typedef uint64_t (*__FreeWebViewPageConfig)(uint64_t);
typedef uint64_t (*__GetWebViewMgr)();
typedef uint64_t (*__SetUrl)(uint64_t,uint64_t,uint64_t);
} // namespace function
namespace prototype {
struct WeChatString {
wchar_t *ptr;
int32_t length;
int32_t max_length;
int64_t c_ptr = 0;
int32_t c_len = 0;
WeChatString() { WeChatString(NULL); }
WeChatString(const std::wstring &s) {
ptr = (wchar_t *)(s.c_str());
length = static_cast<int32_t>(s.length());
max_length = static_cast<int32_t>(s.length());
}
WeChatString(const wchar_t *pStr) { WeChatString((wchar_t *)pStr); }
WeChatString(int tmp) {
ptr = NULL;
length = 0x0;
max_length = 0x0;
}
WeChatString(wchar_t *pStr) {
ptr = pStr;
length = static_cast<int32_t>(wcslen(pStr));
max_length = static_cast<int32_t>(wcslen(pStr));
}
void set_value(const wchar_t *pStr) {
ptr = (wchar_t *)pStr;
length = static_cast<int32_t>(wcslen(pStr));
max_length = static_cast<int32_t>(wcslen(pStr) * 2);
}
};
struct WeChatStr {
char *ptr;
int64_t buf;
int64_t len;
int64_t maxlen;
WeChatStr(const char *p) {
ptr = (char *)p;
buf = 0;
len = strlen(p);
maxlen = len | 0xF;
}
WeChatStr() {
ptr = NULL;
buf = 0;
len = 0;
maxlen = 0xF;
}
};
} // namespace prototype
} // namespace wechat
#endif

View File

@ -0,0 +1,28 @@
#include <winsock2.h>
#include "wxhelper.h"
#include "config.h"
#include "http_server.h"
#include "thread_pool.h"
#include "utils.h"
#include "wxutils.h"
#include "chat_controller.h"
namespace wxhelper {
void WxHelper::init(HMODULE module) {
Config::GetInstance().init();
if (Config::GetInstance().GetHideDll()) {
// base::utils::HideModule(module);
}
// ChatController chatController;
// http::HttpRouter::GetInstance().init();
http::HttpServer::GetInstance().init(
Config::GetInstance().GetHttpServerHost(),
Config::GetInstance().GetHttpServerPort());
http::HttpServer::GetInstance().Start();
base::ThreadPool::GetInstance().Create(2, 8);
}
void WxHelper::finally() { http::HttpServer::GetInstance().Stop(); }
} // namespace wxhelper

View File

@ -0,0 +1,14 @@
#ifndef WXHELPER_WXHELPER_H_
#define WXHELPER_WXHELPER_H_
#include <Windows.h>
#include "singleton.h"
namespace wxhelper {
class WxHelper : public base::Singleton<WxHelper>{
public:
void init(HMODULE module);
void finally();
};
}
#endif