Compare commits

..
Author SHA1 Message Date
hugy 581aacb8ce feat: 完善3.9.2.26已有的功能 2023-05-25 15:30:27 +08:00
hugy dccc997067 3.9.2.26部分功能 2023-05-23 12:01:43 +08:00
hugy 0b52a49155 feat: 增加线程池1 2023-05-20 17:12:02 +08:00
hugy 4027c4afe6 feat: 增加线程池 2023-05-20 17:10:14 +08:00
hugy dcbde9203b feat: 部分偏移更新 2023-05-13 17:25:08 +08:00
hugy 76dc8affe9 chore: spdlog 2023-05-11 10:04:21 +08:00
hugy fd3e6f4a70 feat: add spdlog 2023-05-11 08:37:35 +08:00
hugy 18e34cd11b feat: 3.9.2.26发送文本,图片,文件 2023-05-11 00:04:46 +08:00
21 changed files with 450 additions and 7931 deletions
+3
View File
@@ -0,0 +1,3 @@
[submodule "spdlog"]
path = spdlog
url = https://github.com/gabime/spdlog
+11 -5
View File
@@ -1,25 +1,30 @@
cmake_minimum_required(VERSION 3.0.0)
# include(ExternalProject)
project(wxhelper VERSION 1.0.0)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D '_UNICODE' /D 'UNICODE' /D 'ELPP_THREAD_SAFE'")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D '_UNICODE' /D 'UNICODE' ")
file(GLOB CPP_FILES ${PROJECT_SOURCE_DIR}/src/*.cc ${PROJECT_SOURCE_DIR}/src/*.cpp)
include_directories(${VCPKG_INSTALLED_DIR}/x86-windows/include)
include_directories(${VCPKG_INSTALLED_DIR}/x86-windows/include ${PROJECT_SOURCE_DIR}/spdlog/include)
# add_subdirectory(3rd)
add_subdirectory(spdlog)
# add_subdirectory(source)
find_package(nlohmann_json CONFIG REQUIRED)
find_package(unofficial-mongoose CONFIG REQUIRED)
# find_package(spdlog CONFIG REQUIRED)
# find_package(minhook CONFIG REQUIRED)
add_library(wxhelper SHARED ${CPP_FILES} )
@@ -29,7 +34,8 @@ add_library(wxhelper SHARED ${CPP_FILES} )
target_link_libraries(wxhelper PRIVATE nlohmann_json::nlohmann_json)
target_link_libraries(wxhelper PRIVATE unofficial::mongoose::mongoose)
# target_link_libraries(wxhelper PRIVATE spdlog::spdlog spdlog::spdlog_header_only)
target_link_libraries(wxhelper PRIVATE spdlog::spdlog spdlog::spdlog_header_only)
# target_link_libraries(wxhelper PRIVATE minhook::minhook)
SET_TARGET_PROPERTIES(wxhelper PROPERTIES LINKER_LANGUAGE C
+36
View File
@@ -0,0 +1,36 @@
## 3.9.2.26版本,预览功能没有的接口,不能使用,文档仅供参考。
#### 功能预览:
0.检查是否登录
1.获取登录微信信息
2.发送文本
3.发送@文本
5.发送图片
6.发送文件
9.hook消息
10.取消hook消息
19.通过手机或qq查找微信
20.通过wxid添加好友
23.通过好友申请
25.获取群成员
26.获取群成员昵称
27.删除群成员
28.增加群成员
31.修改群昵称
32.获取数据库句柄
34.查询数据库
35.hook日志
36.关闭hook日志
40.转发消息
44.退出登录
46.联系人列表
47.获取群详情
48.获取解密图片
49.图片提取文字ocr
50.拍一拍
51.群消息置顶消息
52.群消息取消置顶
53.朋友圈首页
54.朋友圈下一页
55.获取联系人或者群名称
56.获取消息附件(图片,视频,文件)
57.获取消息语音文件
Submodule
+1
Submodule spdlog added at ad0e89cbfb
+7 -13
View File
@@ -1,6 +1,5 @@
#include "pch.h"
#include "account_mgr.h"
#include "easylogging++.h"
#include "wechat_function.h"
@@ -129,16 +128,16 @@ int AccountMgr::GetSelfInfo(SelfInfoInner &out) {
}
}
if (*(DWORD *)(service_addr + 0x304) == 0 ||
*(DWORD *)(service_addr + 0x304 + 0x10) == 0) {
if (*(DWORD *)(service_addr + 0x31C) == 0 ||
*(DWORD *)(service_addr + 0x31C + 0x10) == 0) {
out.head_img = string();
} else {
if (*(DWORD *)(service_addr + 0x304 + 0x14) == 0xF) {
out.head_img = string((char *)(service_addr + 0x304),
*(DWORD *)(service_addr + 0x304 + 0x10));
if (*(DWORD *)(service_addr + 0x31C + 0x14) == 0xF) {
out.head_img = string((char *)(service_addr + 0x31C),
*(DWORD *)(service_addr + 0x31C + 0x10));
} else {
out.head_img = string(*(char **)(service_addr + 0x304),
*(DWORD *)(service_addr + 0x304 + 0x10));
out.head_img = string(*(char **)(service_addr + 0x31C),
*(DWORD *)(service_addr + 0x31C + 0x10));
}
}
@@ -181,11 +180,6 @@ int AccountMgr::GetSelfInfo(SelfInfoInner &out) {
return 1;
}
string AccountMgr::GetLoginUrl() {
DWORD login_url_addr = base_addr_ + WX_LOGIN_URL_OFFSET;
return "http://weixin.qq.com/x/" + std::string(reinterpret_cast<char*>(*(DWORD*)login_url_addr));
}
int AccountMgr::CheckLogin() {
int success = -1;
DWORD accout_service_addr = base_addr_ + WX_ACCOUNT_SERVICE_OFFSET;
-3
View File
@@ -8,9 +8,6 @@ namespace wxhelper{
public:
explicit AccountMgr(DWORD base);
~AccountMgr();
std::string GetLoginUrl();
int GetSelfInfo(SelfInfoInner& out);
int CheckLogin();
+2
View File
@@ -108,6 +108,7 @@ int ChatRoomMgr::DelMemberFromChatRoom(wchar_t* chat_room_id, wchar_t** wxids,
DWORD init_chat_msg_addr = base_addr_ + WX_INIT_CHAT_MSG_OFFSET;
__asm {
PUSHAD
PUSHFD
CALL get_chat_room_mgr_addr
SUB ESP,0x14
MOV ESI,EAX
@@ -120,6 +121,7 @@ int ChatRoomMgr::DelMemberFromChatRoom(wchar_t* chat_room_id, wchar_t** wxids,
PUSH EAX
CALL del_member_addr
MOV success,EAX
POPFD
POPAD
}
return success;
+1 -1
View File
@@ -126,7 +126,7 @@ int ContactMgr::AddFriendByWxid(wchar_t *wxid,wchar_t* msg) {
DWORD verify_msg_addr = base_addr_ + WX_VERIFY_MSG_OFFSET;
DWORD set_value_addr = base_addr_ + WX_INIT_CHAT_MSG_OFFSET;
DWORD do_verify_user_addr = base_addr_ + WX_DO_VERIFY_USER_OFFSET;
DWORD fn1_addr = base_addr_ + 0x758720;
DWORD fn1_addr = base_addr_ + 0x7591b0;
WeChatString user_id(wxid);
WeChatString w_msg(msg);
DWORD instance =0;
+6 -8
View File
@@ -2,8 +2,6 @@
#include "db.h"
#include "base64.h"
#include "easylogging++.h"
#include "wechat_function.h"
#include "utils.h"
using namespace std;
@@ -462,9 +460,9 @@ std::vector<void *> DB::GetDbHandles() {
dbs_.push_back(db_end);
#ifdef _DEBUG
for (unsigned int i = 0; i < dbs_.size() - 1; i++) {
LOG(INFO) << "dbname =" << dbs_[i].db_name;
LOG(INFO) << "handle =" << dbs_[i].handle;
LOG(INFO) << "table_count =" << dbs_[i].tables.size();
// LOG(INFO) << "dbname =" << dbs_[i].db_name;
// LOG(INFO) << "handle =" << dbs_[i].handle;
// LOG(INFO) << "table_count =" << dbs_[i].tables.size();
}
#endif
vector<void *> ret_array;
@@ -492,7 +490,7 @@ unsigned int DB::GetLocalIdByMsgId(ULONG64 msgid, int &dbIndex) {
swprintf_s(dbname, L"MSG%d.db", i);
DWORD handle = GetDbHandleByDbName(dbname);
if (handle == 0) {
LOG(INFO) << "MSG db handle is null";
SPDLOG_INFO("MSG db handle is null");
return 0;
}
vector<vector<string>> result;
@@ -517,7 +515,7 @@ vector<string> DB::GetChatMsgByMsgId(ULONG64 msgid) {
swprintf_s(dbname, L"MSG%d.db", i);
DWORD handle = GetDbHandleByDbName(dbname);
if (handle == 0) {
LOG(INFO) << "MSG db handle is null";
// LOG(INFO) << "MSG db handle is null";
return {};
}
vector<vector<string>> result;
@@ -536,7 +534,7 @@ std::string DB::GetVoiceBuffByMsgId(ULONG64 msgid) {
swprintf_s(dbname, L"MediaMSG%d.db", i);
DWORD handle = GetDbHandleByDbName(dbname);
if (handle == 0) {
LOG(INFO) << "Media db handle is null";
// LOG(INFO) << "Media db handle is null";
return "";
}
vector<vector<string>> result;
-3120
View File
File diff suppressed because it is too large Load Diff
-4576
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -1,8 +1,8 @@
#include "pch.h"
#include "global_context.h"
#include "http_server.h"
#include "easylogging++.h"
#include "hooks.h"
#include "thread_pool.h"
namespace wxhelper {
@@ -28,6 +28,7 @@ void GlobalContext::initialize(HMODULE module) {
account_mgr.emplace(AccountMgr{base});
chat_room_mgr.emplace(ChatRoomMgr{base});
sns_mgr.emplace(SNSMgr{base});
ThreadPool::GetInstance().Create(1,512);
}
void GlobalContext::finally() {
+166 -38
View File
@@ -1,10 +1,9 @@
#include <Ws2tcpip.h>
#include "pch.h"
#include <Ws2tcpip.h>
#include <winsock2.h>
#include <nlohmann/json.hpp>
#include "easylogging++.h"
#include "pch.h"
#include "thread_pool.h"
#include "wechat_function.h"
using namespace nlohmann;
using namespace std;
@@ -57,12 +56,12 @@ void SendSocketMessage(InnerMessageStruct *msg) {
string jstr = j_msg.dump() + "\n";
if (server_port_ == 0) {
LOG(INFO) << "http server port error :" << server_port_;
SPDLOG_ERROR("http server port error :{}",server_port_);
return;
}
SOCKET client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (client_socket < 0) {
LOG(INFO) << "socket init fail";
SPDLOG_ERROR("socket init fail");
return;
}
BOOL status = false;
@@ -73,13 +72,13 @@ void SendSocketMessage(InnerMessageStruct *msg) {
InetPtonA(AF_INET, server_ip_, &client_addr.sin_addr.s_addr);
if (connect(client_socket, reinterpret_cast<sockaddr *>(&client_addr),
sizeof(sockaddr)) < 0) {
LOG(INFO) << "socket connect fail";
SPDLOG_ERROR("socket connect fail");
return;
}
char recv_buf[1024] = {0};
int ret = send(client_socket, jstr.c_str(), jstr.size(), 0);
if (ret == -1 || ret == 0) {
LOG(INFO) << "socket send fail ,ret:" << ret;
SPDLOG_ERROR("socket send fail ,ret::{}",ret);
closesocket(client_socket);
return;
}
@@ -87,10 +86,83 @@ void SendSocketMessage(InnerMessageStruct *msg) {
ret = recv(client_socket, recv_buf, sizeof(recv_buf), 0);
closesocket(client_socket);
if (ret == -1 || ret == 0) {
LOG(INFO) << "socket recv fail ,ret:" << ret;
SPDLOG_ERROR("socket recv fail ,ret:{}",ret);
return;
}
}
VOID CALLBACK SendMsgCallback(PTP_CALLBACK_INSTANCE instance, PVOID context,
PTP_WORK Work) {
InnerMessageStruct *msg = (InnerMessageStruct *)context;
if (msg == NULL) {
SPDLOG_INFO("add work:msg is null");
return;
}
unique_ptr<InnerMessageStruct> sms(msg);
json j_msg =
json::parse(msg->buffer, msg->buffer + msg->length, nullptr, false);
if (j_msg.is_discarded() == true) {
return;
}
string jstr = j_msg.dump() + "\n";
if (server_port_ == 0) {
SPDLOG_ERROR("http server port error :{}", server_port_);
return;
}
WSADATA was_data = {0};
int ret = WSAStartup(MAKEWORD(2, 2), &was_data);
if (ret != 0) {
SPDLOG_ERROR("WSAStartup failed:{}", ret);
return;
}
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)server_port_);
InetPtonA(AF_INET, server_ip_, &client_addr.sin_addr.s_addr);
if (connect(client_socket, reinterpret_cast<sockaddr *>(&client_addr),
sizeof(sockaddr)) < 0) {
SPDLOG_ERROR("socket connect fail");
closesocket(client_socket);
WSACleanup();
return ;
}
char recv_buf[1024] = {0};
ret = send(client_socket, jstr.c_str(), jstr.size(), 0);
if (ret == -1 || ret == 0) {
SPDLOG_ERROR("socket send fail ,ret:{}", ret);
closesocket(client_socket);
WSACleanup();
return;
}
ret = shutdown(client_socket, SD_SEND);
if (ret == SOCKET_ERROR) {
SPDLOG_ERROR("shutdown failed with erro:{}", ret);
closesocket(client_socket);
WSACleanup();
return ;
}
memset(recv_buf, 0, sizeof(recv_buf));
ret = recv(client_socket, recv_buf, sizeof(recv_buf), 0);
closesocket(client_socket);
if (ret == -1 || ret == 0) {
SPDLOG_ERROR("socket recv fail ,ret:{}", ret);
WSACleanup();
return;
}
WSACleanup();
return;
}
void __cdecl OnRecvMsg(DWORD msg_addr) {
json j_msg;
unsigned long long msgid = *(unsigned long long *)(msg_addr + 0x30);
@@ -138,13 +210,17 @@ void __cdecl OnRecvMsg(DWORD msg_addr) {
inner_msg->buffer = new char[jstr.size() + 1];
memcpy(inner_msg->buffer, jstr.c_str(), jstr.size() + 1);
inner_msg->length = jstr.size();
HANDLE thread = CreateThread(
NULL, 0, (LPTHREAD_START_ROUTINE)SendSocketMessage, inner_msg, NULL, 0);
if (thread) {
CloseHandle(thread);
}
bool add = ThreadPool::GetInstance().AddWork(SendMsgCallback,inner_msg);
SPDLOG_INFO("add work:{}",add);
// HANDLE thread = CreateThread(
// NULL, 0, (LPTHREAD_START_ROUTINE)SendSocketMessage, inner_msg, NULL, 0);
// if (thread) {
// CloseHandle(thread);
// }
}
/// @brief hook msg implement
_declspec(naked) void HandleSyncMsg() {
__asm {
@@ -214,38 +290,35 @@ int HookRecvMsg(char *client_ip, int port) {
strcpy_s(server_ip_, client_ip);
DWORD base = Utils::GetWeChatWinBase();
if (!base) {
SPDLOG_INFO("base addr is null");
return -1;
}
if (msg_hook_flag_) {
SPDLOG_INFO("recv msg hook already called");
return 2;
}
DWORD hook_recv_msg_addr = base + WX_RECV_MSG_HOOK_OFFSET;
msg_next_addr_ = base + WX_RECV_MSG_HOOK_NEXT_OFFSET;
msg_back_addr_ = hook_recv_msg_addr + 0x5;
LOG(INFO) << "base" << base;
LOG(INFO) << "msg_next_addr_" << msg_next_addr_;
LOG(INFO) << "msg_back_addr_" << msg_back_addr_;
msg_back_addr_ = hook_recv_msg_addr + 0x5;
Utils::HookAnyAddress(hook_recv_msg_addr, (LPVOID)HandleSyncMsg,
msg_asm_code_);
DWORD hook_sns_msg_addr = base + WX_SNS_HOOK_OFFSET;
sns_next_addr_ = base + WX_SNS_HOOK_NEXT_OFFSET;
sns_back_addr_ = hook_sns_msg_addr + 0x5;
LOG(INFO) << "base" << base;
LOG(INFO) << "sns_next_addr_" << sns_next_addr_;
LOG(INFO) << "sns_back_addr_" << sns_back_addr_;
Utils::HookAnyAddress(hook_sns_msg_addr, (LPVOID)HandleSNSMsg, sns_asm_code_);
msg_hook_flag_ = true;
SPDLOG_INFO("hook recv msg success");
return 1;
}
int UnHookRecvMsg() {
server_port_ = 0;
if (!msg_hook_flag_) {
LOG(INFO) << "this port already hooked";
SPDLOG_INFO("recv msg hook already called");
return 2;
}
DWORD base = Utils::GetWeChatWinBase();
@@ -271,9 +344,9 @@ void PrintLog(DWORD addr) {
char *ansi_message = new char[size + 1];
memset(ansi_message, 0, size + 1);
WideCharToMultiByte(CP_ACP, 0, w_msg, -1, ansi_message, size, 0, 0);
spdlog::info("wechat log:{}", ansi_message);
delete[] w_msg;
w_msg = NULL;
LOG(INFO) << ansi_message;
delete[] ansi_message;
ansi_message = NULL;
}
@@ -321,7 +394,7 @@ int UnHookLog() {
void SetErrorCode(int code) { userinfo.error_code = code; }
void SetUserInfoDetail(DWORD address) {
LOG(INFO) << "hook userinfo addr" <<&userinfo;
SPDLOG_INFO("hook userinfo addr = {}",address);
DWORD length = *(DWORD *)(address + 0x8);
userinfo.keyword = new wchar_t[length + 1];
userinfo.keyword_len = length;
@@ -352,6 +425,36 @@ void SetUserInfoDetail(DWORD address) {
ZeroMemory(userinfo.big_image, (length + 1) * sizeof(wchar_t));
}
length = *(DWORD *)(address + 0x6C);
userinfo.V3 = new wchar_t[length + 1];
userinfo.V3_len = length;
if (length) {
memcpy(userinfo.V3, (wchar_t *)(*(DWORD *)(address + 0x68)),
(length + 1) * sizeof(wchar_t));
} else {
ZeroMemory(userinfo.V3, (length + 1) * sizeof(wchar_t));
}
length = *(DWORD *)(address + 0x80);
userinfo.account = new wchar_t[length + 1];
userinfo.account_len = length;
if (length) {
memcpy(userinfo.account, (wchar_t *)(*(DWORD *)(address + 0x7C)),
(length + 1) * sizeof(wchar_t));
} else {
ZeroMemory(userinfo.account, (length + 1) * sizeof(wchar_t));
}
// length = *(DWORD *)(address + 0x94);
// userinfo.friend_name = new wchar_t[length + 1];
// userinfo.friend_name_len = length;
// if (length) {
// memcpy(userinfo.friend_name, (wchar_t *)(*(DWORD *)(address + 0x90)),
// (length + 1) * sizeof(wchar_t));
// } else {
// ZeroMemory(userinfo.friend_name, (length + 1) * sizeof(wchar_t));
// }
length = *(DWORD *)(address + 0xC8);
userinfo.nickname = new wchar_t[length + 1];
userinfo.nickname_len = length;
@@ -362,15 +465,28 @@ void SetUserInfoDetail(DWORD address) {
ZeroMemory(userinfo.nickname, (length + 1) * sizeof(wchar_t));
}
length = *(DWORD *)(address + 0x108);
userinfo.v2 = new wchar_t[length + 1];
userinfo.v2_len = length;
if (length) {
memcpy(userinfo.v2, (wchar_t *)(*(DWORD *)(address + 0x104)),
(length + 1) * sizeof(wchar_t));
} else {
ZeroMemory(userinfo.v2, (length + 1) * sizeof(wchar_t));
}
// the results of calling and UI operations are different
//
// length = *(DWORD *)(address + 0x108);
// userinfo.v2 = new wchar_t[length + 1];
// userinfo.v2_len = length;
// if (length) {
// memcpy(userinfo.v2, (wchar_t *)(*(DWORD *)(address + 0x104)),
// (length + 1) * sizeof(wchar_t));
// } else {
// ZeroMemory(userinfo.v2, (length + 1) * sizeof(wchar_t));
// }
// length = *(DWORD *)(address + 0x11C);
// userinfo.py = new wchar_t[length + 1];
// userinfo.py_len = length;
// if (length) {
// memcpy(userinfo.py, (wchar_t *)(*(DWORD *)(address + 0x118)),
// (length + 1) * sizeof(wchar_t));
// } else {
// ZeroMemory(userinfo.py, (length + 1) * sizeof(wchar_t));
// }
length = *(DWORD *)(address + 0x16C);
userinfo.small_image = new wchar_t[length + 1];
@@ -436,9 +552,21 @@ void DeleteUserInfoCache() {
if (userinfo.v3) {
delete userinfo.v3;
}
if (userinfo.V3) {
delete userinfo.V3;
}
if (userinfo.account) {
delete userinfo.account;
}
if (userinfo.friend_name) {
delete userinfo.friend_name;
}
if (userinfo.nickname) {
delete userinfo.nickname;
}
if (userinfo.py) {
delete userinfo.py;
}
if (userinfo.nation) {
delete userinfo.nation;
}
@@ -497,11 +625,11 @@ int HookSearchContact() {
if (search_contact_flag_) {
return 2;
}
DWORD hook_error_code_addr = base + WX_SEARCH_CONTACT_ERROR_CODE_HOOK_OFFSET;
error_code_next_addr_ = base + WX_SEARCH_CONTACT_ERROR_CODE_HOOK_NEXT_OFFSET;
error_code_back_addr_ = hook_error_code_addr + 0x5;
Utils::HookAnyAddress(hook_error_code_addr, (LPVOID)HandleErrorCode,
error_code_asm_code_);
// DWORD hook_error_code_addr = base + WX_SEARCH_CONTACT_ERROR_CODE_HOOK_OFFSET;
// error_code_next_addr_ = base + WX_SEARCH_CONTACT_ERROR_CODE_HOOK_NEXT_OFFSET;
// error_code_back_addr_ = hook_error_code_addr + 0x5;
// Utils::HookAnyAddress(hook_error_code_addr, (LPVOID)HandleErrorCode,
// error_code_asm_code_);
DWORD hook_user_info_addr = base + WX_SEARCH_CONTACT_DETAIL_HOOK_OFFSET;
user_info_next_addr_ = base + WX_SEARCH_CONTACT_DETAIL_HOOK_NEXT_OFFSET;
+9 -6
View File
@@ -9,7 +9,6 @@
#include "chat_room_mgr.h"
#include "contact_mgr.h"
#include "db.h"
#include "easylogging++.h"
#include "hooks.h"
#include "misc_mgr.h"
#include "send_message_mgr.h"
@@ -71,9 +70,9 @@ string Dispatch(struct mg_connection *c, struct mg_http_message *hm) {
if (mg_vcasecmp(&hm->method, "POST") == 0) {
is_post = 1;
}
el::Logger *defaultLogger = el::Loggers::getLogger("default");
defaultLogger->info("method: %v body: %v", hm->method.ptr, hm->body.ptr);
LOG_IF(is_post != 1, INFO) << "request method is not post";
// el::Logger *defaultLogger = el::Loggers::getLogger("default");
// defaultLogger->info("method: %v body: %v", hm->method.ptr, hm->body.ptr);
// LOG_IF(is_post != 1, INFO) << "request method is not post";
if (is_post == 0) {
json ret_data = {{"result", "ERROR"}, {"msg", "not support method"}};
@@ -94,7 +93,7 @@ string Dispatch(struct mg_connection *c, struct mg_http_message *hm) {
case WECHAT_IS_LOGIN: {
int success = -1;
success = g_context.account_mgr->CheckLogin();
json ret_data = {{"result", "OK"}, {"code", success}, {"login_url", g_context.account_mgr->GetLoginUrl()}};
json ret_data = {{"result", "OK"}, {"code", success}};
ret = ret_data.dump();
break;
}
@@ -227,8 +226,12 @@ string Dispatch(struct mg_connection *c, struct mg_http_message *hm) {
{"province", Utils::WCharToUTF8(user->province)},
{"sex", user->sex},
{"signature", Utils::WCharToUTF8(user->signature)},
{"v2", Utils::WCharToUTF8(user->v2)},
// {"v2", Utils::WCharToUTF8(user->v2)},
{"v3", Utils::WCharToUTF8(user->v3)},
{"V3", Utils::WCharToUTF8(user->V3)},
{"account", Utils::WCharToUTF8(user->account)},
// {"friendName", Utils::WCharToUTF8(user->friend_name)},
// {"py", Utils::WCharToUTF8(user->py)},
};
ret_data["userInfo"] = info;
}
+12 -29
View File
@@ -1,37 +1,20 @@
#include "log.h"
#include "easylogging++.h"
INITIALIZE_EASYLOGGINGPP
#include "pch.h"
#include "log.h"
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_INFO
namespace wxhelper {
Log::Log(/* args */) {}
Log::~Log() {}
Log::~Log() {
}
void Log::Initialize() {
el::Configurations conf;
// 启用日志
conf.setGlobally(el::ConfigurationType::Enabled, "true");
// 设置日志文件目录以及文件名
conf.setGlobally(el::ConfigurationType::Filename,
"log\\log_%datetime{%Y%M%d %H%m%s}.log");
// 设置日志文件最大文件大小
conf.setGlobally(el::ConfigurationType::MaxLogFileSize, "20971520");
// 是否写入文件
conf.setGlobally(el::ConfigurationType::ToFile, "true");
// 是否输出控制台
conf.setGlobally(el::ConfigurationType::ToStandardOutput, "true");
// 设置日志输出格式
conf.setGlobally(el::ConfigurationType::Format,
"[%datetime] [%thread] [%loc] [%level] : %msg");
// 设置日志文件写入周期,如下每100条刷新到输出流中
#ifdef _DEBUG
conf.setGlobally(el::ConfigurationType::LogFlushThreshold, "1");
#else
conf.setGlobally(el::ConfigurationType::LogFlushThreshold, "100");
#endif
// 设置配置文件
el::Loggers::reconfigureAllLoggers(conf);
auto logger = spdlog::daily_logger_mt("daily_logger", "logs/daily.txt", 23, 59);
logger->flush_on(spdlog::level::err);
spdlog::set_default_logger(logger);
spdlog::flush_every(std::chrono::seconds(3));
spdlog::set_level(spdlog::level::debug);
spdlog::set_pattern("%Y-%m-%d %H:%M:%S [%l] [%t] - <%s>|<%#>|<%!>,%v");
}
} // namespace wxhelper
+10 -28
View File
@@ -5,7 +5,6 @@
#include "base64.h"
#include "db.h"
#include "hooks.h"
#include "easylogging++.h"
#define BUFSIZE 1024
#define JPEG0 0xFF
@@ -154,8 +153,8 @@ int MiscMgr::DoDownloadTask(ULONG64 msg_id) {
DWORD get_current_data_path_addr = base_addr_ + WX_GET_CURRENT_DATA_PATH_OFFSET;
DWORD free_app_msg_info_addr = base_addr_ + WX_FREE_APP_MSG_INFO_OFFSET;
DWORD push_thumb_task_addr = base_addr_ + WX_PUSH_THUMB_TASK_OFFSET;
DWORD video_mgr_addr = base_addr_ + WX_VIDEO_MGR_OFFSET;
DWORD download_video_image_addr = base_addr_ + WX_VIDEO_MGR_OFFSET;
WeChatString current_data_path;
@@ -256,23 +255,7 @@ int MiscMgr::DoDownloadTask(ULONG64 msg_id) {
memcpy(&chat_msg[0x19C], &w_thumb_path, sizeof(w_thumb_path));
memcpy(&chat_msg[0x1B0], &w_save_path, sizeof(w_save_path));
memcpy(&chat_msg[0x29C], &temp, sizeof(temp));
// note: the image has been downloaded and will not be downloaded again
// use low-level method
// this function does not work, need to modify chatmsg.
// if (type == 0x3E || type == 0x2B){
// __asm{
// PUSHAD
// PUSHFD
// CALL video_mgr_addr
// LEA ECX,chat_msg
// PUSH ECX
// MOV ECX,EAX
// CALL download_video_image_addr
// POPFD
// POPAD
// }
// }
__asm {
PUSHAD
PUSHFD
@@ -402,8 +385,8 @@ int MiscMgr::GetImgByName(wchar_t* file_path,wchar_t* save_dir) {
int MiscMgr::SearchContactNetScene(wchar_t *keyword,UserInfo ** user) {
int success = -1;
hooks::HookSearchContact();
hooks::DeleteUserInfoCache();
hooks::HookSearchContact();
DWORD search_contact_mgr_addr = base_addr_ + WX_SEARCH_CONTACT_MGR_OFFSET;
DWORD search_contact_addr = base_addr_ + WX_SEARCH_CONTACT_OFFSET;
WeChatString key(keyword);
@@ -420,16 +403,15 @@ int MiscMgr::SearchContactNetScene(wchar_t *keyword,UserInfo ** user) {
popad;
}
success = 1;
while (hooks::userinfo.error_code == 1 && hooks::user_info_flag_) {
Sleep(20);
}
if (hooks::userinfo.error_code == 0) {
// while (hooks::userinfo.error_code == 1 && hooks::user_info_flag_) {
// Sleep(20);
// }
// if (hooks::userinfo.error_code == 0) {
while (hooks::userinfo.over == false && hooks::user_info_flag_) {
Sleep(20);
Sleep(2);
}
}
// }
*user= &hooks::userinfo;
LOG(INFO)<<"user:" <<user;
return success;
}
+5
View File
@@ -16,6 +16,11 @@
#include <fcntl.h>
#include "Windows.h"
#include "utils.h"
#include "spdlog/spdlog.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/sinks/daily_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#endif // PCH_H
+12 -8
View File
@@ -1,12 +1,9 @@
#include "pch.h"
#include "send_message_mgr.h"
#include "easylogging++.h"
#include "wechat_function.h"
#include "db.h"
#include "contact_mgr.h"
#include "spdlog/spdlog.h"
namespace wxhelper {
SendMessageMgr::SendMessageMgr(DWORD base):BaseMgr(base) {}
SendMessageMgr::~SendMessageMgr() {}
@@ -21,6 +18,7 @@ int SendMessageMgr::SendText(wchar_t* wxid, wchar_t* msg) {
char chat_msg[0x2D8] = {0};
__asm {
PUSHAD
PUSHFD
CALL send_message_mgr_addr
PUSH 0x0
PUSH 0x0
@@ -36,9 +34,11 @@ int SendMessageMgr::SendText(wchar_t* wxid, wchar_t* msg) {
ADD ESP,0x18
LEA ECX,chat_msg
CALL free_chat_msg_addr
POPFD
POPAD
}
LOG_IF((success == -1), ERROR) << "SendText fail";
SPDLOG_INFO("SendText code = {}",success);
SPDLOG_INFO("global log with source info");
return success;
}
int SendMessageMgr::SendAtText(wchar_t* chat_room_id, wchar_t** wxids, int len,
@@ -86,6 +86,7 @@ int SendMessageMgr::SendAtText(wchar_t* chat_room_id, wchar_t** wxids, int len,
char chat_msg[0x2D8] = {0};
__asm{
PUSHAD
PUSHFD
CALL send_message_mgr_addr
PUSH 0x0
PUSH 0x0
@@ -102,9 +103,10 @@ int SendMessageMgr::SendAtText(wchar_t* chat_room_id, wchar_t** wxids, int len,
ADD ESP,0x18
LEA ECX,chat_msg
CALL free_chat_msg_addr
POPFD
POPAD
}
LOG_IF((success == -1), ERROR) << "SendText fail";
SPDLOG_INFO("SendText code = {}",success);
return success;
}
int SendMessageMgr::SendImage(wchar_t* wxid, wchar_t* image_path) {
@@ -120,6 +122,7 @@ int SendMessageMgr::SendImage(wchar_t* wxid, wchar_t* image_path) {
WeChatString null_obj = {0};
__asm {
PUSHAD
PUSHFD
CALL send_message_mgr_addr
SUB ESP,0x14
MOV temp,EAX
@@ -138,9 +141,10 @@ int SendMessageMgr::SendImage(wchar_t* wxid, wchar_t* image_path) {
MOV success,EAX
LEA ECX,chat_msg
CALL free_msg_addr
POPFD
POPAD
}
LOG_IF((success == -1), ERROR) << "SendImage fail";
SPDLOG_INFO("SendImage code = {}",success);
return success;
}
int SendMessageMgr::SendFile(wchar_t* wxid, wchar_t* file_path) {
@@ -194,10 +198,10 @@ int SendMessageMgr::SendFile(wchar_t* wxid, wchar_t* file_path) {
POPFD
POPAD
}
SPDLOG_INFO("SendFile code = {}",success);
if (success == 0x31) {
return 1;
}
LOG_IF((success == -1), ERROR) << "SendFile fail";
return success;
}
+41
View File
@@ -0,0 +1,41 @@

#include "pch.h"
#include "thread_pool.h"
#include "Windows.h"
namespace wxhelper {
ThreadPool::~ThreadPool() {
CloseThreadpoolCleanupGroupMembers(cleanup_group_, true, NULL);
CloseThreadpoolCleanupGroup(cleanup_group_);
CloseThreadpool(pool_);
}
bool ThreadPool::Create(unsigned long min, unsigned long max) {
InitializeThreadpoolEnvironment(&env_);
pool_ = CreateThreadpool(NULL);
if (NULL == pool_) {
return false;
}
SetThreadpoolThreadMaximum(pool_, max);
BOOL ret = SetThreadpoolThreadMinimum(pool_, min);
if (FALSE == ret) {
return false;
}
cleanup_group_ = CreateThreadpoolCleanupGroup();
if (NULL == cleanup_group_) {
return false;
}
SetThreadpoolCallbackPool(&env_, pool_);
SetThreadpoolCallbackCleanupGroup(&env_, cleanup_group_, NULL);
return true;
}
bool ThreadPool::AddWork(PTP_WORK_CALLBACK callback,PVOID opt) {
PTP_WORK work = CreateThreadpoolWork(callback, opt, &env_);
if (NULL == work) {
return false;
}
SubmitThreadpoolWork(work);
return true;
}
} // namespace wxhelper
+26
View File
@@ -0,0 +1,26 @@
#ifndef WXHELPER_THREAD_POOL_H_
#define WXHELPER_THREAD_POOL_H_
#include "Windows.h"
#include "singleton.h"
namespace wxhelper {
class ThreadPool :public Singleton<ThreadPool>{
public:
~ThreadPool();
bool Create(unsigned long min = 1, unsigned long max = 4);
bool AddWork(PTP_WORK_CALLBACK callback,PVOID opt);
private:
void operator=(const ThreadPool&) = delete;
void operator=(ThreadPool&&) = delete;
PTP_POOL pool_;
PTP_CLEANUP_GROUP cleanup_group_;
TP_CALLBACK_ENVIRON env_;
};
} // namespace wxhelper
#endif
+100 -95
View File
@@ -4,97 +4,95 @@
#include <string>
// snsDataMgr
#define WX_SNS_DATA_MGR_OFFSET 0xc39680
#define WX_SNS_DATA_MGR_OFFSET 0xc3a500
// chatRoomMgr
#define WX_CHAT_ROOM_MGR_OFFSET 0x78cf20
#define WX_CHAT_ROOM_MGR_OFFSET 0x78d9d0
// contactMgr
#define WX_CONTACT_MGR_OFFSET 0x75a4a0
#define WX_CONTACT_MGR_OFFSET 0x75af30
// syncMgr
#define WX_SYNC_MGR_OFFSET 0xa87fd0
// preDownloadMgr
#define WX_GET_PRE_DOWNLOAD_MGR_OFFSET 0x80f110
#define WX_GET_PRE_DOWNLOAD_MGR_OFFSET 0x80fe50
// chatMgr
#define WX_CHAT_MGR_OFFSET 0x792700
#define WX_CHAT_MGR_OFFSET 0x7931b0
// videoMgr
#define WX_VIDEO_MGR_OFFSET 0x829820
#define WX_VIDEO_MGR_OFFSET 0x82a560
// patMgr
#define WX_PAT_MGR_OFFSET 0x931730
#define WX_PAT_MGR_OFFSET 0x932470
// searchContactMgr
#define WX_SEARCH_CONTACT_MGR_OFFSET 0xa6cb00
#define WX_SEARCH_CONTACT_MGR_OFFSET 0xa6d860
// appMsgMgr
#define WX_APP_MSG_MGR_OFFSET 0x76ae20
#define WX_APP_MSG_MGR_OFFSET 0x76b8c0
// sendMessageMgr
#define WX_SEND_MESSAGE_MGR_OFFSET 0x768140
#define WX_SEND_MESSAGE_MGR_OFFSET 0x768be0
// setChatMsgValue
#define WX_INIT_CHAT_MSG_OFFSET 0xf59e40
#define WX_INIT_CHAT_MSG_OFFSET 0xf5b3f0
// chatMsg
#define WX_NEW_CHAT_MSG_OFFSET 0x76f010
#define WX_FREE_CHAT_MSG_OFFSET 0x756960
#define WX_FREE_CHAT_MSG_2_OFFSET 0x6f4ea0
#define WX_FREE_CHAT_MSG_INSTANCE_COUNTER_OFFSET 0x756e30
#define WX_NEW_CHAT_MSG_OFFSET 0x76fab0
#define WX_FREE_CHAT_MSG_OFFSET 0x7573f0
// #define WX_FREE_CHAT_MSG_2_OFFSET 0x6f4ea0
#define WX_FREE_CHAT_MSG_INSTANCE_COUNTER_OFFSET 0x7578c0
//sns
#define WX_SNS_GET_FIRST_PAGE_OFFSET 0x14e2140
#define WX_SNS_GET_NEXT_PAGE_OFFSET 0x14e21e0
#define WX_SNS_GET_FIRST_PAGE_OFFSET 0x14e36e0
#define WX_SNS_GET_NEXT_PAGE_OFFSET 0x14e3780
//chat room
#define WX_GET_CHAT_ROOM_DETAIL_INFO_OFFSET 0xbde090
#define WX_GET_CHAT_ROOM_DETAIL_INFO_OFFSET 0xbdef30
// chatRoomInfo
#define WX_NEW_CHAT_ROOM_INFO_OFFSET 0xe99c40
#define WX_FREE_CHAT_ROOM_INFO_OFFSET 0xe99f40
#define WX_DEL_CHAT_ROOM_MEMBER_OFFSET 0xbd22a0
#define WX_ADD_MEMBER_TO_CHAT_ROOM_OFFSET 0xbd1dc0
#define WX_NEW_CHAT_ROOM_INFO_OFFSET 0xe9abd0
#define WX_FREE_CHAT_ROOM_INFO_OFFSET 0xe9aed0
#define WX_DEL_CHAT_ROOM_MEMBER_OFFSET 0xbd3140
#define WX_ADD_MEMBER_TO_CHAT_ROOM_OFFSET 0xbd2c60
// chatRoom
#define WX_INIT_CHAT_ROOM_OFFSET 0xe97890
#define WX_FREE_CHAT_ROOM_OFFSET 0xe97ab0
#define WX_INIT_CHAT_ROOM_OFFSET 0xe98820
#define WX_FREE_CHAT_ROOM_OFFSET 0xe98a40
#define WX_GET_MEMBER_FROM_CHAT_ROOM_OFFSET 0xbdf260
#define WX_MOD_CHAT_ROOM_MEMBER_NICK_NAME_OFFSET 0xbd9680
#define WX_GET_MEMBER_FROM_CHAT_ROOM_OFFSET 0xbe0100
#define WX_MOD_CHAT_ROOM_MEMBER_NICK_NAME_OFFSET 0xbda520
#define WX_TOP_MSG_OFFSET 0xbe1840
#define WX_REMOVE_TOP_MSG_OFFSET 0xbe1620
#define WX_TOP_MSG_OFFSET 0xbe26e0
#define WX_REMOVE_TOP_MSG_OFFSET 0xbe24c0
#define WX_GET_MEMBER_NICKNAME_OFFSET 0xbdf3f0
#define WX_GET_MEMBER_NICKNAME_OFFSET 0xbe0290
#define WX_FREE_CONTACT_OFFSET 0xea7880
#define WX_FREE_CONTACT_OFFSET 0xea8800
// wcpayinfo
#define WX_NEW_WCPAYINFO_OFFSET 0x7b2e60
#define WX_FREE_WCPAYINFO_OFFSET 0x79c250
#define WX_CONFIRM_RECEIPT_OFFSET 0x15e2c20
#define WX_NEW_WCPAYINFO_OFFSET 0x7b3900
#define WX_FREE_WCPAYINFO_OFFSET 0x79cd00
#define WX_CONFIRM_RECEIPT_OFFSET 0x15e41d0
//contact
#define WX_CONTACT_GET_LIST_OFFSET 0xc089f0
#define WX_CONTACT_GET_LIST_OFFSET 0xc09890
#define WX_CONTACT_DEL_OFFSET 0xb9b3b0
#define WX_SET_VALUE_OFFSET 0x1f80900
#define WX_DO_DEL_CONTACT_OFFSET 0xca6480
#define WX_GET_CONTACT_OFFSET 0xc04e00
#define WX_DO_VERIFY_USER_OFFSET 0xc02100
#define WX_VERIFY_MSG_OFFSET 0xf59d40
#define WX_VERIFY_OK_OFFSET 0xa18bd0
#define WX_NEW_ADD_FRIEND_HELPER_OFFSET 0xa17d50
#define WX_FREE_ADD_FRIEND_HELPER_OFFSET 0xa17e70
#define WX_GET_CONTACT_OFFSET 0xc05ca0
#define WX_DO_VERIFY_USER_OFFSET 0xc02f90
#define WX_VERIFY_MSG_OFFSET 0xf5b2f0
#define WX_VERIFY_OK_OFFSET 0xa19940
#define WX_NEW_ADD_FRIEND_HELPER_OFFSET 0xa18ac0
#define WX_FREE_ADD_FRIEND_HELPER_OFFSET 0xa18be0
// pushAttachTask
#define WX_PUSH_ATTACH_TASK_OFFSET 0x82bb40
#define WX_PUSH_ATTACH_TASK_OFFSET 0x82c880
#define WX_FREE_CHAT_MSG_OFFSET 0x756960
#define WX_GET_MGR_BY_PREFIX_LOCAL_ID_OFFSET 0xbc0370
#define WX_GET_CURRENT_DATA_PATH_OFFSET 0xc872c0
#define WX_GET_MGR_BY_PREFIX_LOCAL_ID_OFFSET 0xbc11d0
#define WX_APP_MSG_INFO_OFFSET 0x7b3d20
#define WX_GET_APP_MSG_XML_OFFSET 0xe628a0
#define WX_FREE_APP_MSG_INFO_OFFSET 0x79d900
#define WX_PUSH_THUMB_TASK_OFFSET 0x82ba40
#define WX_FREE_APP_MSG_INFO_OFFSET 0x79e3b0
#define WX_PUSH_THUMB_TASK_OFFSET 0x82c780
#define WX_DOWNLOAD_VIDEO_IMG_OFFSET 0xd46c30
@@ -102,46 +100,45 @@
// pat
#define WX_SEND_PAT_MSG_OFFSET 0x1421940
#define WX_RET_OFFSET 0x1D58751
#define WX_SEND_PAT_MSG_OFFSET 0x1422f30
#define WX_RET_OFFSET 0x1D59DB1
//search hook
#define WX_SEARCH_CONTACT_ERROR_CODE_HOOK_OFFSET 0xe17054
#define WX_SEARCH_CONTACT_ERROR_CODE_HOOK_NEXT_OFFSET 0xf57a20
#define WX_SEARCH_CONTACT_DETAIL_HOOK_OFFSET 0xa8ceb0
#define WX_SEARCH_CONTACT_DETAIL_HOOK_NEXT_OFFSET 0xa8d100
#define WX_SEARCH_CONTACT_OFFSET 0xcd1510
#define WX_SEARCH_CONTACT_ERROR_CODE_HOOK_OFFSET 0xe17ed4
#define WX_SEARCH_CONTACT_ERROR_CODE_HOOK_NEXT_OFFSET 0xf58fd0
#define WX_SEARCH_CONTACT_DETAIL_HOOK_OFFSET 0xa8dc00
#define WX_SEARCH_CONTACT_DETAIL_HOOK_NEXT_OFFSET 0xa8de50
#define WX_SEARCH_CONTACT_OFFSET 0xcd2370
//login
#define WX_LOGIN_URL_OFFSET 0x3040DE8
#define WX_LOGOUT_OFFSET 0xe58870
#define WX_ACCOUNT_SERVICE_OFFSET 0x768c80
#define WX_GET_APP_DATA_SAVE_PATH_OFFSET 0xf3a610
#define WX_GET_CURRENT_DATA_PATH_OFFSET 0xc872c0
#define WX_LOGOUT_OFFSET 0xe596d0
#define WX_ACCOUNT_SERVICE_OFFSET 0x769720
#define WX_GET_APP_DATA_SAVE_PATH_OFFSET 0xf3bbd0
#define WX_GET_CURRENT_DATA_PATH_OFFSET 0xc88120
//forward
#define WX_FORWARD_MSG_OFFSET 0xce6730
#define WX_FORWARD_MSG_OFFSET 0xce75a0
// send file
#define WX_SEND_FILE_OFFSET 0xb6d1f0
#define WX_SEND_FILE_OFFSET 0xb6dfd0
// send image
#define WX_SEND_IMAGE_OFFSET 0xce6640
#define WX_SEND_IMAGE_OFFSET 0xce74b0
// send text
#define WX_SEND_TEXT_OFFSET 0xce6c80
#define WX_SEND_TEXT_OFFSET 0xce7af0
//ocr
#define WX_INIT_OBJ_OFFSET 0x80a800
#define WX_OCR_MANAGER_OFFSET 0x80f270
#define WX_DO_OCR_TASK_OFFSET 0x13da3e0
#define WX_INIT_OBJ_OFFSET 0x80b540
#define WX_OCR_MANAGER_OFFSET 0x80ffc0
#define WX_DO_OCR_TASK_OFFSET 0x13db9a0
//storage
#define CONTACT_G_PINSTANCE_OFFSET 0x2ffddc8
#define CONTACT_G_PINSTANCE_OFFSET 0x2fffe08
#define DB_MICRO_MSG_OFFSET 0x68
#define DB_CHAT_MSG_OFFSET 0x1C0
#define DB_MISC_OFFSET 0x3D8
@@ -154,10 +151,10 @@
#define STORAGE_START_OFFSET 0x13f8
#define STORAGE_END_OFFSET 0x13fc
#define PUBLIC_MSG_MGR_OFFSET 0x303df74
#define MULTI_DB_MSG_MGR_OFFSET 0x30403b8
#define FAVORITE_STORAGE_MGR_OFFSET 0x303fd40
#define FTS_FAVORITE_MGR_OFFSET 0x2ffe908
#define PUBLIC_MSG_MGR_OFFSET 0x30400a4
#define MULTI_DB_MSG_MGR_OFFSET 0x30424dc
#define FAVORITE_STORAGE_MGR_OFFSET 0x3041e70
#define FTS_FAVORITE_MGR_OFFSET 0x3000948
#define OP_LOG_STORAGE_VFTABLE 0x2AD3A20
#define CHAT_MSG_STORAGE_VFTABLE 0x2AC10F0
@@ -197,15 +194,15 @@
// hook log
#define WX_HOOK_LOG_OFFSET 0xf57d67
#define WX_HOOK_LOG_NEXT_OFFSET 0x240ea71
#define WX_HOOK_LOG_OFFSET 0xf59317
#define WX_HOOK_LOG_NEXT_OFFSET 0x24102b4
// hook msg
#define WX_RECV_MSG_HOOK_OFFSET 0xd19a0b
#define WX_RECV_MSG_HOOK_NEXT_OFFSET 0x756960
#define WX_SNS_HOOK_OFFSET 0x14f9e15
#define WX_SNS_HOOK_NEXT_OFFSET 0x14fa0a0
#define WX_RECV_MSG_HOOK_OFFSET 0xd1a89b
#define WX_RECV_MSG_HOOK_NEXT_OFFSET 0x7573f0
#define WX_SNS_HOOK_OFFSET 0x14fb3b5
#define WX_SNS_HOOK_NEXT_OFFSET 0x14fb640
// hook voice
@@ -351,24 +348,24 @@
#define SQLITE_NULL 5
#define SQLITE_TEXT 3
#define SQLITE3_EXEC_OFFSET 0x1e24f70
#define SQLITE3_BACKUP_INIT_OFFSET 0x1dea900
#define SQLITE3_PREPARE_OFFSET 0x1e2b8c0
#define SQLITE3_OPEN_OFFSET 0x1e598b0
#define SQLITE3_BACKUP_STEP_OFFSET 0x1dead00
#define SQLITE3_BACKUP_REMAINING_OFFSET 0x1deb440
#define SQLITE3_BACKUP_PAGECOUNT_OFFSET 0x1deb450
#define SQLITE3_BACKUP_FINISH_OFFSET 0x1deb340
#define SQLITE3_SLEEP_OFFSET 0x1e5a0f0
#define SQLITE3_ERRCODE_OFFSET 0x1e58550
#define SQLITE3_CLOSE_OFFSET 0x1e56cd0
#define SQLITE3_STEP_OFFSET 0x1df3770
#define SQLITE3_COLUMN_COUNT_OFFSET 0x1df3c80
#define SQLITE3_COLUMN_NAME_OFFSET 0x1df4570
#define SQLITE3_COLUMN_TYPE_OFFSET 0x1df4410
#define SQLITE3_COLUMN_BLOB_OFFSET 0x1df3cc0
#define SQLITE3_COLUMN_BYTES_OFFSET 0x1df3da0
#define SQLITE3_FINALIZE_OFFSET 0x1df2740
#define SQLITE3_EXEC_OFFSET 0x1e26770
#define SQLITE3_BACKUP_INIT_OFFSET 0x1dec100
#define SQLITE3_PREPARE_OFFSET 0x1E2D0C0
#define SQLITE3_OPEN_OFFSET 0x1e5b090
#define SQLITE3_BACKUP_STEP_OFFSET 0x1DEC500
#define SQLITE3_BACKUP_REMAINING_OFFSET 0x1DECC40
#define SQLITE3_BACKUP_PAGECOUNT_OFFSET 0x1DECC50
#define SQLITE3_BACKUP_FINISH_OFFSET 0x1DECB40
#define SQLITE3_SLEEP_OFFSET 0x1e5b8d0
#define SQLITE3_ERRCODE_OFFSET 0x1e59d30
#define SQLITE3_CLOSE_OFFSET 0x1e584b0
#define SQLITE3_STEP_OFFSET 0x1df4f70
#define SQLITE3_COLUMN_COUNT_OFFSET 0x1df5480
#define SQLITE3_COLUMN_NAME_OFFSET 0x1df5d70
#define SQLITE3_COLUMN_TYPE_OFFSET 0x1df5c10
#define SQLITE3_COLUMN_BLOB_OFFSET 0x1df54c0
#define SQLITE3_COLUMN_BYTES_OFFSET 0x1df55a0
#define SQLITE3_FINALIZE_OFFSET 0x1df3f40
typedef int (*Sqlite3_callback)(void*, int, char**, char**);
@@ -579,12 +576,20 @@ struct UserInfo {
int keyword_len;
wchar_t *v3;
int v3_len;
wchar_t *V3;
int V3_len;
wchar_t *account;
int account_len;
wchar_t *friend_name;
int friend_name_len;
wchar_t *nickname;
int nickname_len;
wchar_t *signature;
int signature_len;
wchar_t *v2;
int v2_len;
wchar_t *py;
int py_len;
wchar_t *nation;
int nation_len;
wchar_t *province;