Merge pull request #158 from lzb112/3.9.11.17

大佬特供
This commit is contained in:
Changhua 2024-06-23 22:25:32 +08:00 committed by GitHub
commit 2129d2d2b2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 603 additions and 291 deletions

View File

@ -1,5 +1,5 @@
#include "Shlwapi.h" #include "Shlwapi.h"
#include "framework.h" #include "../sdk/framework.h"
#include <codecvt> #include <codecvt>
#include <locale> #include <locale>
#include <string.h> #include <string.h>

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <string> #include <string>
#include <minwindef.h>
#define WECHAREXE L"WeChat.exe" #define WECHAREXE L"WeChat.exe"
#define WECHATWINDLL L"WeChatWin.dll" #define WECHATWINDLL L"WeChatWin.dll"

Binary file not shown.

Binary file not shown.

View File

@ -29,26 +29,26 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -144,6 +144,7 @@
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@ -193,11 +194,21 @@ xcopy /y $(OutDir)$(TargetFileName) $(SolutionDir)..\clients\python\wcferry</Com
<ClInclude Include="sdk.h" /> <ClInclude Include="sdk.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\com\log.cpp" /> <ClCompile Include="..\com\log.cpp">
<ClCompile Include="..\com\util.cpp" /> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
<ClCompile Include="dllmain.cpp" /> </ClCompile>
<ClCompile Include="injector.cpp" /> <ClCompile Include="..\com\util.cpp">
<ClCompile Include="sdk.cpp" /> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="dllmain.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="injector.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="sdk.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="sdk.def" /> <None Include="sdk.def" />

View File

@ -4,7 +4,7 @@
#include <string> #include <string>
#include "injector.h" #include "injector.h"
#include "util.h" #include "../com/util.h"
using namespace std; using namespace std;

View File

@ -6,7 +6,7 @@
#include "injector.h" #include "injector.h"
#include "sdk.h" #include "sdk.h"
#include "util.h" #include "../com/util.h"
static BOOL injected = false; static BOOL injected = false;
static HANDLE wcProcess = NULL; static HANDLE wcProcess = NULL;

Binary file not shown.

View File

@ -31,26 +31,26 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -97,7 +97,6 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<VcpkgUseStatic>true</VcpkgUseStatic> <VcpkgUseStatic>true</VcpkgUseStatic>
<VcpkgConfiguration>Release</VcpkgConfiguration>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<VcpkgUseStatic>true</VcpkgUseStatic> <VcpkgUseStatic>true</VcpkgUseStatic>
@ -208,7 +207,7 @@ $(SolutionDir)rpc\tool\protoc --nanopb_out=. wcf.proto</Command>
<AdditionalIncludeDirectories>$(SolutionDir)com;$(SolutionDir)rpc;$(SolutionDir)rpc\nanopb;$(SolutionDir)rpc\proto;$(SolutionDir)smc;$(SolutionDir)spy;C:\Tools\vcpkg\installed\x64-windows-static\include</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)com;$(SolutionDir)rpc;$(SolutionDir)rpc\nanopb;$(SolutionDir)rpc\proto;$(SolutionDir)smc;$(SolutionDir)spy;C:\Tools\vcpkg\installed\x64-windows-static\include</AdditionalIncludeDirectories>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<OmitFramePointers>false</OmitFramePointers> <OmitFramePointers>false</OmitFramePointers>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeaderOutputFile /> <PrecompiledHeaderOutputFile />
<DisableSpecificWarnings>4251;4731;4819</DisableSpecificWarnings> <DisableSpecificWarnings>4251;4731;4819</DisableSpecificWarnings>
@ -226,7 +225,7 @@ $(SolutionDir)rpc\tool\protoc --nanopb_out=. wcf.proto</Command>
</Link> </Link>
<PreBuildEvent> <PreBuildEvent>
<Command>cd $(SolutionDir)rpc\proto <Command>cd $(SolutionDir)rpc\proto
$(SolutionDir)rpc\tool\protoc --nanopb_out=. wcf.proto</Command> F:\C++\vcpkg\installed\x64-windows-static\tools\protobuf\protoc.exe --nanopb_out=. wcf.proto</Command>
</PreBuildEvent> </PreBuildEvent>
<PreBuildEvent> <PreBuildEvent>
<Message>Generating PB files</Message> <Message>Generating PB files</Message>
@ -314,6 +313,7 @@ xcopy /y $(OutDir)$(TargetFileName) $(SolutionDir)..\clients\python\wcferry</Com
<ClInclude Include="spy_types.h" /> <ClInclude Include="spy_types.h" />
<ClInclude Include="sqlite3.h" /> <ClInclude Include="sqlite3.h" />
<ClInclude Include="user_info.h" /> <ClInclude Include="user_info.h" />
<ClInclude Include="wechat_function.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\com\log.cpp" /> <ClCompile Include="..\com\log.cpp" />

View File

@ -93,6 +93,9 @@
<ClInclude Include="..\com\util.h"> <ClInclude Include="..\com\util.h">
<Filter>头文件</Filter> <Filter>头文件</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="wechat_function.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="dllmain.cpp"> <ClCompile Include="dllmain.cpp">

View File

@ -4,11 +4,14 @@
#include <sstream> #include <sstream>
#include "spy.h" #include "spy.h"
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{ {
switch (ul_reason_for_call) { switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
//PortPath_t p;
//p.port = 1234;
////p.path = "";
//InitSpy(&p);
case DLL_THREAD_ATTACH: case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH: case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:

View File

@ -2,48 +2,48 @@
#include "exec_sql.h" #include "exec_sql.h"
#include "load_calls.h" #include "load_calls.h"
#include "log.h"
#include "sqlite3.h" #include "sqlite3.h"
#include "util.h" #include "util.h"
#define OFFSET_DB_INSTANCE 0x5A40598 #define OFFSET_DB_INSTANCE 0x2FFDDC8
#define OFFSET_DB_MICROMSG 0xb8 #define OFFSET_DB_MICROMSG 0x68
#define OFFSET_DB_CHAT_MSG 0x2c8 #define OFFSET_DB_CHAT_MSG 0x1C0
#define OFFSET_DB_MISC 0x5f0 #define OFFSET_DB_MISC 0x3D8
#define OFFSET_DB_EMOTION 0x15f0 #define OFFSET_DB_EMOTION 0x558
#define OFFSET_DB_MEDIA 0xF48 #define OFFSET_DB_MEDIA 0x9B8
#define OFFSET_DB_BIZCHAT_MSG 0x1A70 #define OFFSET_DB_BIZCHAT_MSG 0x1120
#define OFFSET_DB_FUNCTION_MSG 0x1b98 #define OFFSET_DB_FUNCTION_MSG 0x11B0
#define OFFSET_DB_NAME 0x28 #define OFFSET_DB_NAME 0x14
#define OFFSET_DB_MSG_MGR 0x5ABB5D8 #define OFFSET_DB_MSG_MGR 0x30403B8
extern UINT64 g_WeChatWinDllAddr; extern UINT64 g_WeChatWinDllAddr;
typedef map<string, QWORD> dbMap_t; typedef map<string, DWORD> dbMap_t;
static dbMap_t dbMap; static dbMap_t dbMap;
#if 0
static void GetDbHandle(QWORD base, QWORD offset) static void GetDbHandle(DWORD base, DWORD offset)
{ {
wchar_t *wsp = (wchar_t *)(*(QWORD *)(base + offset + OFFSET_DB_NAME)); wchar_t *wsp;
wsp = (wchar_t *)(*(DWORD *)(base + offset + OFFSET_DB_NAME));
string dbname = Wstring2String(wstring(wsp)); string dbname = Wstring2String(wstring(wsp));
dbMap[dbname] = GET_QWORD(base + offset); dbMap[dbname] = GET_DWORD(base + offset);
} }
static void GetMsgDbHandle(QWORD msgMgrAddr) static void GetMsgDbHandle(DWORD msgMgrAddr)
{ {
QWORD dbIndex = GET_QWORD(msgMgrAddr + 0x68); DWORD dbIndex = GET_DWORD(msgMgrAddr + 0x38);
QWORD pStart = GET_QWORD(msgMgrAddr + 0x50); DWORD pStart = GET_DWORD(msgMgrAddr + 0x2C);
for (uint32_t i = 0; i < dbIndex; i++) { for (uint32_t i = 0; i < dbIndex; i++) {
QWORD dbAddr = GET_QWORD(pStart + i * 0x08); DWORD dbAddr = GET_DWORD(pStart + i * 0x04);
if (dbAddr) { if (dbAddr) {
// MSGi.db // MSGi.db
string dbname = Wstring2String(GET_WSTRING(dbAddr)); string dbname = Wstring2String(GET_WSTRING(dbAddr));
dbMap[dbname] = GET_QWORD(dbAddr + 0x78); dbMap[dbname] = GET_DWORD(dbAddr + 0x60);
// MediaMsgi.db // MediaMsgi.db
QWORD mmdbAddr = GET_QWORD(dbAddr + 0x20); DWORD mmdbAddr = GET_DWORD(dbAddr + 0x14);
string mmdbname = Wstring2String(GET_WSTRING(mmdbAddr + 0x78)); string mmdbname = Wstring2String(GET_WSTRING(mmdbAddr + 0x4C));
dbMap[mmdbname] = GET_QWORD(mmdbAddr + 0x50); dbMap[mmdbname] = GET_DWORD(mmdbAddr + 0x38);
} }
} }
} }
@ -52,7 +52,7 @@ dbMap_t GetDbHandles()
{ {
dbMap.clear(); dbMap.clear();
QWORD dbInstanceAddr = GET_QWORD(g_WeChatWinDllAddr + OFFSET_DB_INSTANCE); DWORD dbInstanceAddr = GET_DWORD(g_WeChatWinDllAddr + OFFSET_DB_INSTANCE);
GetDbHandle(dbInstanceAddr, OFFSET_DB_MICROMSG); // MicroMsg.db GetDbHandle(dbInstanceAddr, OFFSET_DB_MICROMSG); // MicroMsg.db
GetDbHandle(dbInstanceAddr, OFFSET_DB_CHAT_MSG); // ChatMsg.db GetDbHandle(dbInstanceAddr, OFFSET_DB_CHAT_MSG); // ChatMsg.db
@ -61,7 +61,7 @@ dbMap_t GetDbHandles()
GetDbHandle(dbInstanceAddr, OFFSET_DB_MEDIA); // Media.db GetDbHandle(dbInstanceAddr, OFFSET_DB_MEDIA); // Media.db
GetDbHandle(dbInstanceAddr, OFFSET_DB_FUNCTION_MSG); // Function.db GetDbHandle(dbInstanceAddr, OFFSET_DB_FUNCTION_MSG); // Function.db
GetMsgDbHandle(GET_QWORD(g_WeChatWinDllAddr + OFFSET_DB_MSG_MGR)); // MSGi.db & MediaMsgi.db GetMsgDbHandle(GET_DWORD(g_WeChatWinDllAddr + OFFSET_DB_MSG_MGR)); // MSGi.db & MediaMsgi.db
return dbMap; return dbMap;
} }
@ -133,13 +133,7 @@ DbRows_t ExecDbQuery(const string db, const string sql)
dbMap = GetDbHandles(); dbMap = GetDbHandles();
} }
QWORD *stmt; DWORD *stmt;
QWORD handle = dbMap[db];
if (handle == 0) {
LOG_WARN("Empty handle, retrying...");
dbMap = GetDbHandles();
}
int rc = func_prepare(dbMap[db], sql.c_str(), -1, &stmt, 0); int rc = func_prepare(dbMap[db], sql.c_str(), -1, &stmt, 0);
if (rc != SQLITE_OK) { if (rc != SQLITE_OK) {
return rows; return rows;
@ -168,16 +162,16 @@ DbRows_t ExecDbQuery(const string db, const string sql)
int GetLocalIdandDbidx(uint64_t id, uint64_t *localId, uint32_t *dbIdx) int GetLocalIdandDbidx(uint64_t id, uint64_t *localId, uint32_t *dbIdx)
{ {
QWORD msgMgrAddr = GET_QWORD(g_WeChatWinDllAddr + OFFSET_DB_MSG_MGR); DWORD msgMgrAddr = GET_DWORD(g_WeChatWinDllAddr + OFFSET_DB_MSG_MGR);
int dbIndex = (int)GET_QWORD(msgMgrAddr + 0x68); // 总不能 int 还不够吧? DWORD dbIndex = GET_DWORD(msgMgrAddr + 0x38);
QWORD pStart = GET_QWORD(msgMgrAddr + 0x50); DWORD pStart = GET_DWORD(msgMgrAddr + 0x2C);
*dbIdx = 0; *dbIdx = 0;
for (int i = dbIndex - 1; i >= 0; i--) { // 从后往前遍历 for (int i = dbIndex - 1; i >= 0; i--) { // 从后往前遍历
QWORD dbAddr = GET_QWORD(pStart + i * 0x08); DWORD dbAddr = GET_DWORD(pStart + i * 0x04);
if (dbAddr) { if (dbAddr) {
string dbname = Wstring2String(GET_WSTRING(dbAddr)); string dbname = Wstring2String(GET_WSTRING(dbAddr));
dbMap[dbname] = GET_QWORD(dbAddr + 0x78); dbMap[dbname] = GET_DWORD(dbAddr + 0x60);
string sql = "SELECT localId FROM MSG WHERE MsgSvrID=" + to_string(id) + ";"; string sql = "SELECT localId FROM MSG WHERE MsgSvrID=" + to_string(id) + ";";
DbRows_t rows = ExecDbQuery(dbname, sql); DbRows_t rows = ExecDbQuery(dbname, sql);
if (rows.empty()) { if (rows.empty()) {
@ -193,7 +187,7 @@ int GetLocalIdandDbidx(uint64_t id, uint64_t *localId, uint32_t *dbIdx)
} }
*localId = strtoull((const char *)(field.content.data()), NULL, 10); *localId = strtoull((const char *)(field.content.data()), NULL, 10);
*dbIdx = (uint32_t)(GET_QWORD(GET_QWORD(dbAddr + 0x28) + 0x1E8) >> 32); *dbIdx = GET_DWORD(GET_DWORD(dbAddr + 0x18) + 0x144);
return 0; return 0;
} }
@ -204,10 +198,10 @@ int GetLocalIdandDbidx(uint64_t id, uint64_t *localId, uint32_t *dbIdx)
vector<uint8_t> GetAudioData(uint64_t id) vector<uint8_t> GetAudioData(uint64_t id)
{ {
QWORD msgMgrAddr = GET_QWORD(g_WeChatWinDllAddr + OFFSET_DB_MSG_MGR); DWORD msgMgrAddr = GET_DWORD(g_WeChatWinDllAddr + OFFSET_DB_MSG_MGR);
int dbIndex = (int)GET_QWORD(msgMgrAddr + 0x68); DWORD dbIndex = GET_DWORD(msgMgrAddr + 0x38);
string sql = "SELECT Buf FROM Media WHERE Reserved0=" + to_string(id) + ";"; string sql = "SELECT Buf from Media WHERE Reserved0=" + to_string(id) + ";";
for (int i = dbIndex - 1; i >= 0; i--) { for (int i = dbIndex - 1; i >= 0; i--) {
string dbname = "MediaMSG" + to_string(i) + ".db"; string dbname = "MediaMSG" + to_string(i) + ".db";
DbRows_t rows = ExecDbQuery(dbname, sql); DbRows_t rows = ExecDbQuery(dbname, sql);
@ -231,3 +225,4 @@ vector<uint8_t> GetAudioData(uint64_t id)
return vector<uint8_t>(); return vector<uint8_t>();
} }
#endif

View File

@ -10,6 +10,7 @@
#include "log.h" #include "log.h"
#include "spy_types.h" #include "spy_types.h"
#include "util.h" #include "util.h"
#include "wechat_function.h"
#define HEADER_PNG1 0x89 #define HEADER_PNG1 0x89
#define HEADER_PNG2 0x50 #define HEADER_PNG2 0x50
@ -25,8 +26,9 @@ extern bool gIsListeningPyq;
extern WxCalls_t g_WxCalls; extern WxCalls_t g_WxCalls;
extern UINT64 g_WeChatWinDllAddr; extern UINT64 g_WeChatWinDllAddr;
int IsLogin(void) { return (int)GET_UINT64(g_WeChatWinDllAddr + g_WxCalls.login); } int IsLogin(void) { return (int)GET_UINT64(g_WeChatWinDllAddr + offset::wcf_kLoginStatu); }
#if 0
static string get_key(uint8_t header1, uint8_t header2, uint8_t *key) static string get_key(uint8_t header1, uint8_t header2, uint8_t *key)
{ {
// PNG? // PNG?
@ -53,7 +55,6 @@ static string get_key(uint8_t header1, uint8_t header2, uint8_t *key)
string DecryptImage(string src, string dir) string DecryptImage(string src, string dir)
{ {
if (!fs::exists(src)) { if (!fs::exists(src)) {
LOG_ERROR("File not exists: {}", src);
return ""; return "";
} }
@ -114,7 +115,6 @@ string DecryptImage(string src, string dir)
return dst; return dst;
} }
#if 0
static int GetFirstPage() static int GetFirstPage()
{ {
int rv = -1; int rv = -1;
@ -323,7 +323,6 @@ int RevokeMsg(uint64_t id)
return status; return status;
} }
#endif
string GetAudio(uint64_t id, string dir) string GetAudio(uint64_t id, string dir)
{ {
@ -345,7 +344,6 @@ string GetAudio(uint64_t id, string dir)
return mp3path; return mp3path;
} }
#if 0
OcrResult_t GetOcrResult(string path) OcrResult_t GetOcrResult(string path)
{ {
OcrResult_t ret = { -1, "" }; OcrResult_t ret = { -1, "" };

View File

@ -6,42 +6,44 @@
#define SUPPORT_VERSION L"3.9.10.27" #define SUPPORT_VERSION L"3.9.10.27"
WxCalls_t wxCalls = { WxCalls_t wxCalls = {
0x5AB8A2C, // Login Status //0x5AB8A2C, // Login Status
{ 0x5AB7FB8, 0x5AB8098, 0x5AB7FD8, 0x5A7E190 }, // User Info: wxid, nickname, mobile, home //{ 0x5AB7FB8, 0x5AB8098, 0x5AB7FD8, 0x5A7E190 }, // User Info: wxid, nickname, mobile, home
{ 0x1C1E690, 0x238DDD0, 0x1C1FF10 }, // Send Text Message //{ 0x1C1E690, 0x238DDD0, 0x1C1FF10 }, // Send Text Message
/* Receive Message: ///* Receive Message:
Hook, call, msgId, type, isSelf, ts, roomId, content, wxid, sign, thumb, extra, msgXml */ // Hook, call, msgId, type, isSelf, ts, roomId, content, wxid, sign, thumb, extra, msgXml */
{ 0x00, 0x2205510, 0x30, 0x38, 0x3C, 0x44, 0x48, 0x88, 0x240, 0x260, 0x280, 0x2A0, 0x308 }, //{ 0x00, 0x2205510, 0x30, 0x38, 0x3C, 0x44, 0x48, 0x88, 0x240, 0x260, 0x280, 0x2A0, 0x308 },
{ 0x1C28800, 0x1C1FF10, 0x1C1E690, 0x2383560 }, // Send Image Message //{ 0x1C28800, 0x1C1FF10, 0x1C1E690, 0x2383560 }, // Send Image Message
{ 0x1C28800, 0x1C1FF10, 0x1C23630, 0x21969E0 }, // Send File Message //{ 0x1C28800, 0x1C1FF10, 0x1C23630, 0x21969E0 }, // Send File Message
{ 0xB8A70, 0x3ED5E0, 0x107F00, 0x3ED7B0, 0x2386FE4 }, // Send xml Message //{ 0xB8A70, 0x3ED5E0, 0x107F00, 0x3ED7B0, 0x2386FE4 }, // Send xml Message
{ 0x771980, 0x4777E0, 0x239E888 }, // Send Emotion Message //{ 0x771980, 0x4777E0, 0x239E888 }, // Send Emotion Message
/* Get Contacts: ///* Get Contacts:
call1, call2, wxId, Code, Remark,Name, Gender, Country, Province, City*/ // call1, call2, wxId, Code, Remark,Name, Gender, Country, Province, City*/
{ 0x75A4A0, 0xC089F0, 0x10, 0x24, 0x58, 0x6C, 0x0E, 0x00, 0x00, 0x00 }, //{ 0x75A4A0, 0xC089F0, 0x10, 0x24, 0x58, 0x6C, 0x0E, 0x00, 0x00, 0x00 },
/* Exec Sql: ///* Exec Sql:
Exec, base, start, end, slot, name*/ // Exec, base, start, end, slot, name*/
{ 0x141BDF0, 0x2366934, 0x1428, 0x142C, 0x3C, 0x50 }, //{ 0x141BDF0, 0x2366934, 0x1428, 0x142C, 0x3C, 0x50 },
{ 0xA17D50, 0xF59E40, 0xA18BD0, 0xA17E70 }, // Accept New Friend application //{ 0xA17D50, 0xF59E40, 0xA18BD0, 0xA17E70 }, // Accept New Friend application
{ 0x78CF20, 0xF59E40, 0xBD1DC0 }, // Add chatroom members //{ 0x78CF20, 0xF59E40, 0xBD1DC0 }, // Add chatroom members
{ 0x78CF20, 0xF59E40, 0xBD22A0 }, // Delete chatroom members //{ 0x78CF20, 0xF59E40, 0xBD22A0 }, // Delete chatroom members
{ 0x7B2E60, 0x15E2C20, 0x79C250 }, // Receive transfer //{ 0x7B2E60, 0x15E2C20, 0x79C250 }, // Receive transfer
/* Receive PYQ ///* Receive PYQ
hook, call, call1, call2, call3, start, end, ts, wxid, content, xml, step*/ // hook, call, call1, call2, call3, start, end, ts, wxid, content, xml, step*/
{ 0x14F9E15, 0x14FA0A0, 0xC39680, 0x14E2140, 0x14E21E0, 0x20, 0x24, 0x2C, 0x18, 0x3C, 0x384, 0xB48 }, //{ 0x14F9E15, 0x14FA0A0, 0xC39680, 0x14E2140, 0x14E21E0, 0x20, 0x24, 0x2C, 0x18, 0x3C, 0x384, 0xB48 },
/* call1, call2, call3, call4, call5, call6*/ ///* call1, call2, call3, call4, call5, call6*/
{ 0x76F010, 0x792700, 0xBC0370, 0x80F110, 0x82BB40, 0x756E30}, //{ 0x76F010, 0x792700, 0xBC0370, 0x80F110, 0x82BB40, 0x756E30},
/* call1, call2, call3, call4, call5*/ ///* call1, call2, call3, call4, call5*/
{0x76F010, 0x792700, 0xBC0370, 0xBB5F70, 0x756E30}, //{0x76F010, 0x792700, 0xBC0370, 0xBB5F70, 0x756E30},
{0x1C27D50, 0x1C27120, 0x1C23630, 0x21A09C0}, // Send Rich Text Message //{0x1C27D50, 0x1C27120, 0x1C23630, 0x21A09C0}, // Send Rich Text Message
{0x2D669B0}, // Send Pat Message ///* call1, call2, call3 */
/* call1, call2, call3, call4, call5, call6, call7, call8*/ //{0x931730, 0x1D58751, 0x1421940},
{0x78CB40, 0x7F99D0, 0x78CF20, 0x78CEF0, 0xF59E40, 0xBD1A00, 0x7FA980, 0x755060}, ///* call1, call2, call3, call4, call5, call6, call7, call8*/
/* call1, call2, call3 */ //{0x78CB40, 0x7F99D0, 0x78CF20, 0x78CEF0, 0xF59E40, 0xBD1A00, 0x7FA980, 0x755060},
{0x80A800, 0x80F270, 0x13DA3E0}, ///* call1, call2, call3 */
{0x238D350}, // Forward message //{0x80A800, 0x80F270, 0x13DA3E0},
/* call1, call2, url */ ///* call1, call2 */
{0xAE9DB0, 0xCDA6F0, 0x3040DE8} //{0xF59E40, 0xCE6730},
///* call1, call2, url */
//{0xAE9DB0, 0xCDA6F0, 0x3040DE8}
}; };
int LoadCalls(const wchar_t *version, WxCalls_t *calls) int LoadCalls(const wchar_t *version, WxCalls_t *calls)

View File

@ -11,6 +11,7 @@
#include "receive_msg.h" #include "receive_msg.h"
#include "user_info.h" #include "user_info.h"
#include "util.h" #include "util.h"
#include "wechat_function.h"
// Defined in rpc_server.cpp // Defined in rpc_server.cpp
extern bool gIsListening, gIsListeningPyq; extern bool gIsListening, gIsListeningPyq;
@ -71,22 +72,22 @@ static UINT64 DispatchMsg(UINT64 arg1, UINT64 arg2)
{ {
WxMsg_t wxMsg = { 0 }; WxMsg_t wxMsg = { 0 };
try { try {
wxMsg.id = GET_QWORD(arg2 + g_WxCalls.recvMsg.msgId); wxMsg.id = GET_QWORD(arg2 + offset::wcf_msgId);
wxMsg.type = GET_DWORD(arg2 + g_WxCalls.recvMsg.type); wxMsg.type = GET_DWORD(arg2 + offset::wcf_type);
wxMsg.is_self = GET_DWORD(arg2 + g_WxCalls.recvMsg.isSelf); wxMsg.is_self = GET_DWORD(arg2 + offset::wcf_isSelf);
wxMsg.ts = GET_DWORD(arg2 + g_WxCalls.recvMsg.ts); wxMsg.ts = GET_DWORD(arg2 + offset::wcf_ts);
wxMsg.content = GetStringByWstrAddr(arg2 + g_WxCalls.recvMsg.content); wxMsg.content = GetStringByWstrAddr(arg2 + offset::wcf_content);
wxMsg.sign = GetStringByWstrAddr(arg2 + g_WxCalls.recvMsg.sign); wxMsg.sign = GetStringByWstrAddr(arg2 + offset::wcf_sign);
wxMsg.xml = GetStringByWstrAddr(arg2 + g_WxCalls.recvMsg.msgXml); wxMsg.xml = GetStringByWstrAddr(arg2 + offset::wcf_msgXml);
string roomid = GetStringByWstrAddr(arg2 + g_WxCalls.recvMsg.roomId); string roomid = GetStringByWstrAddr(arg2 + offset::wcf_roomId);
if (roomid.find("@chatroom") != string::npos) { // 群 ID 的格式为 xxxxxxxxxxx@chatroom if (roomid.find("@chatroom") != string::npos) { // 群 ID 的格式为 xxxxxxxxxxx@chatroom
wxMsg.is_group = true; wxMsg.is_group = true;
wxMsg.roomid = roomid; wxMsg.roomid = roomid;
if (wxMsg.is_self) { if (wxMsg.is_self) {
wxMsg.sender = GetSelfWxid(); wxMsg.sender = GetSelfWxid();
} else { } else {
wxMsg.sender = GetStringByWstrAddr(arg2 + g_WxCalls.recvMsg.wxid); wxMsg.sender = GetStringByWstrAddr(arg2 + offset::wcf_wxid);
} }
} else { } else {
wxMsg.is_group = false; wxMsg.is_group = false;
@ -97,13 +98,13 @@ static UINT64 DispatchMsg(UINT64 arg1, UINT64 arg2)
} }
} }
wxMsg.thumb = GetStringByWstrAddr(arg2 + g_WxCalls.recvMsg.thumb); wxMsg.thumb = GetStringByWstrAddr(arg2 + offset::wcf_thumb);
if (!wxMsg.thumb.empty()) { if (!wxMsg.thumb.empty()) {
wxMsg.thumb = GetHomePath() + wxMsg.thumb; wxMsg.thumb = GetHomePath() + wxMsg.thumb;
replace(wxMsg.thumb.begin(), wxMsg.thumb.end(), '\\', '/'); replace(wxMsg.thumb.begin(), wxMsg.thumb.end(), '\\', '/');
} }
wxMsg.extra = GetStringByWstrAddr(arg2 + g_WxCalls.recvMsg.extra); wxMsg.extra = GetStringByWstrAddr(arg2 + offset::wcf_extra);
if (!wxMsg.extra.empty()) { if (!wxMsg.extra.empty()) {
wxMsg.extra = GetHomePath() + wxMsg.extra; wxMsg.extra = GetHomePath() + wxMsg.extra;
replace(wxMsg.extra.begin(), wxMsg.extra.end(), '\\', '/'); replace(wxMsg.extra.begin(), wxMsg.extra.end(), '\\', '/');
@ -130,7 +131,7 @@ void ListenMessage()
LOG_WARN("gIsListening || (g_WeChatWinDllAddr == 0)"); LOG_WARN("gIsListening || (g_WeChatWinDllAddr == 0)");
return; return;
} }
funcRecvMsg = (funcRecvMsg_t)(g_WeChatWinDllAddr + g_WxCalls.recvMsg.call); funcRecvMsg = (funcRecvMsg_t)(g_WeChatWinDllAddr + offset::wcf_HookCall);
status = MH_Initialize(); status = MH_Initialize();
if (status != MH_OK) { if (status != MH_OK) {
@ -215,22 +216,22 @@ void DispatchMsg(DWORD reg)
{ {
WxMsg_t wxMsg; WxMsg_t wxMsg;
try { try {
wxMsg.id = GET_QWORD(reg + g_WxCalls.recvMsg.msgId); wxMsg.id = GET_QWORD(reg + offset::wcf_msgId);
wxMsg.type = GET_DWORD(reg + g_WxCalls.recvMsg.type); wxMsg.type = GET_DWORD(reg + offset::wcf_type);
wxMsg.is_self = GET_DWORD(reg + g_WxCalls.recvMsg.isSelf); wxMsg.is_self = GET_DWORD(reg + offset::wcf_isSelf);
wxMsg.ts = GET_DWORD(reg + g_WxCalls.recvMsg.ts); wxMsg.ts = GET_DWORD(reg + offset::wcf_ts);
wxMsg.content = GetStringByWstrAddr(reg + g_WxCalls.recvMsg.content); wxMsg.content = GetStringByWstrAddr(reg + offset::wcf_content);
wxMsg.sign = GetStringByStrAddr(reg + g_WxCalls.recvMsg.sign); wxMsg.sign = GetStringByStrAddr(reg + offset::wcf_sign);
wxMsg.xml = GetStringByStrAddr(reg + g_WxCalls.recvMsg.msgXml); wxMsg.xml = GetStringByStrAddr(reg + offset::wcf_msgXml);
string roomid = GetStringByWstrAddr(reg + g_WxCalls.recvMsg.roomId); string roomid = GetStringByWstrAddr(reg + offset::wcf_roomId);
if (roomid.find("@chatroom") != string::npos) { // 群 ID 的格式为 xxxxxxxxxxx@chatroom if (roomid.find("@chatroom") != string::npos) { // 群 ID 的格式为 xxxxxxxxxxx@chatroom
wxMsg.is_group = true; wxMsg.is_group = true;
wxMsg.roomid = roomid; wxMsg.roomid = roomid;
if (wxMsg.is_self) { if (wxMsg.is_self) {
wxMsg.sender = GetSelfWxid(); wxMsg.sender = GetSelfWxid();
} else { } else {
wxMsg.sender = GetStringByStrAddr(reg + g_WxCalls.recvMsg.wxid); wxMsg.sender = GetStringByStrAddr(reg + offset::wcf_wxid);
} }
} else { } else {
wxMsg.is_group = false; wxMsg.is_group = false;
@ -241,13 +242,13 @@ void DispatchMsg(DWORD reg)
} }
} }
wxMsg.thumb = GetStringByStrAddr(reg + g_WxCalls.recvMsg.thumb); wxMsg.thumb = GetStringByStrAddr(reg + offset::wcf_thumb);
if (!wxMsg.thumb.empty()) { if (!wxMsg.thumb.empty()) {
wxMsg.thumb = GetHomePath() + wxMsg.thumb; wxMsg.thumb = GetHomePath() + wxMsg.thumb;
replace(wxMsg.thumb.begin(), wxMsg.thumb.end(), '\\', '/'); replace(wxMsg.thumb.begin(), wxMsg.thumb.end(), '\\', '/');
} }
wxMsg.extra = GetStringByStrAddr(reg + g_WxCalls.recvMsg.extra); wxMsg.extra = GetStringByStrAddr(reg + offset::wcf_extra);
if (!wxMsg.extra.empty()) { if (!wxMsg.extra.empty()) {
wxMsg.extra = GetHomePath() + wxMsg.extra; wxMsg.extra = GetHomePath() + wxMsg.extra;
replace(wxMsg.extra.begin(), wxMsg.extra.end(), '\\', '/'); replace(wxMsg.extra.begin(), wxMsg.extra.end(), '\\', '/');
@ -290,8 +291,8 @@ void ListenMessage()
return; return;
} }
recvMsgHookAddr = g_WeChatWinDllAddr + g_WxCalls.recvMsg.hook; recvMsgHookAddr = g_WeChatWinDllAddr + offset::wcf_hook;
recvMsgCallAddr = g_WeChatWinDllAddr + g_WxCalls.recvMsg.call; recvMsgCallAddr = g_WeChatWinDllAddr + offset::wcf_call;
recvMsgJumpBackAddr = recvMsgHookAddr + 5; recvMsgJumpBackAddr = recvMsgHookAddr + 5;
HookAddress(recvMsgHookAddr, RecieveMsgFunc, recvMsgBackupCode); HookAddress(recvMsgHookAddr, RecieveMsgFunc, recvMsgBackupCode);

View File

@ -149,7 +149,7 @@ bool func_get_contacts(uint8_t *out, size_t *len)
return true; return true;
} }
#endif
bool func_get_db_names(uint8_t *out, size_t *len) bool func_get_db_names(uint8_t *out, size_t *len)
{ {
Response rsp = Response_init_default; Response rsp = Response_init_default;
@ -214,7 +214,7 @@ bool func_get_audio_msg(uint64_t id, char *dir, uint8_t *out, size_t *len)
return true; return true;
} }
#endif
bool func_send_txt(TextMsg txt, uint8_t *out, size_t *len) bool func_send_txt(TextMsg txt, uint8_t *out, size_t *len)
{ {
Response rsp = Response_init_default; Response rsp = Response_init_default;
@ -383,6 +383,7 @@ bool func_send_rich_txt(RichText rt, uint8_t *out, size_t *len)
return true; return true;
} }
#if 0
bool func_send_pat_msg(char *roomid, char *wxid, uint8_t *out, size_t *len) bool func_send_pat_msg(char *roomid, char *wxid, uint8_t *out, size_t *len)
{ {
Response rsp = Response_init_default; Response rsp = Response_init_default;
@ -428,7 +429,7 @@ bool func_forward_msg(uint64_t id, char *receiver, uint8_t *out, size_t *len)
return true; return true;
} }
#endif
static void PushMessage() static void PushMessage()
{ {
static uint8_t buffer[G_BUF_SIZE] = { 0 }; static uint8_t buffer[G_BUF_SIZE] = { 0 };
@ -545,6 +546,7 @@ bool func_disable_recv_txt(uint8_t *out, size_t *len)
return true; return true;
} }
#if 0
bool func_exec_db_query(char *db, char *sql, uint8_t *out, size_t *len) bool func_exec_db_query(char *db, char *sql, uint8_t *out, size_t *len)
{ {
Response rsp = Response_init_default; Response rsp = Response_init_default;
@ -571,7 +573,6 @@ bool func_exec_db_query(char *db, char *sql, uint8_t *out, size_t *len)
return true; return true;
} }
#if 0
bool func_accept_friend(char *v3, char *v4, int32_t scene, uint8_t *out, size_t *len) bool func_accept_friend(char *v3, char *v4, int32_t scene, uint8_t *out, size_t *len)
{ {
Response rsp = Response_init_default; Response rsp = Response_init_default;
@ -716,7 +717,6 @@ bool func_refresh_qrcode(uint8_t *out, size_t *len)
return true; return true;
} }
#endif
bool func_decrypt_image(DecPath dec, uint8_t *out, size_t *len) bool func_decrypt_image(DecPath dec, uint8_t *out, size_t *len)
{ {
@ -743,7 +743,6 @@ bool func_decrypt_image(DecPath dec, uint8_t *out, size_t *len)
return true; return true;
} }
#if 0
bool func_exec_ocr(char *path, uint8_t *out, size_t *len) bool func_exec_ocr(char *path, uint8_t *out, size_t *len)
{ {
Response rsp = Response_init_default; Response rsp = Response_init_default;
@ -841,7 +840,6 @@ bool func_invite_room_members(char *roomid, char *wxids, uint8_t *out, size_t *l
return true; return true;
} }
#endif #endif
static bool dispatcher(uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len) static bool dispatcher(uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len)
{ {
bool ret = false; bool ret = false;
@ -877,7 +875,6 @@ static bool dispatcher(uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len
ret = func_get_contacts(out, out_len); ret = func_get_contacts(out, out_len);
break; break;
} }
#endif
case Functions_FUNC_GET_DB_NAMES: { case Functions_FUNC_GET_DB_NAMES: {
ret = func_get_db_names(out, out_len); ret = func_get_db_names(out, out_len);
break; break;
@ -890,6 +887,7 @@ static bool dispatcher(uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len
ret = func_get_audio_msg(req.msg.am.id, req.msg.am.dir, out, out_len); ret = func_get_audio_msg(req.msg.am.id, req.msg.am.dir, out, out_len);
break; break;
} }
#endif
case Functions_FUNC_SEND_TXT: { case Functions_FUNC_SEND_TXT: {
ret = func_send_txt(req.msg.txt, out, out_len); ret = func_send_txt(req.msg.txt, out, out_len);
break; break;
@ -906,6 +904,7 @@ static bool dispatcher(uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len
ret = func_send_rich_txt(req.msg.rt, out, out_len); ret = func_send_rich_txt(req.msg.rt, out, out_len);
break; break;
} }
#if 0
case Functions_FUNC_SEND_PAT_MSG: { case Functions_FUNC_SEND_PAT_MSG: {
ret = func_send_pat_msg(req.msg.pm.roomid, req.msg.pm.wxid, out, out_len); ret = func_send_pat_msg(req.msg.pm.roomid, req.msg.pm.wxid, out, out_len);
break; break;
@ -914,7 +913,6 @@ static bool dispatcher(uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len
ret = func_forward_msg(req.msg.fm.id, req.msg.fm.receiver, out, out_len); ret = func_forward_msg(req.msg.fm.id, req.msg.fm.receiver, out, out_len);
break; break;
} }
#if 0
case Functions_FUNC_SEND_XML: { case Functions_FUNC_SEND_XML: {
ret = func_send_xml(req.msg.xml, out, out_len); ret = func_send_xml(req.msg.xml, out, out_len);
break; break;
@ -932,11 +930,11 @@ static bool dispatcher(uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len
ret = func_disable_recv_txt(out, out_len); ret = func_disable_recv_txt(out, out_len);
break; break;
} }
#if 0
case Functions_FUNC_EXEC_DB_QUERY: { case Functions_FUNC_EXEC_DB_QUERY: {
ret = func_exec_db_query(req.msg.query.db, req.msg.query.sql, out, out_len); ret = func_exec_db_query(req.msg.query.db, req.msg.query.sql, out, out_len);
break; break;
} }
#if 0
case Functions_FUNC_ACCEPT_FRIEND: { case Functions_FUNC_ACCEPT_FRIEND: {
ret = func_accept_friend(req.msg.v.v3, req.msg.v.v4, req.msg.v.scene, out, out_len); ret = func_accept_friend(req.msg.v.v3, req.msg.v.v4, req.msg.v.scene, out, out_len);
break; break;
@ -965,12 +963,10 @@ static bool dispatcher(uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len
ret = func_refresh_qrcode(out, out_len); ret = func_refresh_qrcode(out, out_len);
break; break;
} }
#endif
case Functions_FUNC_DECRYPT_IMAGE: { case Functions_FUNC_DECRYPT_IMAGE: {
ret = func_decrypt_image(req.msg.dec, out, out_len); ret = func_decrypt_image(req.msg.dec, out, out_len);
break; break;
} }
#if 0
case Functions_FUNC_EXEC_OCR: { case Functions_FUNC_EXEC_OCR: {
ret = func_exec_ocr(req.msg.str, out, out_len); ret = func_exec_ocr(req.msg.str, out, out_len);
break; break;

View File

@ -7,6 +7,7 @@
#include "send_msg.h" #include "send_msg.h"
#include "spy_types.h" #include "spy_types.h"
#include "util.h" #include "util.h"
#include "wechat_function.h"
extern HANDLE g_hEvent; extern HANDLE g_hEvent;
extern WxCalls_t g_WxCalls; extern WxCalls_t g_WxCalls;
@ -23,8 +24,6 @@ typedef QWORD (*funcSendImageMsg_t)(QWORD, QWORD, QWORD, QWORD, QWORD);
typedef QWORD (*funcSendFileMsg_t)(QWORD, QWORD, QWORD, QWORD, QWORD, QWORD *, QWORD, QWORD *, QWORD, QWORD *, QWORD, typedef QWORD (*funcSendFileMsg_t)(QWORD, QWORD, QWORD, QWORD, QWORD, QWORD *, QWORD, QWORD *, QWORD, QWORD *, QWORD,
QWORD); QWORD);
typedef QWORD (*funcSendRichTextMsg_t)(QWORD, QWORD, QWORD); typedef QWORD (*funcSendRichTextMsg_t)(QWORD, QWORD, QWORD);
typedef QWORD (*funcSendPatMsg_t)(QWORD, QWORD);
typedef QWORD (*funcForwardMsg_t)(QWORD, QWORD, QWORD, QWORD);
void SendTextMessage(string wxid, string msg, string atWxids) void SendTextMessage(string wxid, string msg, string atWxids)
{ {
@ -53,9 +52,9 @@ void SendTextMessage(string wxid, string msg, string atWxids)
QWORD wxAters = (QWORD) & ((RawVector_t *)&vWxAtWxids)->start; QWORD wxAters = (QWORD) & ((RawVector_t *)&vWxAtWxids)->start;
char buffer[0x460] = { 0 }; char buffer[0x460] = { 0 };
funcSendMsgMgr_t funcSendMsgMgr = (funcSendMsgMgr_t)(g_WeChatWinDllAddr + g_WxCalls.sendText.call1); funcSendMsgMgr_t funcSendMsgMgr = (funcSendMsgMgr_t)(g_WeChatWinDllAddr + offset::kGetSendMessageMgr);
funcSendTextMsg_t funcSendTextMsg = (funcSendTextMsg_t)(g_WeChatWinDllAddr + g_WxCalls.sendText.call2); funcSendTextMsg_t funcSendTextMsg = (funcSendTextMsg_t)(g_WeChatWinDllAddr + offset::kSendTextMsg);
funcFree_t funcFree = (funcFree_t)(g_WeChatWinDllAddr + g_WxCalls.sendText.call3); funcFree_t funcFree = (funcFree_t)(g_WeChatWinDllAddr + offset::kFreeChatMsg);
funcSendMsgMgr(); funcSendMsgMgr();
success = funcSendTextMsg((QWORD)(&buffer), (QWORD)(&wxWxid), (QWORD)(&wxMsg), wxAters, 1, 1, 0, 0); success = funcSendTextMsg((QWORD)(&buffer), (QWORD)(&wxWxid), (QWORD)(&wxMsg), wxAters, 1, 1, 0, 0);
funcFree((QWORD)(&buffer)); funcFree((QWORD)(&buffer));
@ -69,10 +68,10 @@ void SendImageMessage(string wxid, string path)
WxString wxWxid(wsWxid); WxString wxWxid(wsWxid);
WxString wxPath(wsPath); WxString wxPath(wsPath);
funcNew_t funcNew = (funcNew_t)(g_WeChatWinDllAddr + g_WxCalls.sendImg.call1); funcNew_t funcNew = (funcNew_t)(g_WeChatWinDllAddr + offset::kNewChatMsgByDownloadMgr);
funcFree_t funcFree = (funcFree_t)(g_WeChatWinDllAddr + g_WxCalls.sendImg.call2); funcFree_t funcFree = (funcFree_t)(g_WeChatWinDllAddr + offset::kFreeChatMsg);
funcSendMsgMgr_t funcSendMsgMgr = (funcSendMsgMgr_t)(g_WeChatWinDllAddr + g_WxCalls.sendImg.call3); funcSendMsgMgr_t funcSendMsgMgr = (funcSendMsgMgr_t)(g_WeChatWinDllAddr + offset::kGetSendMessageMgr);
funcSendImageMsg_t funcSendImage = (funcSendImageMsg_t)(g_WeChatWinDllAddr + g_WxCalls.sendImg.call4); funcSendImageMsg_t funcSendImage = (funcSendImageMsg_t)(g_WeChatWinDllAddr + offset::kSendImageMsg);
char msg[0x460] = { 0 }; char msg[0x460] = { 0 };
char msgTmp[0x460] = { 0 }; char msgTmp[0x460] = { 0 };
@ -99,10 +98,10 @@ void SendFileMessage(string wxid, string path)
WxString wxWxid(wsWxid); WxString wxWxid(wsWxid);
WxString wxPath(wsPath); WxString wxPath(wsPath);
funcNew_t funcNew = (funcNew_t)(g_WeChatWinDllAddr + g_WxCalls.sendFile.call1); funcNew_t funcNew = (funcNew_t)(g_WeChatWinDllAddr + offset::kChatMsgInstanceCounter);
funcFree_t funcFree = (funcFree_t)(g_WeChatWinDllAddr + g_WxCalls.sendFile.call2); funcFree_t funcFree = (funcFree_t)(g_WeChatWinDllAddr + offset::kFreeChatMsg);
funcGetAppMsgMgr_t funcGetAppMsgMgr = (funcGetAppMsgMgr_t)(g_WeChatWinDllAddr + g_WxCalls.sendFile.call3); funcGetAppMsgMgr_t funcGetAppMsgMgr = (funcGetAppMsgMgr_t)(g_WeChatWinDllAddr + offset::kGetAppMsgMgr);
funcSendFileMsg_t funcSendFile = (funcSendFileMsg_t)(g_WeChatWinDllAddr + g_WxCalls.sendFile.call4); funcSendFileMsg_t funcSendFile = (funcSendFileMsg_t)(g_WeChatWinDllAddr + offset::kSendFileMsg);
char msg[0x460] = { 0 }; char msg[0x460] = { 0 };
QWORD tmp1[4] = { 0 }; QWORD tmp1[4] = { 0 };
@ -146,10 +145,10 @@ int SendRichTextMessage(RichText_t &rt)
wstring name = String2Wstring(rt.name); wstring name = String2Wstring(rt.name);
wstring digest = String2Wstring(rt.digest); wstring digest = String2Wstring(rt.digest);
funcNew_t funcNew = (funcNew_t)(g_WeChatWinDllAddr + g_WxCalls.rt.call1); funcNew_t funcNew = (funcNew_t)(g_WeChatWinDllAddr + offset::kNewRChatMsg);
funcFree_t funcFree = (funcFree_t)(g_WeChatWinDllAddr + g_WxCalls.rt.call2); funcFree_t funcFree = (funcFree_t)(g_WeChatWinDllAddr + offset::kFreeRChatMsg);
funcGetAppMsgMgr_t funcGetAppMsgMgr = (funcGetAppMsgMgr_t)(g_WeChatWinDllAddr + g_WxCalls.rt.call3); funcGetAppMsgMgr_t funcGetAppMsgMgr = (funcGetAppMsgMgr_t)(g_WeChatWinDllAddr + offset::kGetAppMsgMgr);
funcSendRichTextMsg_t funcForwordPublicMsg = (funcSendRichTextMsg_t)(g_WeChatWinDllAddr + g_WxCalls.rt.call4); funcSendRichTextMsg_t funcForwordPublicMsg = (funcSendRichTextMsg_t)(g_WeChatWinDllAddr + offset::kSendRichTextMsg);
char *buff = (char *)HeapAlloc(GetProcessHeap(), 0, SRTM_SIZE); char *buff = (char *)HeapAlloc(GetProcessHeap(), 0, SRTM_SIZE);
if (buff == NULL) { if (buff == NULL) {
@ -181,45 +180,6 @@ int SendRichTextMessage(RichText_t &rt)
return (int)status; return (int)status;
} }
int SendPatMessage(string roomid, string wxid)
{
QWORD status = -1;
wstring wsRoomid = String2Wstring(roomid);
wstring wsWxid = String2Wstring(wxid);
WxString wxRoomid(wsRoomid);
WxString wxWxid(wsWxid);
funcSendPatMsg_t funcSendPatMsg = (funcSendPatMsg_t)(g_WeChatWinDllAddr + g_WxCalls.pm.call1);
status = funcSendPatMsg((QWORD)(&wxRoomid), (QWORD)(&wxWxid));
return (int)status;
}
int ForwardMessage(QWORD msgid, string receiver)
{
int status = -1;
uint32_t dbIdx = 0;
QWORD localId = 0;
funcForwardMsg_t funcForwardMsg = (funcForwardMsg_t)(g_WeChatWinDllAddr + g_WxCalls.fm.call1);
if (GetLocalIdandDbidx(msgid, &localId, &dbIdx) != 0) {
LOG_ERROR("Failed to get localId, Please check id: {}", to_string(msgid));
return status;
}
wstring wsReceiver = String2Wstring(receiver);
WxString *pReceiver = NewWxString(wsReceiver);
LARGE_INTEGER l;
l.HighPart = dbIdx;
l.LowPart = (DWORD)localId;
status = (int)funcForwardMsg((QWORD)pReceiver, l.QuadPart, 0x4, 0x0);
return status;
}
#if 0 #if 0
void SendXmlMessage(string receiver, string xml, string path, int type) void SendXmlMessage(string receiver, string xml, string path, int type)
{ {
@ -344,4 +304,145 @@ void SendEmotionMessage(string wxid, string path)
popad; popad;
} }
} }
int SendRichTextMessage(RichText_t &rt)
{
int status = -1;
char buff[0x238] = { 0 };
DWORD rtCall3 = g_WeChatWinDllAddr + g_WxCalls.rt.call3;
DWORD rtCall2 = g_WeChatWinDllAddr + g_WxCalls.rt.call2;
DWORD rtCall1 = g_WeChatWinDllAddr + g_WxCalls.rt.call1;
DWORD rtCall5 = g_WeChatWinDllAddr + g_WxCalls.rt.call5;
DWORD rtCall4 = g_WeChatWinDllAddr + g_WxCalls.rt.call4;
__asm {
pushad;
pushfd;
lea ecx,buff;
call rtCall1;
popfd;
popad;
}
wstring receiver = String2Wstring(rt.receiver);
wstring title = String2Wstring(rt.title);
wstring url = String2Wstring(rt.url);
wstring thumburl = String2Wstring(rt.thumburl);
wstring account = String2Wstring(rt.account);
wstring name = String2Wstring(rt.name);
wstring digest = String2Wstring(rt.digest);
WxString wxReceiver(receiver);
WxString wxTitle(title);
WxString wxUrl(url);
WxString wxThumburl(thumburl);
WxString wxAccount(account);
WxString wxName(name);
WxString wxDigest(digest);
memcpy(&buff[0x4], &wxTitle, sizeof(wxTitle));
memcpy(&buff[0x2C], &wxUrl, sizeof(wxUrl));
memcpy(&buff[0x6C], &wxThumburl, sizeof(wxThumburl));
memcpy(&buff[0x94], &wxDigest, sizeof(wxDigest));
memcpy(&buff[0x1A0], &wxAccount, sizeof(wxAccount));
memcpy(&buff[0x1B4], &wxName, sizeof(wxName));
__asm {
pushad;
pushfd;
call rtCall2;
lea ecx, buff;
push ecx;
sub esp, 0x14;
mov edi, eax;
mov ecx, esp;
lea ebx, wxReceiver;
push ebx;
call rtCall3;
mov ecx, edi;
call rtCall4;
mov status, eax;
add ebx, 0x14;
lea ecx, buff;
push 0x0;
call rtCall5;
popfd;
popad;
}
return status;
}
int SendPatMessage(string roomid, string wxid)
{
int status = -1;
wstring wsRoomid = String2Wstring(roomid);
wstring wsWxid = String2Wstring(wxid);
WxString wxRoomid(wsRoomid);
WxString wxWxid(wsWxid);
DWORD pmCall1 = g_WeChatWinDllAddr + g_WxCalls.pm.call1;
DWORD pmCall2 = g_WeChatWinDllAddr + g_WxCalls.pm.call2;
DWORD pmCall3 = g_WeChatWinDllAddr + g_WxCalls.pm.call3;
__asm {
pushad;
call pmCall1;
push pmCall2;
push 0x0;
push eax;
lea ecx, wxRoomid;
lea edx, wxWxid;
call pmCall3;
add esp, 0xc;
movzx eax, al;
mov status, eax;
popad;
}
return status;
}
int ForwardMessage(QWORD msgid, string receiver)
{
int status = -1;
uint32_t dbIdx = 0;
QWORD localId = 0;
if (GetLocalIdandDbidx(msgid, &localId, &dbIdx) != 0) {
LOG_ERROR("Failed to get localId, Please check id: {}", to_string(msgid));
return status;
}
wstring wsReceiver = String2Wstring(receiver);
WxString wxReceiver(wsReceiver);
DWORD fmCall1 = g_WeChatWinDllAddr + g_WxCalls.fm.call1;
DWORD fmCall2 = g_WeChatWinDllAddr + g_WxCalls.fm.call2;
__asm {
pushad;
pushfd;
mov edx, dword ptr [dbIdx];
push edx;
mov eax, dword ptr [localId];
push eax;
sub esp, 0x14;
mov ecx, esp;
lea esi, wxReceiver;
push esi;
call fmCall1;
xor ecx, ecx;
call fmCall2;
movzx eax, al;
mov status, eax;
add esp, 0x1c;
popfd;
popad;
}
return status;
}
#endif #endif

View File

@ -6,7 +6,7 @@
#include "spy.h" #include "spy.h"
#include "util.h" #include "util.h"
WxCalls_t g_WxCalls = { 0 }; //WxCalls_t g_WxCalls = { 0 };
UINT64 g_WeChatWinDllAddr = 0; UINT64 g_WeChatWinDllAddr = 0;
void InitSpy(LPVOID args) void InitSpy(LPVOID args)
@ -27,11 +27,11 @@ void InitSpy(LPVOID args)
return; return;
} }
LOG_INFO("WeChat version: {}", Wstring2String(version).c_str()); LOG_INFO("WeChat version: {}", Wstring2String(version).c_str());
if (LoadCalls(version, &g_WxCalls) != 0) { // 加载微信版本对应的Call地址 //if (LoadCalls(version, &g_WxCalls) != 0) { // 加载微信版本对应的Call地址
LOG_ERROR("不支持当前版本"); // LOG_ERROR("不支持当前版本");
MessageBox(NULL, L"不支持当前版本", L"错误", 0); // MessageBox(NULL, L"不支持当前版本", L"错误", 0);
return; // return;
} //}
RpcStartServer(pp->port); RpcStartServer(pp->port);
} }

View File

@ -2,5 +2,5 @@
#include "framework.h" #include "framework.h"
void InitSpy(int port); void InitSpy(LPVOID port);
void CleanupSpy(); void CleanupSpy();

View File

@ -5,40 +5,54 @@
typedef uint64_t QWORD; typedef uint64_t QWORD;
typedef struct UserInfoCall { typedef struct UserInfoCall {
DWORD wxid; DWORD wxid = 0x5AB7FB8;
DWORD nickName; DWORD nickName = 0x5AB8098;
DWORD mobile; DWORD mobile = 0x5AB7FD8;
DWORD home; DWORD home = 0x5A7E190;
} UserInfoCall_t; } UserInfoCall_t;
typedef struct RecvMsg { typedef struct RecvMsg {
DWORD hook; // Hook地址 DWORD hook = 0x00; // Hook地址
DWORD call; // Call地址 DWORD call = 0x2205510; // Call地址
DWORD msgId; // 消息ID地址 DWORD msgId = 0x30; // 消息ID地址
DWORD type; // 消息类型地址 DWORD type = 0x38; // 消息类型地址
DWORD isSelf; // 是否自己发送标志地址 DWORD isSelf = 0x3C; // 是否自己发送标志地址
DWORD ts; // TimeStamp DWORD ts = 0x44; // TimeStamp
DWORD roomId; // 群聊时为群ID私聊时为微信ID DWORD roomId = 0x48; // 群聊时为群ID私聊时为微信ID
DWORD content; // 消息内容地址 DWORD content = 0x88; // 消息内容地址
DWORD wxid; // 私聊时为空群聊时为发送者微信ID DWORD wxid = 0x240; // 私聊时为空群聊时为发送者微信ID
DWORD sign; // Sign DWORD sign = 0x260; // Sign
DWORD thumb; // 缩略图 DWORD thumb = 0x280; // 缩略图
DWORD extra; // 附加数据 DWORD extra = 0x2A0; // 附加数据
DWORD msgXml; // 消息xml内容地址 DWORD msgXml = 0x308; // 消息xml内容地址
} RecvMsg_t; } RecvMsg_t;
typedef struct SendText { typedef struct SendText {
DWORD call1; DWORD call1 = 0x1C1E690;
DWORD call2; DWORD call2 = 0x238DDD0;
DWORD call3; DWORD call3 = 0x1C1FF10;
} SendText_t; };
typedef struct Sendfile { typedef struct Sendfile {
DWORD call1; DWORD call1 = 0x1C28800;
DWORD call2; DWORD call2 = 0x1C1FF10;
DWORD call3; DWORD call3 = 0x1C23630;
DWORD call4; DWORD call4 = 0x21969E0;
} Sendfile_t; };
typedef struct SendEmo {
DWORD call1 = 0x771980;
DWORD call2 = 0x4777E0;
DWORD call3 = 0x239E888;
};
typedef struct SendImage {
DWORD call1 = 0x1C28800;
DWORD call2 = 0x1C1FF10;
DWORD call3 = 0x1C1E690;
DWORD call4 = 0x2383560;
};
typedef struct Contact { typedef struct Contact {
DWORD base; DWORD base;
@ -69,11 +83,17 @@ typedef struct NewFriend {
DWORD call4; DWORD call4;
} NewFriend_t; } NewFriend_t;
typedef struct RoomMember { typedef struct AddRoomMember {
DWORD call1; DWORD call1;
DWORD call2; DWORD call2;
DWORD call3; DWORD call3;
} RoomMember_t; } ;
typedef struct DelRoomMember {
DWORD call1;
DWORD call2;
DWORD call3;
};
typedef struct Xml { typedef struct Xml {
DWORD call1; DWORD call1;
@ -130,6 +150,8 @@ typedef struct CallRichText {
typedef struct CallPatMsg { typedef struct CallPatMsg {
DWORD call1; DWORD call1;
DWORD call2;
DWORD call3;
} CallPatMsg_t; } CallPatMsg_t;
typedef struct CallInviteCM { typedef struct CallInviteCM {
@ -151,6 +173,7 @@ typedef struct CallOcr {
typedef struct CallFm { typedef struct CallFm {
DWORD call1; DWORD call1;
DWORD call2;
} CallFm_t; } CallFm_t;
typedef struct CallRfLoginQr { typedef struct CallRfLoginQr {
@ -160,29 +183,29 @@ typedef struct CallRfLoginQr {
} CallRfLoginQr_t; } CallRfLoginQr_t;
typedef struct WxCalls { typedef struct WxCalls {
DWORD login; // 登录状态 //DWORD login = 0x5AB8A2C; // 登录状态
UserInfoCall_t ui; // 用户信息 //UserInfoCall_t ui; // 用户信息
SendText_t sendText; // 发送消息 //SendText sendText; // 发送消息
RecvMsg_t recvMsg; // 接收消息 //RecvMsg_t recvMsg; // 接收消息
Sendfile_t sendImg; // 发送图片 //SendImage sendImg; // 发送图片
Sendfile_t sendFile; // 发送文件 //Sendfile sendFile; // 发送文件
Xml_t sendXml; // 发送XML //Xml_t sendXml; // 发送XML
Sendfile_t sendEmo; // 发送表情 //SendEmo sendEmo; // 发送表情
Contact_t contact; // 获取联系人 //Contact_t contact; // 获取联系人
Sql_t sql; // 执行 SQL //Sql_t sql; // 执行 SQL
NewFriend_t anf; // 通过好友申请 //NewFriend_t anf; // 通过好友申请
RoomMember_t arm; // 添加群成员 //AddRoomMember arm; // 添加群成员
RoomMember_t drm; // 删除群成员 //DelRoomMember drm; // 删除群成员
TF_t tf; // 接收转账 //TF_t tf; // 接收转账
Pyq_t pyq; // 接收朋友圈消息 //Pyq_t pyq; // 接收朋友圈消息
DlAttach_t da; // 下载资源(图片、文件、视频) //DlAttach_t da; // 下载资源(图片、文件、视频)
RevokeMsg_t rm; // 撤回消息 //RevokeMsg_t rm; // 撤回消息
CallRichText_t rt; // 发送消息卡片 //CallRichText_t rt; // 发送消息卡片
CallPatMsg_t pm; // 发送拍一拍消息 //CallPatMsg_t pm; // 发送拍一拍消息
CallInviteCM_t irm; // 邀请群成员 //CallInviteCM_t irm; // 邀请群成员
CallOcr_t ocr; // OCR //CallOcr_t ocr; // OCR
CallFm_t fm; // 转发消息 //CallFm_t fm; // 转发消息
CallRfLoginQr_t rlq; // 刷新登录二维码 //CallRfLoginQr_t rlq; // 刷新登录二维码
} WxCalls_t; } WxCalls_t;
struct WxString { struct WxString {

View File

@ -136,9 +136,9 @@
#define SQLITE_NULL 5 #define SQLITE_NULL 5
#define SQLITE_TEXT 3 #define SQLITE_TEXT 3
#define SQLITE3_EXEC_OFFSET 0x3AFBCE0 #define SQLITE3_EXEC_OFFSET 0x1E24F70
#define SQLITE3_BACKUP_INIT_OFFSET 0x1DEA900 #define SQLITE3_BACKUP_INIT_OFFSET 0x1DEA900
#define SQLITE3_PREPARE_OFFSET 0x3B03990 #define SQLITE3_PREPARE_OFFSET 0x1E2B8C0
#define SQLITE3_OPEN_OFFSET 0x1E598B0 #define SQLITE3_OPEN_OFFSET 0x1E598B0
#define SQLITE3_BACKUP_STEP_OFFSET 0x1DEAD00 #define SQLITE3_BACKUP_STEP_OFFSET 0x1DEAD00
#define SQLITE3_BACKUP_REMAINING_OFFSET 0x1DEB440 #define SQLITE3_BACKUP_REMAINING_OFFSET 0x1DEB440
@ -147,46 +147,46 @@
#define SQLITE3_SLEEP_OFFSET 0x1E5A0F0 #define SQLITE3_SLEEP_OFFSET 0x1E5A0F0
#define SQLITE3_ERRCODE_OFFSET 0x1E58550 #define SQLITE3_ERRCODE_OFFSET 0x1E58550
#define SQLITE3_CLOSE_OFFSET 0x1E56CD0 #define SQLITE3_CLOSE_OFFSET 0x1E56CD0
#define SQLITE3_STEP_OFFSET 0x3ABFCE0 #define SQLITE3_STEP_OFFSET 0x1DF3770
#define SQLITE3_COLUMN_COUNT_OFFSET 0x3AC0500 #define SQLITE3_COLUMN_COUNT_OFFSET 0x1DF3C80
#define SQLITE3_COLUMN_NAME_OFFSET 0x3AC0F00 #define SQLITE3_COLUMN_NAME_OFFSET 0x1DF4570
#define SQLITE3_COLUMN_TYPE_OFFSET 0x3AC0D50 #define SQLITE3_COLUMN_TYPE_OFFSET 0x1DF4410
#define SQLITE3_COLUMN_BLOB_OFFSET 0x3AC0530 #define SQLITE3_COLUMN_BLOB_OFFSET 0x1DF3CC0
#define SQLITE3_COLUMN_BYTES_OFFSET 0x3AC0620 #define SQLITE3_COLUMN_BYTES_OFFSET 0x1DF3DA0
#define SQLITE3_FINALIZE_OFFSET 0x3ABED90 #define SQLITE3_FINALIZE_OFFSET 0x1DF2740
typedef int (*Sqlite3_callback)(void *, int, char **, char **); typedef int (*Sqlite3_callback)(void *, int, char **, char **);
typedef int(__cdecl *Sqlite3_exec)(QWORD, /* An open database */ typedef int(__cdecl *Sqlite3_exec)(DWORD, /* An open database */
const char *sql, /* SQL to be evaluated */ const char *sql, /* SQL to be evaluated */
Sqlite3_callback, /* Callback function */ Sqlite3_callback, /* Callback function */
void *, /* 1st argument to callback */ void *, /* 1st argument to callback */
char **errmsg /* Error msg written here */ char **errmsg /* Error msg written here */
); );
typedef QWORD(__cdecl *Sqlite3_backup_init)(QWORD *pDest, /* Destination database handle */ typedef DWORD(__cdecl *Sqlite3_backup_init)(DWORD *pDest, /* Destination database handle */
const char *zDestName, /* Destination database name */ const char *zDestName, /* Destination database name */
QWORD *pSource, /* Source database handle */ DWORD *pSource, /* Source database handle */
const char *zSourceName /* Source database name */ const char *zSourceName /* Source database name */
); );
typedef int(__cdecl *Sqlite3_prepare)(QWORD db, /* Database handle */ typedef int(__cdecl *Sqlite3_prepare)(DWORD db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */ const char *zSql, /* SQL statement, UTF-8 encoded */
int nByte, /* Maximum length of zSql in bytes. */ int nByte, /* Maximum length of zSql in bytes. */
QWORD **ppStmt, /* OUT: Statement handle */ DWORD **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */ const char **pzTail /* OUT: Pointer to unused portion of zSql */
); );
typedef int(__cdecl *Sqlite3_open)(const char *filename, QWORD **ppDb); typedef int(__cdecl *Sqlite3_open)(const char *filename, DWORD **ppDb);
typedef int(__cdecl *Sqlite3_backup_step)(QWORD *p, int nPage); typedef int(__cdecl *Sqlite3_backup_step)(DWORD *p, int nPage);
typedef int(__cdecl *Sqlite3_backup_remaining)(QWORD *p); typedef int(__cdecl *Sqlite3_backup_remaining)(DWORD *p);
typedef int(__cdecl *Sqlite3_backup_pagecount)(QWORD *p); typedef int(__cdecl *Sqlite3_backup_pagecount)(DWORD *p);
typedef int(__cdecl *Sqlite3_backup_finish)(QWORD *p); typedef int(__cdecl *Sqlite3_backup_finish)(DWORD *p);
typedef int(__cdecl *Sqlite3_sleep)(int); typedef int(__cdecl *Sqlite3_sleep)(int);
typedef int(__cdecl *Sqlite3_errcode)(QWORD *db); typedef int(__cdecl *Sqlite3_errcode)(DWORD *db);
typedef int(__cdecl *Sqlite3_close)(QWORD *); typedef int(__cdecl *Sqlite3_close)(DWORD *);
typedef int(__cdecl *Sqlite3_step)(QWORD *); typedef int(__cdecl *Sqlite3_step)(DWORD *);
typedef int(__cdecl *Sqlite3_column_count)(QWORD *pStmt); typedef int(__cdecl *Sqlite3_column_count)(DWORD *pStmt);
typedef const char *(__cdecl *Sqlite3_column_name)(QWORD *, int N); typedef const char *(__cdecl *Sqlite3_column_name)(DWORD *, int N);
typedef int(__cdecl *Sqlite3_column_type)(QWORD *, int iCol); typedef int(__cdecl *Sqlite3_column_type)(DWORD *, int iCol);
typedef const void *(__cdecl *Sqlite3_column_blob)(QWORD *, int iCol); typedef const void *(__cdecl *Sqlite3_column_blob)(DWORD *, int iCol);
typedef int(__cdecl *Sqlite3_column_bytes)(QWORD *, int iCol); typedef int(__cdecl *Sqlite3_column_bytes)(DWORD *, int iCol);
typedef int(__cdecl *Sqlite3_finalize)(QWORD *pStmt); typedef int(__cdecl *Sqlite3_finalize)(DWORD *pStmt);

View File

@ -2,6 +2,7 @@
#include "load_calls.h" #include "load_calls.h"
#include "log.h" #include "log.h"
#include "util.h" #include "util.h"
#include "wechat_function.h"
extern WxCalls_t g_WxCalls; extern WxCalls_t g_WxCalls;
extern UINT64 g_WeChatWinDllAddr; extern UINT64 g_WeChatWinDllAddr;
@ -11,7 +12,7 @@ static char home[MAX_PATH] = { 0 };
string GetHomePath() string GetHomePath()
{ {
if (home[0] == 0) { if (home[0] == 0) {
string path = Wstring2String(GET_WSTRING(g_WeChatWinDllAddr + g_WxCalls.ui.home)) + "\\WeChat Files\\"; string path = Wstring2String(GET_WSTRING(g_WeChatWinDllAddr + offset::wcf_home)) + "\\WeChat Files\\";
strncpy_s(home, path.c_str(), path.size()); strncpy_s(home, path.c_str(), path.size());
} }
@ -22,15 +23,15 @@ string GetSelfWxid()
{ {
UINT64 wxidType = 0; UINT64 wxidType = 0;
try { try {
wxidType = GET_UINT64(g_WeChatWinDllAddr + g_WxCalls.ui.wxid + 0x18); wxidType = GET_UINT64(g_WeChatWinDllAddr + offset::wcf_iwxid + 0x18);
if (wxidType == 0xF) { if (wxidType == 0xF) {
return GET_STRING_FROM_P(g_WeChatWinDllAddr + g_WxCalls.ui.wxid); return GET_STRING_FROM_P(g_WeChatWinDllAddr + offset::wcf_iwxid);
} else { } else {
return GET_STRING(g_WeChatWinDllAddr + g_WxCalls.ui.wxid); return GET_STRING(g_WeChatWinDllAddr + offset::wcf_iwxid);
} }
} catch (...) { } catch (...) {
LOG_ERROR("wxid type: {:#x}", wxidType); LOG_ERROR("wxid type: {:#x}", wxidType);
LOG_BUFFER((uint8_t *)(g_WeChatWinDllAddr + g_WxCalls.ui.wxid), 20); LOG_BUFFER((uint8_t *)(g_WeChatWinDllAddr + offset::wcf_iwxid), 20);
return "empty_wxid"; return "empty_wxid";
} }
} }
@ -41,14 +42,14 @@ UserInfo_t GetUserInfo()
ui.wxid = GetSelfWxid(); ui.wxid = GetSelfWxid();
UINT64 nameType = GET_UINT64(g_WeChatWinDllAddr + g_WxCalls.ui.nickName + 0x18); UINT64 nameType = GET_UINT64(g_WeChatWinDllAddr + offset::wcf_nickName + 0x18);
if (nameType == 0xF) { if (nameType == 0xF) {
ui.name = GET_STRING_FROM_P(g_WeChatWinDllAddr + g_WxCalls.ui.nickName); ui.name = GET_STRING_FROM_P(g_WeChatWinDllAddr + offset::wcf_nickName);
} else { // 0x1F } else { // 0x1F
ui.name = GET_STRING(g_WeChatWinDllAddr + g_WxCalls.ui.nickName); ui.name = GET_STRING(g_WeChatWinDllAddr + offset::wcf_nickName);
} }
ui.mobile = GET_STRING_FROM_P(g_WeChatWinDllAddr + g_WxCalls.ui.mobile); ui.mobile = GET_STRING_FROM_P(g_WeChatWinDllAddr + offset::wcf_mobile);
ui.home = GetHomePath(); ui.home = GetHomePath();
return ui; return ui;

View File

@ -0,0 +1,177 @@
#include <string>
#include <vector>
#include <windows.h>
namespace offset {
const UINT64 kGetAccountServiceMgr = 0x1B50D00; //ok
const UINT64 kGetCurrentDataPath = 0x2248D40; //ok
const UINT64 kGetAppDataSavePath = 0x25DBFE0; //ok
const UINT64 kGetSendMessageMgr = 0x1B4F500; //OK
const UINT64 kNewChatMsgByDownloadMgr = 0x1B59670; //ok
const UINT64 kSendTextMsg = 0x22C2070; //OK
const UINT64 kFreeChatMsg = 0x1B50D80; //OK
const UINT64 kDoAddMsg = 0x230A490; //ok
const UINT64 kSendImageMsg = 0x22B7800; //ok
const UINT64 kChatMsgInstanceCounter = kNewChatMsgByDownloadMgr; //ok
const UINT64 kSendFileMsg = 0x20CB750;//ok
const UINT64 kGetAppMsgMgr = 0x1B544A0; //ok
const UINT64 kGetContactMgr = 0x1B3CCD0;//ok
const UINT64 kGetContactList = 0x219A220;//ok
const UINT64 k_sqlite3_exec = 0x3A59B40;//ok
const UINT64 k_sqlite3_prepare = 0x3A617F0;//ok
//const UINT64 k_sqlite3_open = 0x27242a0; //1
const UINT64 k_sqlite3_step = 0x3A1DB40;//ok
const UINT64 k_sqlite3_column_count = 0x3A1E360;//ok
const UINT64 k_sqlite3_column_name = 0x3A1ED60;//ok
const UINT64 k_sqlite3_column_type = 0x3A1EBB0;//ok
const UINT64 k_sqlite3_column_blob = 0x3A1E390;//ok
const UINT64 k_sqlite3_column_bytes = 0x3A1E480;//ok
const UINT64 k_sqlite3_finalize = 0x3A1CBF0; //ok
const UINT64 kGPInstance = 0x58DD340; //ok
const UINT64 kMicroMsgDB = 0xb8; //ok
const UINT64 kChatMsgDB = 0x2c8; //ok
const UINT64 kMiscDB = 0x5f0; //ok
const UINT64 kEmotionDB = 0x15f0; //ok
const UINT64 kMediaDB = 0xF48; //ok
const UINT64 kBizchatMsgDB = 0x1AC0;//ok
const UINT64 kFunctionMsgDB = 0x1b98;//ok
const UINT64 kDBName = 0x28;
const UINT64 kStorageStart = 0x0;
const UINT64 kStorageEnd = 0x0;
const UINT64 kMultiDBMgr = 0x593AC38; //ok
const UINT64 kPublicMsgMgr = 0x59381D8; //ok
const UINT64 kFavoriteStorageMgr = 0x593B7D0; //ok
const UINT64 kChatRoomMgr = 0x1B7EEC0; //ok
const UINT64 kGetChatRoomDetailInfo = 0x2160C10; //ok
const UINT64 kNewChatRoomInfo = 0x25051D0;//ok
const UINT64 kFreeChatRoomInfo = 0x25053B0;//ok
//const UINT64 kDoAddMemberToChatRoom = 0xe63c70;
//const UINT64 kDoModChatRoomMemberNickName = 0xe6db00;
//const UINT64 kDelMemberFromChatRoom = 0xe64290;
const UINT64 kGetMemberFromChatRoom = 0x2162460;//ok
const UINT64 kNewChatRoom = 0x25025F0;//ok
const UINT64 kFreeChatRoom = 0x25027F0;//ok
//const UINT64 kTopMsg = 0xa5e4f0;
//const UINT64 kRemoveTopMsg = 0xe787b0;
//const UINT64 kInviteMember = 0xe63650;
//const UINT64 kHookLog = 0x1304e60;
//const UINT64 kCreateChatRoom = 0xe63340;
//const UINT64 kQuitChatRoom = 0xe6e3b0;
const UINT64 kForwardMsg = 0x22C15F0; //ok
//const UINT64 kOnSnsTimeLineSceneFinish = 0x1a73150;
//const UINT64 kSNSGetFirstPage = 0x1a51dd0;
//const UINT64 kSNSGetNextPageScene = 0x1a77240;
//const UINT64 kSNSDataMgr = 0xeebda0;
//const UINT64 kSNSTimeLineMgr = 0x19e83a0;
const UINT64 kGetMgrByPrefixLocalId = 0x213B010; //ok
//const UINT64 kAddFavFromMsg = 0x1601520;
const UINT64 kGetChatMgr = 0x1B82BF0; //ok
//const UINT64 kGetFavoriteMgr = 0x8c69b0;
//const UINT64 kAddFavFromImage = 0x160b920;
const UINT64 kGetContact = 0x2194630; //ok
const UINT64 kNewContact = 0x25193B0; //ok
const UINT64 kFreeContact = 0x2519A60; //ok
//const UINT64 kNewMMReaderItem = 0x8c79a0;
//const UINT64 kFreeMMReaderItem = 0x8c6da0;
//const UINT64 kForwordPublicMsg = 0xddc6c0;
const UINT64 kParseAppMsgXml = 0x24B3FD0; //ok
const UINT64 kNewAppMsgInfo = 0x1BCE7B0; //ok
const UINT64 kFreeAppMsgInfo = 0x1B93D80; //ok
const UINT64 kGetPreDownLoadMgr = 0x1C0A3A0; //ok
const UINT64 kPushAttachTask = 0x1CDA9B0; //ok
//const UINT64 kGetCustomSmileyMgr = 0x915c00;
//const UINT64 kSendCustomEmotion = 0xec0a40;
//const UINT64 kNewJsApiShareAppMessage = 0x13be1a0;
//const UINT64 kInitJsConfig = 0x137bc00;
//const UINT64 kSendApplet = 0x13c0920;
//const UINT64 kSendAppletSecond = 0x13c1150;
//const UINT64 kGetAppInfoByWaid = 0x13c5790;
//const UINT64 kCopyShareAppMessageRequest = 0x13c0670;
//const UINT64 kNewWAUpdatableMsgInfo = 0x919ca0;
//const UINT64 kFreeWAUpdatableMsgInfo = 0x8fc230;
//const UINT64 kSendPatMsg = 0x195f340;
//const UINT64 kGetOCRManager = 0x999780;
//const UINT64 kDoOCRTask = 0x190b2a0;
const UINT64 kGetLockWechatMgr = 0x1C84DA0;//ok
const UINT64 kRequestLockWechat = 0x1C39860;//ok
const UINT64 kRequestUnLockWechat = 0x1C39B00;//ok
const UINT64 kOnLoginBtnClick = 0x202BC90;//ok
const UINT64 kOnLoginBtnParam = 0x4ECEE08;//ok
const UINT64 kGetQRCodeLoginMgr = 0x201E420;//ok
const UINT64 kUpdateMsg = 0x2142200;//ok
const UINT64 kGetVoiceMgr = 0x1E13320;//ok
const UINT64 kChatMsg2NetSceneSendMsg = 0x1B71FD0;//ok
const UINT64 kTranslateVoice = 0x2353E00;//ok
const UINT64 kNewWebViewPageConfig = 0x1B53AE0; //ok
const UINT64 kFreeWebViewPageConfig = 0x1B53D10; //ok
const UINT64 kGetWebViewMgr = 0x1B43950; //ok
const UINT64 kShowWebView = 0x302ED40;//ok
const UINT64 kSetUrl = 0x26155F0; //ok
//发送小程序
const UINT64 kNewJsApiShareAppMessage = 0x26CDA30; //ok
const UINT64 kInitJsConfig = 0x268A970; //ok
const UINT64 kSendApplet = 0x26D01D0; //ok
const UINT64 kSendAppletSecond = 0x26D0A00; //ok
const UINT64 kGetAppInfoByWaid = 0x26D4F80; //ok
const UINT64 kCopyShareAppMessageRequest = 0x26CFF20;//ok
const UINT64 kNewWAUpdatableMsgInfo = 0x1BCDD10; //ok
const UINT64 kFreeWAUpdatableMsgInfo = 0x1B92AC0;//ok
const UINT64 kSendPatMsg = 0x2CA97A0;//ok PatMgr::SendPatMsg
const UINT64 kSendAppletRcxParam = 0x4F64A60; //ok
//取群联系人昵称
const UINT64 kChatRoomNickNameMgr = 0x1B7F100; //ok
const UINT64 kGetChatRoomNickName = 0x21625D0; //ok
//卡片
//const UINT64 kRichTextMgr = 0x1C23630;
const UINT64 kSendRichTextMsg = 0x20D5730;
const UINT64 kNewRChatMsg = 0x1B58BC0;
const UINT64 kFreeRChatMsg = 0x1B57F90;
//HOOK偏移
const UINT64 wcf_hook = 0x00; // Hook地址
const UINT64 wcf_HookCall = 0x213A2A0; // Call地址
const UINT64 wcf_msgId = 0x30; // 消息ID地址
const UINT64 wcf_type = 0x38; // 消息类型地址
const UINT64 wcf_isSelf = 0x3C; // 是否自己发送标志地址
const UINT64 wcf_ts = 0x44; // TimeStamp
const UINT64 wcf_roomId = 0x48; // 群聊时为群ID私聊时为微信ID
const UINT64 wcf_content = 0x88; // 消息内容地址
const UINT64 wcf_wxid = 0x240; // 私聊时为空群聊时为发送者微信ID
const UINT64 wcf_sign = 0x260; // Sign
const UINT64 wcf_thumb = 0x280; // 缩略图
const UINT64 wcf_extra = 0x2A0; // 附加数据
const UINT64 wcf_msgXml = 0x308; // 消息xml内容地址
//登录状态
const UINT64 wcf_kLoginStatu = 0x59380B0;
const UINT64 wcf_iwxid = 0x5AB7FB8;
const UINT64 wcf_nickName = 0x5AB8098;
const UINT64 wcf_mobile = 0x5AB7FD8;
const UINT64 wcf_home = 0x5A7E190;
} // namespace offset