Compare commits
20
Commits
tool
...
3.9.2.26-v3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
826e504fb3 | ||
|
|
80718a2af5 | ||
|
|
aaada266df | ||
|
|
581aacb8ce | ||
|
|
dccc997067 | ||
|
|
0b52a49155 | ||
|
|
4027c4afe6 | ||
|
|
dcbde9203b | ||
|
|
76dc8affe9 | ||
|
|
fd3e6f4a70 | ||
|
|
18e34cd11b | ||
|
|
83d779c072 | ||
|
|
8fa942c741 | ||
|
|
c0b55da015 | ||
|
|
34eb14edb2 | ||
|
|
f9a7924658 | ||
|
|
6105789fcc | ||
|
|
dffdbfb9d7 | ||
|
|
8279303614 | ||
|
|
5ba4f72d5c |
@@ -0,0 +1,3 @@
|
||||
[submodule "spdlog"]
|
||||
path = spdlog
|
||||
url = https://github.com/gabime/spdlog
|
||||
+11
-5
@@ -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'")
|
||||
|
||||
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
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
#### 功能预览:
|
||||
0.检查是否登录
|
||||
1.获取登录微信信息
|
||||
2.发送文本
|
||||
2.发送文本
|
||||
3.发送@文本
|
||||
5.发送图片
|
||||
6.发送文件
|
||||
9.hook消息
|
||||
@@ -31,7 +32,7 @@
|
||||
46.联系人列表
|
||||
47.获取群详情
|
||||
48.获取解密图片
|
||||
<!-- 49.图片提取文字ocr -->
|
||||
49.图片提取文字ocr
|
||||
50.拍一拍
|
||||
51.群消息置顶消息
|
||||
52.群消息取消置顶
|
||||
|
||||
+1630
File diff suppressed because it is too large
Load Diff
+1746
File diff suppressed because it is too large
Load Diff
@@ -771,6 +771,128 @@ error:
|
||||
return result;
|
||||
}
|
||||
|
||||
int InjectDllAndStartHttpByPid(unsigned int pid, wchar_t* szDllPath, DWORD port)
|
||||
{
|
||||
if(!EnableDebugPrivilege()){
|
||||
return 0;
|
||||
}
|
||||
int result = 0;
|
||||
HANDLE hRemoteThread = NULL;
|
||||
LPTHREAD_START_ROUTINE lpSysLibAddr = NULL;
|
||||
HINSTANCE__* hKernelModule = NULL;
|
||||
LPVOID lpRemoteDllBase = NULL;
|
||||
HANDLE hProcess;
|
||||
size_t ulDllLength;
|
||||
wchar_t* dllName = (wchar_t*)L"wxhelper.dll";
|
||||
size_t dllNameLen = wcslen(dllName) * 2 + 2;
|
||||
char* funcName = (char* )"http_start";
|
||||
size_t funcNameLen = strlen(funcName) + 1;
|
||||
|
||||
HANDLE hStartHttp = NULL;
|
||||
LPVOID portAddr = NULL;
|
||||
HANDLE getProcThread = NULL;
|
||||
|
||||
LPVOID paramsAddr = NULL;
|
||||
LPVOID param1Addr = NULL;
|
||||
LPVOID param2Addr = NULL;
|
||||
LPVOID GetProcFuncAddr = NULL;
|
||||
|
||||
DWORD params[2] = { 0 };
|
||||
|
||||
ulDllLength = (wcslen(szDllPath) + 1) * sizeof(wchar_t);
|
||||
hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
|
||||
if (!hProcess) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
lpRemoteDllBase = VirtualAllocEx(hProcess, NULL, ulDllLength, MEM_COMMIT, PAGE_READWRITE);
|
||||
if (lpRemoteDllBase)
|
||||
{
|
||||
if (WriteProcessMemory(hProcess, lpRemoteDllBase, szDllPath, ulDllLength, NULL)
|
||||
&& (hKernelModule = GetModuleHandleW(L"kernel32.dll")) != 0
|
||||
&& (lpSysLibAddr = (LPTHREAD_START_ROUTINE)GetProcAddress(hKernelModule, "LoadLibraryW")) != 0
|
||||
&& (hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, lpSysLibAddr, lpRemoteDllBase, 0, NULL)) != 0)
|
||||
{
|
||||
WaitForSingleObject(hRemoteThread, INFINITE);
|
||||
GetProcFuncAddr = FillAsmCode(hProcess);
|
||||
param1Addr = VirtualAllocEx(hProcess, NULL, dllNameLen, MEM_COMMIT, PAGE_READWRITE);
|
||||
if (param1Addr) {
|
||||
SIZE_T dwWriteSize;
|
||||
BOOL bRet = WriteProcessMemory(hProcess, (LPVOID)param1Addr, dllName, dllNameLen, &dwWriteSize);
|
||||
if (!bRet) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
param2Addr = VirtualAllocEx(hProcess, NULL, funcNameLen, MEM_COMMIT, PAGE_READWRITE);
|
||||
if (param2Addr) {
|
||||
SIZE_T dwWriteSize;
|
||||
BOOL bRet = WriteProcessMemory(hProcess, (LPVOID)param2Addr, funcName, funcNameLen, &dwWriteSize);
|
||||
if (!bRet) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
params[0] = (DWORD)param1Addr;
|
||||
params[1] = (DWORD)param2Addr;
|
||||
|
||||
paramsAddr = VirtualAllocEx(hProcess, NULL, sizeof(params), MEM_COMMIT, PAGE_READWRITE);
|
||||
if (paramsAddr) {
|
||||
SIZE_T dwWriteSize;
|
||||
BOOL bRet = WriteProcessMemory(hProcess, (LPVOID)paramsAddr, ¶ms[0], sizeof(params), &dwWriteSize);
|
||||
if (!bRet) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD dwRet = 0;
|
||||
getProcThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcFuncAddr, paramsAddr, 0, NULL);
|
||||
|
||||
if (getProcThread)
|
||||
{
|
||||
WaitForSingleObject(getProcThread, INFINITE);
|
||||
GetExitCodeThread(getProcThread, &dwRet);
|
||||
if (dwRet) {
|
||||
hStartHttp = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)dwRet, (LPVOID)port, 0, NULL);
|
||||
WaitForSingleObject(hStartHttp, INFINITE);
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
error:
|
||||
if (hRemoteThread) {
|
||||
CloseHandle(hRemoteThread);
|
||||
}
|
||||
if (getProcThread) {
|
||||
CloseHandle(getProcThread);
|
||||
}
|
||||
if (hStartHttp) {
|
||||
CloseHandle(hStartHttp);
|
||||
}
|
||||
|
||||
if (lpRemoteDllBase) {
|
||||
VirtualFreeEx(hProcess, lpRemoteDllBase, ulDllLength, MEM_DECOMMIT | MEM_RELEASE);
|
||||
}
|
||||
if (param1Addr) {
|
||||
VirtualFreeEx(hProcess, param1Addr, dllNameLen, MEM_DECOMMIT | MEM_RELEASE);
|
||||
}
|
||||
|
||||
if (param2Addr) {
|
||||
VirtualFreeEx(hProcess, param1Addr, funcNameLen, MEM_DECOMMIT | MEM_RELEASE);
|
||||
}
|
||||
|
||||
if (paramsAddr) {
|
||||
VirtualFreeEx(hProcess, param1Addr, sizeof(params), MEM_DECOMMIT | MEM_RELEASE);
|
||||
}
|
||||
|
||||
if (GetProcFuncAddr) {
|
||||
VirtualFreeEx(hProcess, GetProcFuncAddr, sizeof(GetProcAddressAsmCode), MEM_DECOMMIT | MEM_RELEASE);
|
||||
}
|
||||
|
||||
CloseHandle(hProcess);
|
||||
return result;
|
||||
}
|
||||
|
||||
int InjectDll(wchar_t* szPName, wchar_t* szDllPath)
|
||||
{
|
||||
if(!EnableDebugPrivilege()){
|
||||
@@ -825,6 +947,58 @@ int InjectDll(wchar_t* szPName, wchar_t* szDllPath)
|
||||
return result;
|
||||
}
|
||||
|
||||
int InjectDllByPid(unsigned int pid, wchar_t* szDllPath)
|
||||
{
|
||||
if(!EnableDebugPrivilege()){
|
||||
return 0;
|
||||
}
|
||||
int result = 0;
|
||||
HANDLE hRemoteThread;
|
||||
LPTHREAD_START_ROUTINE lpSysLibAddr;
|
||||
HINSTANCE__* hKernelModule;
|
||||
LPVOID lpRemoteDllBase;
|
||||
HANDLE hProcess;
|
||||
size_t ulDllLength;
|
||||
|
||||
ulDllLength = (wcslen(szDllPath) + 1) * sizeof(wchar_t);
|
||||
hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
|
||||
if (!hProcess) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
lpRemoteDllBase = VirtualAllocEx(hProcess, NULL, ulDllLength, MEM_COMMIT, PAGE_READWRITE);
|
||||
if (lpRemoteDllBase)
|
||||
{
|
||||
if (WriteProcessMemory(hProcess, lpRemoteDllBase, szDllPath, ulDllLength, NULL)
|
||||
&& (hKernelModule = GetModuleHandleW(L"kernel32.dll")) != 0
|
||||
&& (lpSysLibAddr = (LPTHREAD_START_ROUTINE)GetProcAddress(hKernelModule, "LoadLibraryW")) != 0
|
||||
&& (hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, lpSysLibAddr, lpRemoteDllBase, 0, NULL)) != 0)
|
||||
{
|
||||
WaitForSingleObject(hRemoteThread, INFINITE);
|
||||
VirtualFreeEx(hProcess, lpRemoteDllBase, ulDllLength, MEM_DECOMMIT | MEM_RELEASE);
|
||||
CloseHandle(hRemoteThread);
|
||||
CloseHandle(hProcess);
|
||||
OutputDebugStringA("[DBG] dll inject success");
|
||||
printf("dll inject success");
|
||||
printf("dll path : %s ", szDllPath);
|
||||
printf("pid : %d ", pid);
|
||||
result = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
VirtualFreeEx(hProcess, lpRemoteDllBase, ulDllLength, MEM_DECOMMIT | MEM_RELEASE);
|
||||
CloseHandle(hProcess);
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CloseHandle(hProcess);
|
||||
result = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int UnInjectDll(wchar_t* szPName, wchar_t* szDName)
|
||||
{
|
||||
HMODULE hDll;
|
||||
@@ -878,8 +1052,9 @@ int main(int argc, char** argv)
|
||||
int port = 0;
|
||||
|
||||
ULONG pid = 0;
|
||||
unsigned int injectPid =0;
|
||||
|
||||
while ((param = getopt(argc, argv, "i:p:u:d:m:P:h")) != -1)
|
||||
while ((param = getopt(argc, argv, "i:p:u:d:m:P:I:h")) != -1)
|
||||
{
|
||||
switch (param)
|
||||
{
|
||||
@@ -916,6 +1091,9 @@ int main(int argc, char** argv)
|
||||
case 'P':
|
||||
port = std::atoi(optarg);
|
||||
break;
|
||||
case 'I':
|
||||
injectPid = std::atoi(optarg);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
break;
|
||||
@@ -925,6 +1103,24 @@ int main(int argc, char** argv)
|
||||
if (pid) {
|
||||
FindHandles(pid, (LPSTR)"_WeChat_App_Instance_Identity_Mutex_Name", TRUE, TRUE);
|
||||
}
|
||||
if (injectPid != 0 && cDllPath[0] != 0)
|
||||
{
|
||||
if(cDllPath[0] != '\0')
|
||||
{
|
||||
if (port == 0) {
|
||||
std::wstring wsPath = Utf8ToUnicode(cDllPath);
|
||||
int ret = InjectDllByPid(injectPid, (wchar_t*)wsPath.c_str());
|
||||
printf(" 注入结果:%i \n", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring wsPath = Utf8ToUnicode(cDllPath);
|
||||
int ret = InjectDllAndStartHttpByPid(injectPid, (wchar_t*)wsPath.c_str(), port);
|
||||
printf(" 注入结果:%i \n", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (cInjectprogram[0] != 0 && cDllPath[0] != 0)
|
||||
{
|
||||
|
||||
Submodule
+1
Submodule spdlog added at ad0e89cbfb
+42
-17
@@ -1,22 +1,16 @@
|
||||
#include "pch.h"
|
||||
#include "account_mgr.h"
|
||||
#include "easylogging++.h"
|
||||
|
||||
|
||||
#include "wechat_function.h"
|
||||
|
||||
using namespace std;
|
||||
namespace wxhelper {
|
||||
AccountMgr::AccountMgr(DWORD base):BaseMgr(base){
|
||||
|
||||
}
|
||||
AccountMgr::~AccountMgr(){
|
||||
|
||||
}
|
||||
AccountMgr::AccountMgr(DWORD base) : BaseMgr(base) {}
|
||||
AccountMgr::~AccountMgr() {}
|
||||
int AccountMgr::GetSelfInfo(SelfInfoInner &out) {
|
||||
DWORD accout_service_addr = base_addr_ + WX_ACCOUNT_SERVICE_OFFSET;
|
||||
DWORD get_app_save_addr = base_addr_ + WX_GET_APP_DATA_SAVE_PATH_OFFSET;
|
||||
DWORD get_current_data_path_addr = base_addr_ + WX_GET_CURRENT_DATA_PATH_OFFSET;
|
||||
DWORD get_current_data_path_addr =
|
||||
base_addr_ + WX_GET_CURRENT_DATA_PATH_OFFSET;
|
||||
DWORD service_addr = NULL;
|
||||
__asm {
|
||||
PUSHAD
|
||||
@@ -129,16 +123,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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,4 +210,35 @@ int AccountMgr::Logout() {
|
||||
return success;
|
||||
}
|
||||
|
||||
/// @brief 根据 502647092 提供的偏移 获取二维码url
|
||||
/// @return
|
||||
std::string AccountMgr::GetQRCodeUrl() {
|
||||
DWORD qr_code_login_addr = base_addr_ + WX_QR_CODE_LOGIN_MGR_OFFSET ;
|
||||
DWORD get_qr_code_img_addr = base_addr_ + WX_GET_QR_CODE_IMAGE_OFFSET ;
|
||||
|
||||
DWORD temp;
|
||||
__asm {
|
||||
PUSHAD
|
||||
PUSHFD
|
||||
CALL qr_code_login_addr
|
||||
MOV temp,EAX
|
||||
POPFD
|
||||
POPAD
|
||||
}
|
||||
std::string pre("https://weixin.qq.com/x/");
|
||||
DWORD ptr = temp + 0x8;
|
||||
DWORD len = *(DWORD*)(ptr+0x10);
|
||||
if (*(DWORD *)(ptr) == 0) {
|
||||
return std::string();
|
||||
} else {
|
||||
if( *(DWORD*) (temp+0x1c) > 0xf){
|
||||
std::string suff(*(char **)ptr,len);
|
||||
return pre + suff;
|
||||
}else{
|
||||
std::string suff((char *)ptr,len);
|
||||
return pre + suff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace wxhelper
|
||||
@@ -13,6 +13,8 @@ namespace wxhelper{
|
||||
int CheckLogin();
|
||||
|
||||
int Logout();
|
||||
|
||||
std::string GetQRCodeUrl();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -71,6 +71,9 @@ typedef enum HTTP_API_ROUTE {
|
||||
WECHAT_CONTACT_NAME,
|
||||
WECHAT_ATTACH_DOWNLOAD,
|
||||
WECHAT_GET_VOICE,
|
||||
WECHAT_GET_QRCODE,
|
||||
WECHAT_INVITE_MEMBERS,
|
||||
WECHAT_GET_MEMBER_PROFILE,
|
||||
} WECHAT_HTTP_APIS,
|
||||
*PWECHAT_HTTP_APIS;
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -372,4 +374,65 @@ std::wstring ChatRoomMgr::GetChatRoomMemberNickname(wchar_t* chat_room_id,
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
int ChatRoomMgr::InviteMemberToChatRoom(wchar_t* chat_room_id, wchar_t** wxids, int len) {
|
||||
int success = -1;
|
||||
WeChatString chat_room(chat_room_id);
|
||||
vector<WeChatString> members;
|
||||
VectorInner* list = (VectorInner*)&members;
|
||||
DWORD members_ptr = (DWORD)&list->start;
|
||||
for (int i = 0; i < len; i++) {
|
||||
WeChatString pwxid(wxids[i]);
|
||||
members.push_back(pwxid);
|
||||
}
|
||||
DWORD get_chat_room_mgr_addr = base_addr_ + WX_CHAT_ROOM_MGR_OFFSET;
|
||||
DWORD add_member_addr = base_addr_ + WX_ADD_MEMBER_TO_CHAT_ROOM_OFFSET;
|
||||
DWORD init_chat_msg_addr = base_addr_ + WX_INIT_CHAT_MSG_OFFSET;
|
||||
DWORD get_share_record_mgr_addr = base_addr_ + WX_SHARE_RECORD_MGR_OFFSET;
|
||||
|
||||
DWORD fn1 = base_addr_ + 0x7fa730;
|
||||
DWORD fn2 = base_addr_ + 0x78d9a0;
|
||||
DWORD fn3 = base_addr_ + 0x7fb6e0;
|
||||
DWORD fn4 = base_addr_ + 0x755af0;
|
||||
DWORD invite_addr = base_addr_ + 0xbd28a0;
|
||||
|
||||
DWORD sys_addr = (DWORD)GetModuleHandleA("win32u.dll") + 0x116C;
|
||||
DWORD addr[2] = {sys_addr,0};
|
||||
__asm {
|
||||
PUSHAD
|
||||
PUSHFD
|
||||
CALL get_share_record_mgr_addr
|
||||
LEA ECX,addr
|
||||
PUSH ECX
|
||||
MOV ECX,EAX
|
||||
CALL fn1
|
||||
CALL get_chat_room_mgr_addr
|
||||
SUB ESP,0x8
|
||||
LEA EAX,addr
|
||||
MOV ECX,ESP
|
||||
PUSH EAX
|
||||
CALL fn2
|
||||
SUB ESP,0x14
|
||||
MOV ECX,ESP
|
||||
LEA EAX,chat_room
|
||||
PUSH EAX
|
||||
CALL init_chat_msg_addr
|
||||
MOV EAX,dword ptr[members_ptr]
|
||||
PUSH EAX
|
||||
CALL invite_addr
|
||||
CALL get_share_record_mgr_addr
|
||||
PUSH 0x0
|
||||
PUSH 0x1
|
||||
MOV ECX,EAX
|
||||
CALL fn3
|
||||
LEA ECX,addr
|
||||
CALL fn4
|
||||
POPFD
|
||||
POPAD
|
||||
}
|
||||
success = 1;
|
||||
return success;
|
||||
|
||||
}
|
||||
|
||||
} // namespace wxhelper
|
||||
@@ -23,6 +23,8 @@ class ChatRoomMgr:public BaseMgr {
|
||||
|
||||
std::wstring GetChatRoomMemberNickname(wchar_t* chat_room_id,
|
||||
wchar_t* wxid);
|
||||
int InviteMemberToChatRoom(wchar_t* chat_room_id, wchar_t** wxids,
|
||||
int len);
|
||||
};
|
||||
} // namespace wxhelper
|
||||
#endif
|
||||
+13
-2
@@ -1,6 +1,17 @@
|
||||
#include "config.h"
|
||||
#include "pch.h"
|
||||
#include "config.h"
|
||||
|
||||
namespace wxhelper {
|
||||
Config::Config(/* args */) {}
|
||||
|
||||
Config::~Config() {}
|
||||
} // namespace wxhelper
|
||||
|
||||
|
||||
void Config::Initialize(){
|
||||
port_ = GetPrivateProfileInt("config", "Port", 19088, "./config.ini");
|
||||
}
|
||||
int Config::GetPort(){
|
||||
return port_;
|
||||
}
|
||||
|
||||
} // namespace wxhelper
|
||||
+13
-11
@@ -1,15 +1,17 @@
|
||||
#ifndef WXHELPER_CONFIG_H_
|
||||
#ifndef WXHELPER_CONFIG_H_
|
||||
#define WXHELPER_CONFIG_H_
|
||||
|
||||
namespace wxhelper{
|
||||
namespace wxhelper {
|
||||
|
||||
class Config
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
Config(/* args */);
|
||||
~Config();
|
||||
};
|
||||
}
|
||||
class Config {
|
||||
public:
|
||||
Config(/* args */);
|
||||
~Config();
|
||||
void Initialize();
|
||||
int GetPort();
|
||||
|
||||
private:
|
||||
int port_;
|
||||
};
|
||||
} // namespace wxhelper
|
||||
#endif
|
||||
+42
-3
@@ -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;
|
||||
@@ -175,7 +175,7 @@ int ContactMgr::AddFriendByWxid(wchar_t *wxid,wchar_t* msg) {
|
||||
return success;
|
||||
}
|
||||
|
||||
int ContactMgr::VerifyApply(wchar_t *v3, wchar_t *v4){
|
||||
int ContactMgr::VerifyApply(wchar_t *v3, wchar_t *v4,int permission){
|
||||
int success = -1;
|
||||
DWORD set_value_addr = base_addr_ + WX_INIT_CHAT_MSG_OFFSET;
|
||||
DWORD verify_addr = base_addr_ + WX_VERIFY_OK_OFFSET;
|
||||
@@ -186,12 +186,13 @@ int ContactMgr::AddFriendByWxid(wchar_t *wxid,wchar_t* msg) {
|
||||
WeChatString v3_str(v3);
|
||||
char helper_obj[0x40] = {0};
|
||||
char nullbuffer[0x3CC] = {0};
|
||||
int flag = permission < 0 ? 0:permission;
|
||||
__asm {
|
||||
PUSHAD
|
||||
PUSHFD
|
||||
LEA ECX,helper_obj
|
||||
CALL new_helper_addr
|
||||
MOV ESI,0x0
|
||||
MOV ESI,flag
|
||||
MOV EDI,0x6
|
||||
PUSH ESI
|
||||
PUSH EDI
|
||||
@@ -216,4 +217,42 @@ int ContactMgr::AddFriendByWxid(wchar_t *wxid,wchar_t* msg) {
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
int ContactMgr::GetContactByWxid(wchar_t *wxid,ContactProfile& profile){
|
||||
int success = -1;
|
||||
char buff[0x440] = {0};
|
||||
WeChatString pri(wxid);
|
||||
DWORD contact_mgr_addr = base_addr_ + WX_CONTACT_MGR_OFFSET;
|
||||
DWORD get_contact_addr = base_addr_ + WX_GET_CONTACT_OFFSET;
|
||||
DWORD free_contact_addr = base_addr_ + WX_FREE_CONTACT_OFFSET;
|
||||
__asm {
|
||||
PUSHAD
|
||||
PUSHFD
|
||||
CALL contact_mgr_addr
|
||||
LEA ECX,buff
|
||||
PUSH ECX
|
||||
LEA ECX,pri
|
||||
PUSH ECX
|
||||
MOV ECX,EAX
|
||||
CALL get_contact_addr
|
||||
POPFD
|
||||
POPAD
|
||||
}
|
||||
success = 0;
|
||||
profile.wxid = READ_WSTRING(buff, 0x10);
|
||||
profile.account = READ_WSTRING(buff, 0x24);
|
||||
profile.v3 = READ_WSTRING(buff, 0x38);
|
||||
profile.nickname = READ_WSTRING(buff, 0x6C);
|
||||
profile.head_image = READ_WSTRING(buff, 0x110);
|
||||
__asm {
|
||||
PUSHAD
|
||||
PUSHFD
|
||||
LEA ECX,buff
|
||||
CALL free_contact_addr
|
||||
POPFD
|
||||
POPAD
|
||||
}
|
||||
success = 1;
|
||||
return success;
|
||||
}
|
||||
} // namespace wxhelper
|
||||
+2
-1
@@ -14,7 +14,8 @@ class ContactMgr : public BaseMgr {
|
||||
int DelContact(wchar_t* wxid);
|
||||
std::wstring GetContactOrChatRoomNickname(wchar_t* id);
|
||||
int AddFriendByWxid(wchar_t* wxid,wchar_t* msg);
|
||||
int VerifyApply(wchar_t *v3, wchar_t *v4);
|
||||
int VerifyApply(wchar_t *v3, wchar_t *v4,int permission);
|
||||
int GetContactByWxid(wchar_t* wxid,ContactProfile& profile);
|
||||
};
|
||||
} // namespace wxhelper
|
||||
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
#include "db.h"
|
||||
|
||||
#include "base64.h"
|
||||
#include "easylogging++.h"
|
||||
|
||||
#include "wechat_function.h"
|
||||
#include "utils.h"
|
||||
using namespace std;
|
||||
|
||||
namespace wxhelper {
|
||||
@@ -117,8 +116,16 @@ int DB::Select(DWORD db_hanle, const char *sql,
|
||||
vector<string> item;
|
||||
for (size_t i = 0; i < it.size(); i++) {
|
||||
if (!it[i].is_blob) {
|
||||
string content(it[i].content);
|
||||
item.push_back(content);
|
||||
bool is_utf8 = Utils::IsTextUtf8(it[i].content, it[i].content_len);
|
||||
if (is_utf8) {
|
||||
string content(it[i].content);
|
||||
item.push_back(content);
|
||||
} else {
|
||||
string base64_str =
|
||||
base64_encode((BYTE *)it[i].content, it[i].content_len);
|
||||
item.push_back(base64_str);
|
||||
}
|
||||
|
||||
} else {
|
||||
string b64_str =
|
||||
base64_encode((BYTE *)it[i].content, it[i].content_len);
|
||||
@@ -453,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;
|
||||
@@ -483,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;
|
||||
@@ -508,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;
|
||||
@@ -527,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;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
-4576
File diff suppressed because it is too large
Load Diff
@@ -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 {
|
||||
@@ -11,14 +11,15 @@ void GlobalContext::initialize(HMODULE module) {
|
||||
module_ = module;
|
||||
DWORD base = Utils::GetWeChatWinBase();
|
||||
config.emplace();
|
||||
config->Initialize();
|
||||
log.emplace();
|
||||
log->initialize();
|
||||
log->Initialize();
|
||||
hide_module.emplace();
|
||||
#ifndef _DEBUG
|
||||
hide_module->Hide(module_);
|
||||
#endif
|
||||
|
||||
HttpServer::GetInstance().Init(19088);
|
||||
HttpServer::GetInstance().Init(config->GetPort());
|
||||
HttpServer::GetInstance().HttpStart();
|
||||
DB::GetInstance().init(base);
|
||||
contact_mgr.emplace(ContactMgr{base});
|
||||
@@ -27,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
@@ -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;
|
||||
|
||||
+60
-13
@@ -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"}};
|
||||
@@ -131,7 +130,6 @@ string Dispatch(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
break;
|
||||
}
|
||||
case WECHAT_MSG_SEND_AT: {
|
||||
break;
|
||||
wstring chat_room_id = GetWStringParam(j_param, "chatRoomId");
|
||||
vector<wstring> wxids = getArrayParam(j_param, "wxids");
|
||||
wstring msg = GetWStringParam(j_param, "msg");
|
||||
@@ -228,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;
|
||||
}
|
||||
@@ -253,7 +255,8 @@ string Dispatch(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
case WECHAT_CONTACT_VERIFY_APPLY: {
|
||||
wstring v3 = GetWStringParam(j_param, "v3");
|
||||
wstring v4 = GetWStringParam(j_param, "v4");
|
||||
int success = g_context.contact_mgr->VerifyApply(WS2LPWS(v3),WS2LPWS(v4));
|
||||
int permission = GetIntParam(j_param, "permission");
|
||||
int success = g_context.contact_mgr->VerifyApply(WS2LPWS(v3),WS2LPWS(v4),permission);
|
||||
json ret_data = {{"code", success}, {"result", "OK"}};
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
@@ -502,11 +505,11 @@ string Dispatch(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
break;
|
||||
}
|
||||
case WECHAT_DO_OCR: {
|
||||
// wstring image_path = GetWStringParam(j_param, "imagePath");
|
||||
// string text("");
|
||||
// int success = g_context.misc_mgr->DoOCRTask(WS2LPWS(image_path), text);
|
||||
// json ret_data = {{"code", success}, {"result", "OK"}, {"text", text}};
|
||||
// ret = ret_data.dump();
|
||||
wstring image_path = GetWStringParam(j_param, "imagePath");
|
||||
string text("");
|
||||
int success = g_context.misc_mgr->DoOCRTask(WS2LPWS(image_path), text);
|
||||
json ret_data = {{"code", success}, {"result", "OK"}, {"text", text}};
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
}
|
||||
case WECHAT_SEND_PAT_MSG: {
|
||||
@@ -569,7 +572,51 @@ string Dispatch(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
}
|
||||
case WECHAT_GET_QRCODE: {
|
||||
string url = g_context.account_mgr->GetQRCodeUrl();
|
||||
json ret_data = {{"code", 1}, {"result", "OK"},{"qrCodeUrl",url}};
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
}
|
||||
case WECHAT_INVITE_MEMBERS: {
|
||||
wstring room_id = GetWStringParam(j_param, "chatRoomId");
|
||||
vector<wstring> wxids = getArrayParam(j_param, "memberIds");
|
||||
vector<wchar_t *> wxid_list;
|
||||
for (unsigned int i = 0; i < wxids.size(); i++) {
|
||||
wxid_list.push_back(WS2LPWS(wxids[i]));
|
||||
}
|
||||
int success = g_context.chat_room_mgr->InviteMemberToChatRoom(
|
||||
WS2LPWS(room_id), wxid_list.data(), wxid_list.size());
|
||||
json ret_data = {{"code", success}, {"result", "OK"}};
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
}
|
||||
case WECHAT_GET_MEMBER_PROFILE: {
|
||||
wstring pri_id = GetWStringParam(j_param, "wxid");
|
||||
ContactProfile profile;
|
||||
int success =
|
||||
g_context.contact_mgr->GetContactByWxid(WS2LPWS(pri_id),profile);
|
||||
if(success==1){
|
||||
json ret_data = {
|
||||
{"code", success},
|
||||
{"result", "OK"},
|
||||
{"account", Utils::WstringToUTF8(profile.account)},
|
||||
{"headImage", Utils::WstringToUTF8(profile.head_image)},
|
||||
{"nickname", Utils::WstringToUTF8(profile.nickname)},
|
||||
{"v3", Utils::WstringToUTF8(profile.v3)},
|
||||
{"wxid", Utils::WstringToUTF8(profile.wxid)},
|
||||
};
|
||||
ret = ret_data.dump();
|
||||
} else {
|
||||
json ret_data = {{"result", "ok"}, {"code", success}};
|
||||
ret = ret_data.dump();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
json ret_data = {{"result", "ERROR"}, {"msg", "not support api"}};
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -589,7 +636,7 @@ void HttpHandler::HandlerRequest(struct mg_connection *c, void *ev_data) {
|
||||
ret = res.dump();
|
||||
}
|
||||
if (ret != "") {
|
||||
mg_http_reply(c, 200, "", ret.c_str(), 0, 0);
|
||||
mg_http_reply(c, 200, "Content-Type: application/json\r\n", "%s\n", ret.c_str());
|
||||
}
|
||||
} else {
|
||||
mg_http_reply(c, 500, NULL, "%s", "Invalid URI");
|
||||
|
||||
+12
-29
@@ -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);
|
||||
void Log::Initialize() {
|
||||
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
|
||||
@@ -8,7 +8,7 @@ namespace wxhelper{
|
||||
public:
|
||||
Log(/* args */);
|
||||
~Log();
|
||||
void initialize();
|
||||
void Initialize();
|
||||
};
|
||||
|
||||
|
||||
|
||||
+11
-29
@@ -5,7 +5,6 @@
|
||||
#include "base64.h"
|
||||
#include "db.h"
|
||||
#include "hooks.h"
|
||||
#include "easylogging++.h"
|
||||
#define BUFSIZE 1024
|
||||
|
||||
#define JPEG0 0xFF
|
||||
@@ -90,7 +89,7 @@ int MiscMgr::DoOCRTask(wchar_t *img_path, std::string &result) {
|
||||
for (unsigned int i = 0; i < num - 1; i++) {
|
||||
DWORD content = *(DWORD *)header;
|
||||
result += Utils::WstringToUTF8(READ_WSTRING(content, 0x14));
|
||||
|
||||
result += "\r\n";
|
||||
header = content;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
+86
-24
@@ -1,11 +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() {}
|
||||
@@ -14,13 +12,13 @@ int SendMessageMgr::SendText(wchar_t* wxid, wchar_t* msg) {
|
||||
WeChatString to_user(wxid);
|
||||
WeChatString text_msg(msg);
|
||||
wchar_t** msg_pptr = &text_msg.ptr;
|
||||
DWORD base = Utils::GetWeChatWinBase();
|
||||
DWORD send_message_mgr_addr = base + WX_SEND_MESSAGE_MGR_OFFSET;
|
||||
DWORD send_text_msg_addr = base + WX_SEND_TEXT_OFFSET;
|
||||
DWORD free_chat_msg_addr = base + WX_FREE_CHAT_MSG_OFFSET;
|
||||
DWORD send_message_mgr_addr = base_addr_ + WX_SEND_MESSAGE_MGR_OFFSET;
|
||||
DWORD send_text_msg_addr = base_addr_ + WX_SEND_TEXT_OFFSET;
|
||||
DWORD free_chat_msg_addr = base_addr_ + WX_FREE_CHAT_MSG_OFFSET;
|
||||
char chat_msg[0x2D8] = {0};
|
||||
__asm {
|
||||
PUSHAD
|
||||
PUSHFD
|
||||
CALL send_message_mgr_addr
|
||||
PUSH 0x0
|
||||
PUSH 0x0
|
||||
@@ -36,14 +34,79 @@ 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,
|
||||
wchar_t* msg) {
|
||||
int success = -1;
|
||||
WeChatString * at_users = new WeChatString[len+1];
|
||||
std::wstring at_msg = L"";
|
||||
int number =0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
std::wstring nickname;
|
||||
if (!lstrcmpiW((wchar_t *)wxids[i], (wchar_t *)L"notify@all")) {
|
||||
nickname = L"所有人";
|
||||
} else {
|
||||
ContactMgr contact{base_addr_};
|
||||
nickname = contact.GetContactOrChatRoomNickname(wxids[i]);
|
||||
}
|
||||
if (nickname.length() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
WeChatString temp = {0};
|
||||
temp.ptr = (wchar_t *)wxids[i];
|
||||
temp.length = wcslen((wchar_t *)wxids[i]);
|
||||
temp.max_length = wcslen((wchar_t *)wxids[i]) * 2;
|
||||
memcpy(&at_users[number], &temp, sizeof(WeChatString));
|
||||
at_msg = at_msg + L"@" + nickname + L" ";
|
||||
number++;
|
||||
}
|
||||
if (number < 1){
|
||||
return success;
|
||||
}
|
||||
std::wstring origin(msg);
|
||||
at_msg += origin;
|
||||
AtInner at_list = {0};
|
||||
at_list.start = (DWORD)at_users;
|
||||
at_list.finsh = (DWORD)&at_users[number];
|
||||
at_list.end = (DWORD)&at_users[number];
|
||||
WeChatString to_user(chat_room_id);
|
||||
WeChatString text_msg((wchar_t *)at_msg.c_str());
|
||||
wchar_t **msg_pptr = &text_msg.ptr;
|
||||
|
||||
DWORD send_message_mgr_addr = base_addr_ + WX_SEND_MESSAGE_MGR_OFFSET;
|
||||
DWORD send_text_msg_addr = base_addr_ + WX_SEND_TEXT_OFFSET;
|
||||
DWORD free_chat_msg_addr = base_addr_ + WX_FREE_CHAT_MSG_OFFSET;
|
||||
char chat_msg[0x2D8] = {0};
|
||||
__asm{
|
||||
PUSHAD
|
||||
PUSHFD
|
||||
CALL send_message_mgr_addr
|
||||
PUSH 0x0
|
||||
PUSH 0x0
|
||||
PUSH 0x0
|
||||
PUSH 0x1
|
||||
LEA EAX,at_list
|
||||
PUSH EAX
|
||||
MOV EAX,msg_pptr
|
||||
PUSH EAX
|
||||
LEA EDX,to_user
|
||||
LEA ECX,chat_msg
|
||||
CALL send_text_msg_addr
|
||||
MOV success,EAX
|
||||
ADD ESP,0x18
|
||||
LEA ECX,chat_msg
|
||||
CALL free_chat_msg_addr
|
||||
POPFD
|
||||
POPAD
|
||||
}
|
||||
SPDLOG_INFO("SendText code = {}",success);
|
||||
return success;
|
||||
}
|
||||
int SendMessageMgr::SendImage(wchar_t* wxid, wchar_t* image_path) {
|
||||
@@ -51,15 +114,15 @@ int SendMessageMgr::SendImage(wchar_t* wxid, wchar_t* image_path) {
|
||||
WeChatString to_user(wxid);
|
||||
WeChatString path(image_path);
|
||||
char chat_msg[0x2D8] = {0};
|
||||
DWORD base = Utils::GetWeChatWinBase();
|
||||
DWORD send_message_mgr_addr = base + WX_SEND_MESSAGE_MGR_OFFSET;
|
||||
DWORD init_chat_msg_addr = base + WX_INIT_CHAT_MSG_OFFSET;
|
||||
DWORD send_image_msg_addr = base + WX_SEND_IMAGE_OFFSET;
|
||||
DWORD free_msg_addr = base + WX_FREE_CHAT_MSG_OFFSET;
|
||||
DWORD send_message_mgr_addr = base_addr_ + WX_SEND_MESSAGE_MGR_OFFSET;
|
||||
DWORD init_chat_msg_addr = base_addr_ + WX_INIT_CHAT_MSG_OFFSET;
|
||||
DWORD send_image_msg_addr = base_addr_ + WX_SEND_IMAGE_OFFSET;
|
||||
DWORD free_msg_addr = base_addr_ + WX_FREE_CHAT_MSG_OFFSET;
|
||||
DWORD temp = 0;
|
||||
WeChatString null_obj = {0};
|
||||
__asm {
|
||||
PUSHAD
|
||||
PUSHFD
|
||||
CALL send_message_mgr_addr
|
||||
SUB ESP,0x14
|
||||
MOV temp,EAX
|
||||
@@ -78,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) {
|
||||
@@ -88,11 +152,10 @@ int SendMessageMgr::SendFile(wchar_t* wxid, wchar_t* file_path) {
|
||||
WeChatString to_user(wxid);
|
||||
WeChatString path(file_path);
|
||||
char chat_msg[0x2D8] = {0};
|
||||
DWORD base = Utils::GetWeChatWinBase();
|
||||
DWORD app_msg_mgr_addr = base + WX_APP_MSG_MGR_OFFSET;
|
||||
DWORD init_chat_msg_addr = base + WX_INIT_CHAT_MSG_OFFSET;
|
||||
DWORD send_file_addr = base + WX_SEND_FILE_OFFSET;
|
||||
DWORD free_msg_addr = base + WX_FREE_CHAT_MSG_OFFSET;
|
||||
DWORD app_msg_mgr_addr = base_addr_ + WX_APP_MSG_MGR_OFFSET;
|
||||
DWORD init_chat_msg_addr = base_addr_ + WX_INIT_CHAT_MSG_OFFSET;
|
||||
DWORD send_file_addr = base_addr_ + WX_SEND_FILE_OFFSET;
|
||||
DWORD free_msg_addr = base_addr_ + WX_FREE_CHAT_MSG_OFFSET;
|
||||
DWORD temp = 0;
|
||||
WeChatString null_obj = {0};
|
||||
__asm {
|
||||
@@ -135,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;
|
||||
}
|
||||
|
||||
@@ -150,9 +213,8 @@ int SendMessageMgr::ForwardMsg(wchar_t* wxid, unsigned long long msgid) {
|
||||
|
||||
if (localid == 0) return 0;
|
||||
WeChatString to_user(wxid);
|
||||
DWORD base = Utils::GetWeChatWinBase();
|
||||
DWORD forward_msg_addr = base + WX_FORWARD_MSG_OFFSET;
|
||||
DWORD init_chat_msg_addr = base + WX_INIT_CHAT_MSG_OFFSET;
|
||||
DWORD forward_msg_addr = base_addr_ + WX_FORWARD_MSG_OFFSET;
|
||||
DWORD init_chat_msg_addr = base_addr_ + WX_INIT_CHAT_MSG_OFFSET;
|
||||
__asm {
|
||||
PUSHAD
|
||||
PUSHFD
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
+44
-7
@@ -1,7 +1,6 @@
|
||||
#include "pch.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
namespace wxhelper {
|
||||
std::wstring Utils::UTF8ToWstring(const std::string &str) {
|
||||
@@ -19,7 +18,7 @@ std::wstring Utils::AnsiToWstring(const std::string &input, DWORD locale) {
|
||||
MultiByteToWideChar(CP_UTF8, 0, input.c_str(), -1, &temp[0], wchar_len);
|
||||
return std::wstring(&temp[0]);
|
||||
}
|
||||
|
||||
|
||||
return std::wstring();
|
||||
}
|
||||
|
||||
@@ -102,8 +101,6 @@ void Utils::Hex2Bytes(const std::string &hex, BYTE *bytes) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Utils::IsDigit(std::string str) {
|
||||
if (str.length() == 0) {
|
||||
return false;
|
||||
@@ -119,7 +116,8 @@ bool Utils::IsDigit(std::string str) {
|
||||
bool Utils::FindOrCreateDirectoryW(const wchar_t *path) {
|
||||
WIN32_FIND_DATAW fd;
|
||||
HANDLE hFind = ::FindFirstFileW(path, &fd);
|
||||
if (hFind != INVALID_HANDLE_VALUE && (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
if (hFind != INVALID_HANDLE_VALUE &&
|
||||
(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
FindClose(hFind);
|
||||
return true;
|
||||
}
|
||||
@@ -174,4 +172,43 @@ std::string Utils::WCharToUTF8(wchar_t *wstr) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
bool Utils::IsTextUtf8(const char *str,int length) {
|
||||
char endian = 1;
|
||||
bool littlen_endian = (*(char *)&endian == 1);
|
||||
|
||||
size_t i;
|
||||
int bytes_num;
|
||||
unsigned char chr;
|
||||
|
||||
i = 0;
|
||||
bytes_num = 0;
|
||||
while (i < length) {
|
||||
if (littlen_endian) {
|
||||
chr = *(str + i);
|
||||
} else { // Big Endian
|
||||
chr = (*(str + i) << 8) | *(str + i + 1);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (bytes_num == 0) {
|
||||
if ((chr & 0x80) != 0) {
|
||||
while ((chr & 0x80) != 0) {
|
||||
chr <<= 1;
|
||||
bytes_num++;
|
||||
}
|
||||
if ((bytes_num < 2) || (bytes_num > 6)) {
|
||||
return false;
|
||||
}
|
||||
bytes_num--;
|
||||
}
|
||||
} else {
|
||||
if ((chr & 0xC0) != 0x80) {
|
||||
return false;
|
||||
}
|
||||
bytes_num--;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return (bytes_num == 0);
|
||||
}
|
||||
} // namespace wxhelper
|
||||
@@ -47,6 +47,8 @@ class Utils {
|
||||
|
||||
static std::string WCharToUTF8(wchar_t *wstr);
|
||||
|
||||
static bool IsTextUtf8(const char * str,int length) ;
|
||||
|
||||
template <typename T1, typename T2>
|
||||
static std::vector<T1> split(T1 str, T2 letter) {
|
||||
std::vector<T1> arr;
|
||||
|
||||
+113
-96
@@ -4,97 +4,97 @@
|
||||
#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
|
||||
// shareRecordMgr
|
||||
#define WX_SHARE_RECORD_MGR_OFFSET 0x78d5f0
|
||||
|
||||
|
||||
// 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,45 +102,46 @@
|
||||
|
||||
|
||||
// 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_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
|
||||
#define WX_QR_CODE_LOGIN_MGR_OFFSET 0xaeab70
|
||||
#define WX_GET_QR_CODE_IMAGE_OFFSET 0xcdb560
|
||||
|
||||
//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 0x7a98f0
|
||||
#define WX_OCR_MANAGER_OFFSET 0x7ae470
|
||||
#define WX_DO_OCR_TASK_OFFSET 0x13230c0
|
||||
#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
|
||||
@@ -153,10 +154,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
|
||||
@@ -196,15 +197,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
|
||||
@@ -350,24 +351,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**);
|
||||
|
||||
@@ -578,12 +579,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;
|
||||
@@ -769,4 +778,12 @@ struct Unkown{
|
||||
DWORD field5= 0;
|
||||
DWORD field6= 0;
|
||||
};
|
||||
|
||||
struct ContactProfile{
|
||||
std::wstring wxid;
|
||||
std::wstring account;
|
||||
std::wstring v3;
|
||||
std::wstring nickname;
|
||||
std::wstring head_image;
|
||||
};
|
||||
#endif
|
||||
Reference in New Issue
Block a user