Feature: Support HTTP protocol and add building option

This commit is contained in:
yuanyuanxiang
2025-07-12 20:27:14 +08:00
parent 45e7950bb7
commit db6b55d59b
12 changed files with 262 additions and 24 deletions

View File

@@ -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);
}
// <20>˺<EFBFBD><CBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƕ<EFBFBD><C7B6>̰߳<DFB3>ȫ<EFBFBD><C8AB>. ֻ<><D6BB>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD>.
LPBYTE CBuffer::GetBuffer(ULONG ulPos)
{

View File

@@ -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;

View File

@@ -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);

View File

@@ -566,7 +566,7 @@ BOOL IOCPServer::OnClientReceiving(PCONTEXT_OBJECT ContextObject, DWORD dwTrans
BOOL WriteContextData(CONTEXT_OBJECT* ContextObject, PBYTE szBuffer, size_t ulOriginalLength) {
assert(ContextObject);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD>
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);

View File

@@ -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]; // <20>Ա<EFBFBD><D4B1><EFBFBD>Ϣ
Encoder* m_Encoder; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Encoder* m_Encoder2; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>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 {