Files
SimpleRemoter/common/mask.h
2025-08-10 12:04:08 +02:00

171 lines
5.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#include "header.h"
// 数据包协议封装格式
// Copy left: 962914132@qq.com & ChatGPT
enum PkgMaskType {
MaskTypeUnknown = -1,
MaskTypeNone,
MaskTypeHTTP,
MaskTypeNum,
};
#define DEFAULT_HOST "example.com"
inline ULONG UnMaskHttp(char* src, ULONG srcSize) {
const char* header_end_mark = "\r\n\r\n";
const ULONG mark_len = 4;
// 查找 HTTP 头部结束标记
for (ULONG i = 0; i + mark_len <= srcSize; ++i) {
if (memcmp(src + i, header_end_mark, mark_len) == 0) {
return i + mark_len; // 返回 Body 起始位置
}
}
return 0; // 无效数据
}
// TryUnMask 尝试去掉伪装的协议头.
inline ULONG TryUnMask(char* src, ULONG srcSize, PkgMaskType& maskHit) {
if (srcSize >= 5 && memcmp(src, "POST ", 5) == 0) {
maskHit = MaskTypeHTTP;
return UnMaskHttp(src, srcSize);
}
maskHit = MaskTypeNone;
return 0;
}
// PkgMask 针对消息进一步加密、混淆或伪装.
class PkgMask {
protected:
virtual ~PkgMask() {}
public:
virtual void Destroy() {
delete this;
}
virtual void Mask(char*& dst, ULONG& dstSize, char* src, ULONG srcSize, int cmd = -1) {
dst = src;
dstSize = srcSize;
}
virtual ULONG UnMask(char* src, ULONG srcSize) {
return 0;
}
virtual PkgMask* SetServer(const std::string& addr) { return this; }
virtual PkgMaskType GetMaskType() const {
return MaskTypeNone;
}
};
class HttpMask : public PkgMask {
public:
virtual PkgMaskType GetMaskType() const override {
return MaskTypeHTTP;
}
/**
* @brief 构造函数
* @param host HTTP Host 头字段
*/
explicit HttpMask(const std::string& host, const std::map<std::string, std::string>& headers = {}) :
product_(GenerateRandomString()), host_(host) {
// 初始化随机数生成器
srand(static_cast<unsigned>(time(nullptr)));
char buf[32];
sprintf_s(buf, "V%d.%d.%d", rand() % 10, rand() % 10, rand() % 10);
version_ = buf;
user_agent_ = GetEnhancedSystemUA(product_, version_);
for (std::map<std::string, std::string>::const_iterator it = headers.begin(); it != headers.end(); ++it) {
headers_ += it->first + ": " + it->second + "\r\n";
}
}
/**
* @brief 将原始数据伪装为 HTTP 请求
* @param dst [输出] 伪装后的数据缓冲区(需调用者释放)
* @param dstSize [输出] 伪装后数据长度
* @param src 原始数据指针
* @param srcSize 原始数据长度
* @param cmd 命令号
*/
void Mask(char*& dst, ULONG& dstSize, char* src, ULONG srcSize, int cmd = -1) {
// 生成动态 HTTP 头部
std::string http_header =
"POST " + GeneratePath(cmd) + " HTTP/1.1\r\n"
"Host: " + host_ + "\r\n"
"User-Agent: " + user_agent_ + "\r\n"
"Content-Type: application/octet-stream\r\n"
"Content-Length: " + std::to_string(srcSize) + "\r\n" + headers_ +
"Connection: keep-alive\r\n"
"\r\n"; // 空行分隔头部和 Body
// 分配输出缓冲区
dstSize = static_cast<ULONG>(http_header.size()) + srcSize;
dst = new char[dstSize];
// 拷贝数据HTTP 头部 + 原始数据
memcpy(dst, http_header.data(), http_header.size());
memcpy(dst + http_header.size(), src, srcSize);
}
/**
* @brief 从 HTTP 数据中提取原始数据起始位置
* @param src 收到的 HTTP 数据
* @param srcSize 数据长度
* @return ULONG 原始数据在 src 中的起始偏移量(失败返回 0
*/
ULONG UnMask(char* src, ULONG srcSize) {
return UnMaskHttp(src, srcSize);
}
PkgMask* SetServer(const std::string& addr) override {
host_ = addr;
return this;
}
private:
static std::string GetEnhancedSystemUA(const std::string& appName, const std::string& appVersion) {
#ifdef _WIN32
OSVERSIONINFOEX osvi = {};
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
GetVersionEx((OSVERSIONINFO*)&osvi);
// 获取系统架构
SYSTEM_INFO si;
GetNativeSystemInfo(&si);
std::string arch = (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) ? "Win64; x64" :
(si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64) ? "Win64; ARM64" :
"WOW64";
return "Mozilla/5.0 (" +
std::string("Windows NT ") +
std::to_string(osvi.dwMajorVersion) + "." +
std::to_string(osvi.dwMinorVersion) + "; " +
arch + ") " +
appName + "/" + appVersion;
#else
return "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36";
#endif
}
std::string host_; // 目标主机
std::string product_; // 产品名称
std::string version_; // 产品版本
std::string user_agent_;// 代理名称
std::string headers_; // 自定义请求头
/** 生成随机 URL 路径 */
std::string GenerateRandomString(int size = 8) const {
static const char charset[] = "abcdefghijklmnopqrstuvwxyz0123456789";
char path[32];
for (int i = 0; i < size; ++i) {
path[i] = charset[rand() % (sizeof(charset) - 1)];
}
path[size] = 0;
return path;
}
std::string GeneratePath(int cmd) const {
static std::string root = "/" + product_ + "/" + GenerateRandomString() + "/";
return root + (cmd == -1 ? GenerateRandomString() : std::to_string(cmd));
}
};