Merge branch 'lich0821:master' into master
This commit is contained in:
commit
68a99c5bc1
28
README.MD
28
README.MD
@ -2,24 +2,17 @@
|
|||||||
|
|
||||||
一个玩微信的工具。更多介绍见:[WeChatFerry: 一个玩微信的工具](https://mp.weixin.qq.com/s/CGLfSaNDy8MyuyPWGjGJ7w)。
|
一个玩微信的工具。更多介绍见:[WeChatFerry: 一个玩微信的工具](https://mp.weixin.qq.com/s/CGLfSaNDy8MyuyPWGjGJ7w)。
|
||||||
|
|
||||||
<details><summary><font color="red" size="12">免责声明【必读】</font></summary>
|
<details>
|
||||||
|
<summary><b>⚠️ 免责声明【必读】⚠️</b></summary>
|
||||||
|
|
||||||
本工具仅供学习和技术研究使用,不得用于任何商业或非法行为,否则后果自负。
|
请阅读完整的免责声明:[点击查看](DISCLAIMER.md)
|
||||||
|
|
||||||
本工具的作者不对本工具的安全性、完整性、可靠性、有效性、正确性或适用性做任何明示或暗示的保证,也不对本工具的使用或滥用造成的任何直接或间接的损失、责任、索赔、要求或诉讼承担任何责任。
|
|
||||||
|
|
||||||
本工具的作者保留随时修改、更新、删除或终止本工具的权利,无需事先通知或承担任何义务。
|
|
||||||
|
|
||||||
本工具的使用者应遵守相关法律法规,尊重微信的版权和隐私,不得侵犯微信或其他第三方的合法权益,不得从事任何违法或不道德的行为。
|
|
||||||
|
|
||||||
本工具的使用者在下载、安装、运行或使用本工具时,即表示已阅读并同意本免责声明。如有异议,请立即停止使用本工具,并删除所有相关文件。
|
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|[📖 Python 文档](https://wechatferry.readthedocs.io/)|[📺 Python 视频教程](https://mp.weixin.qq.com/s/APdjGyZ2hllXxyG_sNCfXQ)|[🙋 FAQ](https://mp.weixin.qq.com/s/YvgFFhF6D-79kXDzRqtg6w)|
|
|[📖 Python 文档](https://wechatferry.readthedocs.io/)|[📺 Python 视频教程](https://mp.weixin.qq.com/s/APdjGyZ2hllXxyG_sNCfXQ)|[🙋 FAQ](https://mp.weixin.qq.com/s/UbzPuw3-2xZLEzUABXMEdw)|
|
||||||
|:-:|:-:|:-:|
|
|:-:|:-:|:-:|
|
||||||
|
|
||||||
👉 [WeChatRobot🤖](https://github.com/lich0821/WeChatRobot),一个基于 WeChatFerry 的 Python 机器人框架。
|
👉 [WeChatRobot🤖](https://github.com/lich0821/WeChatRobot),一个基于 WeChatFerry 的 Python 机器人示例。
|
||||||
|
|
||||||
|||
|
|||
|
||||||
|:-:|:-:|
|
|:-:|:-:|
|
||||||
@ -76,11 +69,12 @@
|
|||||||
pip install --upgrade wcferry
|
pip install --upgrade wcferry
|
||||||
```
|
```
|
||||||
|
|
||||||
* 参考框架:[🤖WeChatRobot](https://github.com/lich0821/WeChatRobot)
|
* 参考示例:[🤖WeChatRobot](https://github.com/lich0821/WeChatRobot)
|
||||||
|
|
||||||
### HTTP
|
### HTTP
|
||||||
* [wcfrust](https://github.com/lich0821/wcf-client-rust)(基于 Rust)
|
* [wcfrust](https://github.com/lich0821/wcf-client-rust)(基于 Rust)
|
||||||
* [go_wcf_http](clients/go_wcf_http/README.MD)(基于 Go)
|
* [go_wcf_http](clients/go_wcf_http/README.MD)(基于 Go)
|
||||||
|
* [wrest-chat](https://github.com/opentdp/wrest-chat)(基于 Go)
|
||||||
* [wcf-http](https://github.com/yuxiaoli/wcf-http)(基于 Python)
|
* [wcf-http](https://github.com/yuxiaoli/wcf-http)(基于 Python)
|
||||||
|
|
||||||
### Java
|
### Java
|
||||||
@ -211,9 +205,9 @@ WeChatFerry
|
|||||||
|
|
||||||
## 版本更新
|
## 版本更新
|
||||||
|
|
||||||
### v39.3.4
|
### v39.3.5
|
||||||
|
|
||||||
* 实现获取登录二维码
|
* 代码优化
|
||||||
|
|
||||||
<details><summary>点击查看更多</summary>
|
<details><summary>点击查看更多</summary>
|
||||||
|
|
||||||
@ -225,6 +219,10 @@ WeChatFerry
|
|||||||
* `y` 是 `WeChatFerry` 的版本,从 0 开始
|
* `y` 是 `WeChatFerry` 的版本,从 0 开始
|
||||||
* `z` 是各客户端的版本,从 0 开始
|
* `z` 是各客户端的版本,从 0 开始
|
||||||
|
|
||||||
|
### v39.3.4
|
||||||
|
|
||||||
|
* 实现获取登录二维码
|
||||||
|
|
||||||
### v39.3.3
|
### v39.3.3
|
||||||
|
|
||||||
* 修复发送文件 / 图片中文路径问题
|
* 修复发送文件 / 图片中文路径问题
|
||||||
|
18
WeChatFerry/DISCLAIMER.md
Normal file
18
WeChatFerry/DISCLAIMER.md
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# 免责声明
|
||||||
|
|
||||||
|
1. **本工具为开源项目,仅提供基础功能,供用户进行合法的学习、研究和非商业用途**。禁止将本工具用于任何违法或侵权行为。
|
||||||
|
|
||||||
|
2. **二次开发者的责任**:
|
||||||
|
- 任何基于本工具进行的二次开发、修改或衍生产品,其行为及后果由二次开发者独立承担,与本工具贡献者无关。
|
||||||
|
- **禁止使用贡献者的姓名、项目名称或相关信息作为二次开发产品的背书或推广手段**。
|
||||||
|
- 建议二次开发者在其衍生产品中添加自己的免责声明,明确责任归属。
|
||||||
|
|
||||||
|
3. **用户责任**:
|
||||||
|
- 使用本工具或其衍生产品的所有后果由用户自行承担。原贡献者不对因直接或间接使用本工具而导致的任何损失、责任或争议负责。
|
||||||
|
|
||||||
|
4. **法律约束**:
|
||||||
|
- 用户和二次开发者须遵守《中华人民共和国网络安全法》、《中华人民共和国著作权法》等相关法律法规。
|
||||||
|
- 本工具涉及的所有第三方商标或产品名称,其权利归权利人所有,作者与第三方无任何直接或间接关联。
|
||||||
|
|
||||||
|
5. **作者保留权利**:
|
||||||
|
- 本工具作者保留随时修改、更新、删除或终止本工具的权利,无需事先通知或承担任何义务。
|
@ -1,56 +0,0 @@
|
|||||||
#include <filesystem>
|
|
||||||
|
|
||||||
#include "log.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
#define LOGGER_NAME "WCF"
|
|
||||||
#define LOGGER_FILE_NAME "/logs/wcf.txt"
|
|
||||||
#define LOGGER_MAX_SIZE 1024 * 1024 * 10 // 10M
|
|
||||||
#define LOGGER_MAX_FILES 10 // 10 files
|
|
||||||
|
|
||||||
void InitLogger(std::string path)
|
|
||||||
{
|
|
||||||
static std::shared_ptr<spdlog::logger> logger = nullptr;
|
|
||||||
if (logger != nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// check and create logs folder
|
|
||||||
std::filesystem::path logDir = std::filesystem::path(path) / "logs";
|
|
||||||
if (!std::filesystem::exists(logDir)) {
|
|
||||||
std::filesystem::create_directory(logDir);
|
|
||||||
}
|
|
||||||
auto filename = std::filesystem::path(path + LOGGER_FILE_NAME).make_preferred().string();
|
|
||||||
try {
|
|
||||||
logger = spdlog::rotating_logger_mt(LOGGER_NAME, filename, LOGGER_MAX_SIZE, LOGGER_MAX_FILES);
|
|
||||||
} catch (const spdlog::spdlog_ex &ex) {
|
|
||||||
MessageBox(NULL, String2Wstring(ex.what()).c_str(), L"Init LOGGER ERROR", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
spdlog::set_default_logger(logger);
|
|
||||||
logger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] [%n] [%s::%#::%!] %v");
|
|
||||||
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_DEBUG
|
|
||||||
spdlog::set_level(spdlog::level::debug);
|
|
||||||
logger->flush_on(spdlog::level::debug);
|
|
||||||
#else
|
|
||||||
logger->flush_on(spdlog::level::info);
|
|
||||||
#endif
|
|
||||||
LOG_DEBUG("InitLogger with debug level");
|
|
||||||
}
|
|
||||||
|
|
||||||
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_DEBUG
|
|
||||||
|
|
||||||
#define BUF_SIZE (1024 * 1024)
|
|
||||||
static char buf[BUF_SIZE] = { 0 };
|
|
||||||
|
|
||||||
void log_buffer(uint8_t *buffer, size_t len)
|
|
||||||
{
|
|
||||||
size_t j = sprintf_s(buf, BUF_SIZE, "BUF@%p[%zd]: ", buffer, len);
|
|
||||||
for (size_t i = 0; i < len; i++) {
|
|
||||||
j += sprintf_s(buf + j, BUF_SIZE, "%02X ", buffer[i]);
|
|
||||||
if (j > BUF_SIZE - 3) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LOG_DEBUG(buf);
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,24 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#ifdef ENABLE_DEBUG_LOG
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG
|
|
||||||
void log_buffer(uint8_t *buffer, size_t len);
|
|
||||||
#define LOG_BUFFER(buf, len) log_buffer((buf), (len))
|
|
||||||
#else
|
|
||||||
#define LOG_BUFFER(...) (void)0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "spdlog/sinks/rotating_file_sink.h"
|
|
||||||
#include "spdlog/sinks/stdout_color_sinks.h"
|
|
||||||
#include "spdlog/spdlog.h"
|
|
||||||
|
|
||||||
#define LOG_DEBUG(...) SPDLOG_DEBUG(__VA_ARGS__);
|
|
||||||
#define LOG_INFO(...) SPDLOG_INFO(__VA_ARGS__);
|
|
||||||
#define LOG_WARN(...) SPDLOG_WARN(__VA_ARGS__);
|
|
||||||
#define LOG_ERROR(...) SPDLOG_ERROR(__VA_ARGS__);
|
|
||||||
|
|
||||||
void InitLogger(std::string path);
|
|
87
WeChatFerry/com/log.hpp
Normal file
87
WeChatFerry/com/log.hpp
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <memory>
|
||||||
|
#include <spdlog/sinks/rotating_file_sink.h>
|
||||||
|
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
#define LOG_DEBUG(...) SPDLOG_DEBUG(__VA_ARGS__)
|
||||||
|
#define LOG_INFO(...) SPDLOG_INFO(__VA_ARGS__)
|
||||||
|
#define LOG_WARN(...) SPDLOG_WARN(__VA_ARGS__)
|
||||||
|
#define LOG_ERROR(...) SPDLOG_ERROR(__VA_ARGS__)
|
||||||
|
|
||||||
|
#ifdef ENABLE_DEBUG_LOG
|
||||||
|
#define LOG_BUFFER(buf, len) Log::log_buffer((buf), (len))
|
||||||
|
#else
|
||||||
|
#define LOG_BUFFER(...) (void)0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Log
|
||||||
|
{
|
||||||
|
inline constexpr char DEFAULT_LOGGER_NAME[] = "WCF";
|
||||||
|
inline constexpr char DEFAULT_LOGGER_FILE[] = "logs/wcf.txt";
|
||||||
|
inline constexpr size_t DEFAULT_LOGGER_MAX_SIZE = 1024 * 1024 * 10; // 10MB
|
||||||
|
inline constexpr size_t DEFAULT_LOGGER_MAX_FILES = 10;
|
||||||
|
|
||||||
|
inline void InitLogger(const std::string &path)
|
||||||
|
{
|
||||||
|
static std::shared_ptr<spdlog::logger> logger = nullptr;
|
||||||
|
|
||||||
|
if (logger != nullptr) {
|
||||||
|
return; // 已初始化
|
||||||
|
}
|
||||||
|
|
||||||
|
std::filesystem::path filename = std::filesystem::path(path) / DEFAULT_LOGGER_FILE;
|
||||||
|
std::filesystem::path logDir = filename.parent_path();
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(logDir)) {
|
||||||
|
std::filesystem::create_directories(logDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
logger = spdlog::rotating_logger_mt(DEFAULT_LOGGER_NAME, filename.string(), DEFAULT_LOGGER_MAX_SIZE,
|
||||||
|
DEFAULT_LOGGER_MAX_FILES);
|
||||||
|
} catch (const spdlog::spdlog_ex &ex) {
|
||||||
|
MessageBox(NULL, String2Wstring(ex.what()).c_str(), L"Init LOGGER ERROR", MB_ICONERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
spdlog::set_default_logger(logger);
|
||||||
|
logger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] [%n] [%s::%#::%!] %v");
|
||||||
|
|
||||||
|
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_DEBUG
|
||||||
|
spdlog::set_level(spdlog::level::debug);
|
||||||
|
logger->flush_on(spdlog::level::debug);
|
||||||
|
#else
|
||||||
|
spdlog::set_level(spdlog::level::info);
|
||||||
|
logger->flush_on(spdlog::level::info);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SPDLOG_DEBUG("Logger initialized with default settings.");
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_DEBUG_LOG
|
||||||
|
inline void log_buffer(uint8_t *buffer, size_t len)
|
||||||
|
{
|
||||||
|
constexpr size_t BUF_SIZE = 1024 * 1024;
|
||||||
|
std::ostringstream oss;
|
||||||
|
|
||||||
|
oss << "BUF@" << static_cast<void *>(buffer) << "[" << len << "]: ";
|
||||||
|
for (size_t i = 0; i < len; ++i) {
|
||||||
|
oss << std::hex << std::uppercase << std::setw(2) << std::setfill('0') << static_cast<int>(buffer[i]) << " ";
|
||||||
|
if (oss.tellp() > BUF_SIZE - 3) {
|
||||||
|
break; // 防止缓冲区溢出
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SPDLOG_DEBUG(oss.str());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace Log
|
@ -8,7 +8,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.hpp"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#pragma comment(lib, "shlwapi")
|
#pragma comment(lib, "shlwapi")
|
||||||
|
44
WeChatFerry/license_check.bat
Normal file
44
WeChatFerry/license_check.bat
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
@echo off
|
||||||
|
chcp 65001 > nul
|
||||||
|
cd /d %~dp0
|
||||||
|
|
||||||
|
if "%CI%" == "true" (
|
||||||
|
echo 自动化编译环境,跳过手动确认。
|
||||||
|
echo 用户已接受开源协议 > license_accepted.flag
|
||||||
|
exit /b 0
|
||||||
|
)
|
||||||
|
|
||||||
|
:: 检查是否已接受协议
|
||||||
|
if exist ".license_accepted.flag" (
|
||||||
|
echo 用户已接受免责声明
|
||||||
|
exit /b 0
|
||||||
|
)
|
||||||
|
|
||||||
|
:: 检查免责声明文件是否存在
|
||||||
|
if not exist "DISCLAIMER.md" (
|
||||||
|
echo 错误:未找到免责声明文件 DISCLAIMER.md。
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
:: 生成临时文件并读取免责声明
|
||||||
|
type "DISCLAIMER.md" > temp_disclaimer.txt
|
||||||
|
|
||||||
|
:: 使用 PowerShell 显示弹窗
|
||||||
|
powershell -NoProfile -Command ^
|
||||||
|
"$text = Get-Content -Raw -Path 'temp_disclaimer.txt';" ^
|
||||||
|
"Add-Type -AssemblyName PresentationFramework;" ^
|
||||||
|
"$result = [System.Windows.MessageBox]::Show($text, '免责声明', 'OKCancel', 'Warning');" ^
|
||||||
|
"if ($result -ne 'OK') { exit 1 }"
|
||||||
|
|
||||||
|
:: 检查 PowerShell 执行结果
|
||||||
|
if %errorlevel% neq 0 (
|
||||||
|
echo 错误:用户未接受免责声明。停止生成。
|
||||||
|
del temp_disclaimer.txt
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
:: 用户接受免责声明,创建标志文件
|
||||||
|
echo 用户已接受免责声明 > .license_accepted.flag
|
||||||
|
del temp_disclaimer.txt
|
||||||
|
echo 用户已接受免责声明
|
||||||
|
exit /b 0
|
@ -1,5 +1,5 @@
|
|||||||
#include "pb_util.h"
|
#include "pb_util.h"
|
||||||
#include "log.h"
|
#include "log.hpp"
|
||||||
#include "pb_types.h"
|
#include "pb_types.h"
|
||||||
#include "wcf.pb.h"
|
#include "wcf.pb.h"
|
||||||
|
|
||||||
|
@ -141,14 +141,13 @@ xcopy /y $(OutDir)$(TargetFileName) $(SolutionDir)..\clients\python\wcferry</Com
|
|||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\com\log.h" />
|
<ClInclude Include="..\com\log.hpp" />
|
||||||
<ClInclude Include="..\com\util.h" />
|
<ClInclude Include="..\com\util.h" />
|
||||||
<ClInclude Include="framework.h" />
|
<ClInclude Include="framework.h" />
|
||||||
<ClInclude Include="injector.h" />
|
<ClInclude Include="injector.h" />
|
||||||
<ClInclude Include="sdk.h" />
|
<ClInclude Include="sdk.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\com\log.cpp" />
|
|
||||||
<ClCompile Include="..\com\util.cpp" />
|
<ClCompile Include="..\com\util.cpp" />
|
||||||
<ClCompile Include="dllmain.cpp" />
|
<ClCompile Include="dllmain.cpp" />
|
||||||
<ClCompile Include="injector.cpp" />
|
<ClCompile Include="injector.cpp" />
|
||||||
|
@ -24,10 +24,10 @@
|
|||||||
<ClInclude Include="injector.h">
|
<ClInclude Include="injector.h">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\com\log.h">
|
<ClInclude Include="..\com\util.h">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\com\util.h">
|
<ClInclude Include="..\com\log.hpp">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@ -41,9 +41,6 @@
|
|||||||
<ClCompile Include="injector.cpp">
|
<ClCompile Include="injector.cpp">
|
||||||
<Filter>源文件</Filter>
|
<Filter>源文件</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\com\log.cpp">
|
|
||||||
<Filter>源文件</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\com\util.cpp">
|
<ClCompile Include="..\com\util.cpp">
|
||||||
<Filter>源文件</Filter>
|
<Filter>源文件</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -1,44 +1,97 @@
|
|||||||
#include "Shlwapi.h"
|
#include "framework.h"
|
||||||
#include "framework.h"
|
#include <chrono>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
#include <optional>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
|
#include <sstream>
|
||||||
|
#include <thread>
|
||||||
#include <tlhelp32.h>
|
#include <tlhelp32.h>
|
||||||
|
|
||||||
#include "injector.h"
|
#include "injector.h"
|
||||||
#include "sdk.h"
|
#include "sdk.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
static BOOL injected = false;
|
static BOOL injected = false;
|
||||||
static HANDLE wcProcess = NULL;
|
static HANDLE wcProcess = NULL;
|
||||||
static HMODULE spyBase = NULL;
|
static HMODULE spyBase = NULL;
|
||||||
static WCHAR spyDllPath[MAX_PATH] = { 0 };
|
static std::wstring spyDllPath;
|
||||||
|
|
||||||
static int GetDllPath(bool debug, wchar_t *dllPath)
|
constexpr char DISCLAIMER_FILE[] = ".license_accepted.flag";
|
||||||
|
constexpr char DISCLAIMER_TEXT_FILE[] = "DISCLAIMER.md";
|
||||||
|
|
||||||
|
static std::optional<std::wstring> ReadDisclaimerText(const char *filePath)
|
||||||
{
|
{
|
||||||
GetModuleFileName(GetModuleHandle(WCFSDKDLL), dllPath, MAX_PATH);
|
std::ifstream file(filePath, std::ios::binary);
|
||||||
PathRemoveFileSpec(dllPath);
|
if (!file.is_open()) {
|
||||||
if (debug) {
|
return std::nullopt; // 文件打开失败
|
||||||
PathAppend(dllPath, WCFSPYDLL_DEBUG);
|
|
||||||
} else {
|
|
||||||
PathAppend(dllPath, WCFSPYDLL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PathFileExists(dllPath)) {
|
std::string content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
||||||
MessageBox(NULL, dllPath, L"文件不存在", 0);
|
return String2Wstring(content);
|
||||||
return ERROR_FILE_NOT_FOUND;
|
}
|
||||||
|
|
||||||
|
static bool ShowDisclaimer()
|
||||||
|
{
|
||||||
|
if (std::filesystem::exists(DISCLAIMER_FILE)) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
std::optional<std::wstring> disclaimerTextOpt = ReadDisclaimerText(DISCLAIMER_TEXT_FILE);
|
||||||
|
if (!disclaimerTextOpt.has_value() || disclaimerTextOpt->empty()) {
|
||||||
|
MessageBox(NULL, L"免责声明文件为空或读取失败。", L"错误", MB_ICONERROR);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring disclaimerText = *disclaimerTextOpt;
|
||||||
|
|
||||||
|
int result = MessageBox(NULL, disclaimerText.c_str(), L"免责声明", MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2);
|
||||||
|
|
||||||
|
if (result == IDCANCEL) {
|
||||||
|
MessageBox(NULL, L"您拒绝了免责声明,程序将退出。", L"提示", MB_ICONINFORMATION);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ofstream flagFile(DISCLAIMER_FILE, std::ios::out | std::ios::trunc);
|
||||||
|
if (!flagFile) {
|
||||||
|
MessageBox(NULL, L"无法创建协议标志文件。", L"错误", MB_ICONERROR);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
flagFile << "User accepted the license agreement.";
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::wstring GetDllPath(bool debug)
|
||||||
|
{
|
||||||
|
WCHAR buffer[MAX_PATH] = { 0 };
|
||||||
|
GetModuleFileName(GetModuleHandle(WCFSDKDLL), buffer, MAX_PATH);
|
||||||
|
|
||||||
|
std::filesystem::path path(buffer);
|
||||||
|
path.remove_filename(); // 移除文件名,保留目录路径
|
||||||
|
|
||||||
|
path /= debug ? WCFSPYDLL_DEBUG : WCFSPYDLL;
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(path)) {
|
||||||
|
MessageBox(NULL, path.c_str(), L"文件不存在", MB_ICONERROR);
|
||||||
|
return L"";
|
||||||
|
}
|
||||||
|
|
||||||
|
return path.wstring();
|
||||||
}
|
}
|
||||||
|
|
||||||
int WxInitSDK(bool debug, int port)
|
int WxInitSDK(bool debug, int port)
|
||||||
{
|
{
|
||||||
|
if (!ShowDisclaimer()) {
|
||||||
|
exit(-1); // 用户拒绝协议,退出程序
|
||||||
|
}
|
||||||
|
|
||||||
int status = 0;
|
int status = 0;
|
||||||
DWORD wcPid = 0;
|
DWORD wcPid = 0;
|
||||||
|
|
||||||
status = GetDllPath(debug, spyDllPath);
|
spyDllPath = GetDllPath(debug);
|
||||||
if (status != 0) {
|
if (spyDllPath.empty()) {
|
||||||
return status;
|
return ERROR_FILE_NOT_FOUND; // DLL 文件路径不存在
|
||||||
}
|
}
|
||||||
|
|
||||||
status = OpenWeChat(&wcPid);
|
status = OpenWeChat(&wcPid);
|
||||||
@ -52,8 +105,8 @@ int WxInitSDK(bool debug, int port)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sleep(2000); // 等待微信打开
|
std::this_thread::sleep_for(std::chrono::seconds(2)); // 等待微信打开
|
||||||
wcProcess = InjectDll(wcPid, spyDllPath, &spyBase);
|
wcProcess = InjectDll(wcPid, spyDllPath.c_str(), &spyBase);
|
||||||
if (wcProcess == NULL) {
|
if (wcProcess == NULL) {
|
||||||
MessageBox(NULL, L"注入失败", L"WxInitSDK", 0);
|
MessageBox(NULL, L"注入失败", L"WxInitSDK", 0);
|
||||||
return -1;
|
return -1;
|
||||||
@ -63,7 +116,7 @@ int WxInitSDK(bool debug, int port)
|
|||||||
pp.port = port;
|
pp.port = port;
|
||||||
sprintf_s(pp.path, MAX_PATH, "%s", std::filesystem::current_path().string().c_str());
|
sprintf_s(pp.path, MAX_PATH, "%s", std::filesystem::current_path().string().c_str());
|
||||||
|
|
||||||
if (!CallDllFuncEx(wcProcess, spyDllPath, spyBase, "InitSpy", (LPVOID)&pp, sizeof(PortPath_t), NULL)) {
|
if (!CallDllFuncEx(wcProcess, spyDllPath.c_str(), spyBase, "InitSpy", (LPVOID)&pp, sizeof(PortPath_t), NULL)) {
|
||||||
MessageBox(NULL, L"初始化失败", L"WxInitSDK", 0);
|
MessageBox(NULL, L"初始化失败", L"WxInitSDK", 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -78,7 +131,7 @@ int WxDestroySDK()
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CallDllFunc(wcProcess, spyDllPath, spyBase, "CleanupSpy", NULL)) {
|
if (!CallDllFunc(wcProcess, spyDllPath.c_str(), spyBase, "CleanupSpy", NULL)) {
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,9 @@
|
|||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
</Link>
|
</Link>
|
||||||
<PreBuildEvent>
|
<PreBuildEvent>
|
||||||
<Command>cd $(SolutionDir)rpc\proto
|
<Command>call "$(SolutionDir)license_check.bat"
|
||||||
|
if errorlevel 1 exit 1
|
||||||
|
cd $(SolutionDir)rpc\proto
|
||||||
$(SolutionDir)rpc\tool\protoc --nanopb_out=. wcf.proto</Command>
|
$(SolutionDir)rpc\tool\protoc --nanopb_out=. wcf.proto</Command>
|
||||||
</PreBuildEvent>
|
</PreBuildEvent>
|
||||||
<PreBuildEvent>
|
<PreBuildEvent>
|
||||||
@ -124,7 +126,9 @@ xcopy /y $(OutDir)$(TargetFileName) $(SolutionDir)Out
|
|||||||
xcopy /y $(OutDir)$(TargetName).exp $(SolutionDir)Out
|
xcopy /y $(OutDir)$(TargetName).exp $(SolutionDir)Out
|
||||||
xcopy /y $(OutDir)$(TargetName).lib $(SolutionDir)Out
|
xcopy /y $(OutDir)$(TargetName).lib $(SolutionDir)Out
|
||||||
xcopy /y $(OutDir)$(TargetName).pdb $(SolutionDir)Out
|
xcopy /y $(OutDir)$(TargetName).pdb $(SolutionDir)Out
|
||||||
xcopy /y $(OutDir)$(TargetFileName) $(SolutionDir)..\clients\python\wcferry</Command>
|
xcopy /y $(SolutionDir)DISCLAIMER.md $(SolutionDir)Out
|
||||||
|
xcopy /y $(OutDir)$(TargetFileName) $(SolutionDir)..\clients\python\wcferry
|
||||||
|
xcopy /y $(SolutionDir)DISCLAIMER.md $(SolutionDir)..\clients\python\wcferry</Command>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Message>Copy spy.dll</Message>
|
<Message>Copy spy.dll</Message>
|
||||||
@ -161,7 +165,9 @@ xcopy /y $(OutDir)$(TargetFileName) $(SolutionDir)..\clients\python\wcferry</Com
|
|||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
</Link>
|
</Link>
|
||||||
<PreBuildEvent>
|
<PreBuildEvent>
|
||||||
<Command>cd $(SolutionDir)rpc\proto
|
<Command>call "$(SolutionDir)license_check.bat"
|
||||||
|
if errorlevel 1 exit 1
|
||||||
|
cd $(SolutionDir)rpc\proto
|
||||||
$(SolutionDir)rpc\tool\protoc --nanopb_out=. wcf.proto</Command>
|
$(SolutionDir)rpc\tool\protoc --nanopb_out=. wcf.proto</Command>
|
||||||
</PreBuildEvent>
|
</PreBuildEvent>
|
||||||
<PreBuildEvent>
|
<PreBuildEvent>
|
||||||
@ -173,7 +179,9 @@ xcopy /y $(OutDir)$(TargetFileName) $(SolutionDir)Out
|
|||||||
xcopy /y $(OutDir)$(TargetName).exp $(SolutionDir)Out
|
xcopy /y $(OutDir)$(TargetName).exp $(SolutionDir)Out
|
||||||
xcopy /y $(OutDir)$(TargetName).lib $(SolutionDir)Out
|
xcopy /y $(OutDir)$(TargetName).lib $(SolutionDir)Out
|
||||||
xcopy /y $(OutDir)$(TargetName).pdb $(SolutionDir)Out
|
xcopy /y $(OutDir)$(TargetName).pdb $(SolutionDir)Out
|
||||||
xcopy /y $(OutDir)$(TargetFileName) $(SolutionDir)..\clients\python\wcferry</Command>
|
xcopy /y $(SolutionDir)DISCLAIMER.md $(SolutionDir)Out
|
||||||
|
xcopy /y $(OutDir)$(TargetFileName) $(SolutionDir)..\clients\python\wcferry
|
||||||
|
xcopy /y $(SolutionDir)DISCLAIMER.md $(SolutionDir)..\clients\python\wcferry</Command>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Message>Copy spy.dll</Message>
|
<Message>Copy spy.dll</Message>
|
||||||
@ -211,7 +219,9 @@ xcopy /y $(OutDir)$(TargetFileName) $(SolutionDir)..\clients\python\wcferry</Com
|
|||||||
</Link>
|
</Link>
|
||||||
<PreBuildEvent>
|
<PreBuildEvent>
|
||||||
<Message>Generating PB files</Message>
|
<Message>Generating PB files</Message>
|
||||||
<Command>cd $(SolutionDir)rpc\proto
|
<Command>call "$(SolutionDir)license_check.bat"
|
||||||
|
if errorlevel 1 exit 1
|
||||||
|
cd $(SolutionDir)rpc\proto
|
||||||
$(SolutionDir)rpc\tool\protoc --nanopb_out=. wcf.proto</Command>
|
$(SolutionDir)rpc\tool\protoc --nanopb_out=. wcf.proto</Command>
|
||||||
</PreBuildEvent>
|
</PreBuildEvent>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
@ -221,11 +231,13 @@ xcopy /y $(OutDir)$(TargetFileName) $(SolutionDir)Out
|
|||||||
xcopy /y $(OutDir)$(TargetName).exp $(SolutionDir)Out
|
xcopy /y $(OutDir)$(TargetName).exp $(SolutionDir)Out
|
||||||
xcopy /y $(OutDir)$(TargetName).lib $(SolutionDir)Out
|
xcopy /y $(OutDir)$(TargetName).lib $(SolutionDir)Out
|
||||||
xcopy /y $(OutDir)$(TargetName).pdb $(SolutionDir)Out
|
xcopy /y $(OutDir)$(TargetName).pdb $(SolutionDir)Out
|
||||||
xcopy /y $(OutDir)$(TargetFileName) $(SolutionDir)..\clients\python\wcferry</Command>
|
xcopy /y $(SolutionDir)DISCLAIMER.md $(SolutionDir)Out
|
||||||
|
xcopy /y $(OutDir)$(TargetFileName) $(SolutionDir)..\clients\python\wcferry
|
||||||
|
xcopy /y $(SolutionDir)DISCLAIMER.md $(SolutionDir)..\clients\python\wcferry</Command>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\com\log.h" />
|
<ClInclude Include="..\com\log.hpp" />
|
||||||
<ClInclude Include="..\com\util.h" />
|
<ClInclude Include="..\com\util.h" />
|
||||||
<ClInclude Include="..\rpc\nanopb\pb.h" />
|
<ClInclude Include="..\rpc\nanopb\pb.h" />
|
||||||
<ClInclude Include="..\rpc\nanopb\pb_common.h" />
|
<ClInclude Include="..\rpc\nanopb\pb_common.h" />
|
||||||
@ -250,7 +262,6 @@ xcopy /y $(OutDir)$(TargetFileName) $(SolutionDir)..\clients\python\wcferry</Com
|
|||||||
<ClInclude Include="user_info.h" />
|
<ClInclude Include="user_info.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\com\log.cpp" />
|
|
||||||
<ClCompile Include="..\com\util.cpp" />
|
<ClCompile Include="..\com\util.cpp" />
|
||||||
<ClCompile Include="..\rpc\nanopb\pb_common.c" />
|
<ClCompile Include="..\rpc\nanopb\pb_common.c" />
|
||||||
<ClCompile Include="..\rpc\nanopb\pb_decode.c" />
|
<ClCompile Include="..\rpc\nanopb\pb_decode.c" />
|
||||||
|
@ -81,10 +81,10 @@
|
|||||||
<ClInclude Include="..\smc\codec.h">
|
<ClInclude Include="..\smc\codec.h">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\com\log.h">
|
<ClInclude Include="..\com\util.h">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\com\util.h">
|
<ClInclude Include="..\com\log.hpp">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@ -134,9 +134,6 @@
|
|||||||
<ClCompile Include="funcs.cpp">
|
<ClCompile Include="funcs.cpp">
|
||||||
<Filter>源文件</Filter>
|
<Filter>源文件</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\com\log.cpp">
|
|
||||||
<Filter>源文件</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\com\util.cpp">
|
<ClCompile Include="..\com\util.cpp">
|
||||||
<Filter>源文件</Filter>
|
<Filter>源文件</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "chatroom_mgmt.h"
|
#include "chatroom_mgmt.h"
|
||||||
#include "log.h"
|
#include "log.hpp"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#pragma execution_character_set("utf-8")
|
#pragma execution_character_set("utf-8")
|
||||||
|
|
||||||
#include "contact_mgmt.h"
|
#include "contact_mgmt.h"
|
||||||
#include "log.h"
|
#include "log.hpp"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
#include "exec_sql.h"
|
#include "exec_sql.h"
|
||||||
#include "log.h"
|
#include "log.hpp"
|
||||||
#include "sqlite3.h"
|
#include "sqlite3.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include "codec.h"
|
#include "codec.h"
|
||||||
#include "exec_sql.h"
|
#include "exec_sql.h"
|
||||||
#include "funcs.h"
|
#include "funcs.h"
|
||||||
#include "log.h"
|
#include "log.hpp"
|
||||||
#include "spy_types.h"
|
#include "spy_types.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.hpp"
|
||||||
#include "receive_msg.h"
|
#include "receive_msg.h"
|
||||||
#include "user_info.h"
|
#include "user_info.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#include "contact_mgmt.h"
|
#include "contact_mgmt.h"
|
||||||
#include "exec_sql.h"
|
#include "exec_sql.h"
|
||||||
#include "funcs.h"
|
#include "funcs.h"
|
||||||
#include "log.h"
|
#include "log.hpp"
|
||||||
#include "pb_types.h"
|
#include "pb_types.h"
|
||||||
#include "pb_util.h"
|
#include "pb_util.h"
|
||||||
#include "receive_msg.h"
|
#include "receive_msg.h"
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "exec_sql.h"
|
#include "exec_sql.h"
|
||||||
#include "log.h"
|
#include "log.hpp"
|
||||||
#include "send_msg.h"
|
#include "send_msg.h"
|
||||||
#include "spy_types.h"
|
#include "spy_types.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.hpp"
|
||||||
#include "rpc_server.h"
|
#include "rpc_server.h"
|
||||||
#include "spy.h"
|
#include "spy.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@ -21,7 +21,7 @@ void InitSpy(LPVOID args)
|
|||||||
wchar_t version[16] = { 0 };
|
wchar_t version[16] = { 0 };
|
||||||
PortPath_t *pp = (PortPath_t *)args;
|
PortPath_t *pp = (PortPath_t *)args;
|
||||||
|
|
||||||
InitLogger(pp->path);
|
Log::InitLogger(pp->path);
|
||||||
g_WeChatWinDllAddr = (UINT64)GetModuleHandle(L"WeChatWin.dll"); // 获取wechatWin模块地址
|
g_WeChatWinDllAddr = (UINT64)GetModuleHandle(L"WeChatWin.dll"); // 获取wechatWin模块地址
|
||||||
if (g_WeChatWinDllAddr == 0) {
|
if (g_WeChatWinDllAddr == 0) {
|
||||||
LOG_ERROR("获取 wechatWin.dll 模块地址失败");
|
LOG_ERROR("获取 wechatWin.dll 模块地址失败");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "user_info.h"
|
#include "user_info.h"
|
||||||
#include "log.h"
|
#include "log.hpp"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
extern UINT64 g_WeChatWinDllAddr;
|
extern UINT64 g_WeChatWinDllAddr;
|
||||||
|
Loading…
Reference in New Issue
Block a user