Release v1.1.3
This commit is contained in:
16
ReadMe.md
16
ReadMe.md
@@ -273,6 +273,22 @@
|
|||||||
* 插件:#145 支持远程画板功能
|
* 插件:#145 支持远程画板功能
|
||||||
* 插件:增加远程桌面隐私屏幕功能
|
* 插件:增加远程桌面隐私屏幕功能
|
||||||
|
|
||||||
|
**2025.07.19**
|
||||||
|
|
||||||
|
Release v1.1.3
|
||||||
|
|
||||||
|
- 添加加密和解密函数
|
||||||
|
- 修改弹出消息为通过 `NM_DBLCLK` 触发
|
||||||
|
- 改进:将 DLL 数据保存到注册表中
|
||||||
|
- 新功能:支持 HTTP 协议并添加构建选项
|
||||||
|
- 新功能:为客户端构建添加加密选项
|
||||||
|
- 改进:减少鼠标移动消息的传输
|
||||||
|
- 修复:在操作高权限窗口时失去控制的问题
|
||||||
|
- 改进:通过异常处理提升客户端稳定性
|
||||||
|
- 新功能:远程桌面支持多显示器
|
||||||
|
- 改进:支持授权在线主机数量
|
||||||
|
- 修复:#159 在 TestRun 注入模式下授权无效的问题
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# 6.其他项目 <a id="6-other-projects"></a>
|
# 6.其他项目 <a id="6-other-projects"></a>
|
||||||
|
|||||||
16
ReadMe_EN.md
16
ReadMe_EN.md
@@ -290,6 +290,22 @@ Release v1.1.2:
|
|||||||
* Plugin: #145 Support remote drawing board
|
* Plugin: #145 Support remote drawing board
|
||||||
* Plugin: Add remote desktop privacy screen feature
|
* Plugin: Add remote desktop privacy screen feature
|
||||||
|
|
||||||
|
**2025.07.19**
|
||||||
|
|
||||||
|
Release v1.1.3
|
||||||
|
|
||||||
|
* Add encrypt and decrypt functions
|
||||||
|
* Modify the popup message to be triggered by `NM_DBLCLK`
|
||||||
|
* Improve: Save DLL data to registry
|
||||||
|
* Feature: Support HTTP protocol and add building option
|
||||||
|
* Feature: Add encryption option for client building
|
||||||
|
* Improvement: Reduce transmit mouse move message
|
||||||
|
* fix: Lost control when operating high permission windows
|
||||||
|
* Improve client stability by handling exceptions
|
||||||
|
* feature: Remote desktop support multi monitor
|
||||||
|
* Improve: Support authorizing the online host quantity
|
||||||
|
* fix:#159 Authorization doesn't work under TestRun injection
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# 6. Related Projects
|
# 6. Related Projects
|
||||||
|
|||||||
BIN
Releases/v1.1.3/Yama.exe
Normal file
BIN
Releases/v1.1.3/Yama.exe
Normal file
Binary file not shown.
@@ -233,8 +233,9 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
|||||||
HANDLE hMutex = OpenMutex(SYNCHRONIZE, FALSE, "MASTER.EXE");
|
HANDLE hMutex = OpenMutex(SYNCHRONIZE, FALSE, "MASTER.EXE");
|
||||||
hMutex = hMutex ? hMutex : OpenMutex(SYNCHRONIZE, FALSE, "YAMA.EXE");
|
hMutex = hMutex ? hMutex : OpenMutex(SYNCHRONIZE, FALSE, "YAMA.EXE");
|
||||||
#ifndef _DEBUG
|
#ifndef _DEBUG
|
||||||
if (hMutex == NULL) // û<>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD>
|
if (hMutex == NULL) { // û<>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD>
|
||||||
break;
|
Mprintf("!!! [WARN] Master program is not running.\n");
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
CloseHandle(hMutex);
|
CloseHandle(hMutex);
|
||||||
|
|
||||||
@@ -244,14 +245,19 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
|||||||
const char* pwdHash = m_conn->pwdHash[0] ? m_conn->pwdHash : masterHash.c_str();
|
const char* pwdHash = m_conn->pwdHash[0] ? m_conn->pwdHash : masterHash.c_str();
|
||||||
if (passCode[0] == 0) {
|
if (passCode[0] == 0) {
|
||||||
std::string devId = getDeviceID();
|
std::string devId = getDeviceID();
|
||||||
|
memcpy(buf + 24, buf + 12, 8); // <20><>Ϣǩ<CFA2><C7A9>
|
||||||
|
memcpy(buf + 96, buf + 8, 4); // ʱ<><CAB1><EFBFBD><EFBFBD>
|
||||||
memcpy(buf + 5, devId.c_str(), devId.length()); // 16<31>ֽ<EFBFBD>
|
memcpy(buf + 5, devId.c_str(), devId.length()); // 16<31>ֽ<EFBFBD>
|
||||||
memcpy(buf + 32, pwdHash, 64); // 64<36>ֽ<EFBFBD>
|
memcpy(buf + 32, pwdHash, 64); // 64<36>ֽ<EFBFBD>
|
||||||
m_ClientObject->Send2Server((char*)buf, sizeof(buf));
|
m_ClientObject->Send2Server((char*)buf, sizeof(buf));
|
||||||
|
Mprintf("Request for authorization update.\n");
|
||||||
} else {
|
} else {
|
||||||
int* days = (int*)(buf + 1);
|
unsigned short* days = (unsigned short*)(buf + 1);
|
||||||
|
unsigned short* num = (unsigned short*)(buf + 3);
|
||||||
config* cfg = pwdHash == masterHash ? new config : new iniFile;
|
config* cfg = pwdHash == masterHash ? new config : new iniFile;
|
||||||
cfg->SetStr("settings", "Password", *days <= 0 ? "" : passCode);
|
cfg->SetStr("settings", "Password", *days <= 0 ? "" : passCode);
|
||||||
cfg->SetStr("settings", "HMAC", *days <= 0 ? "" : buf + 64);
|
cfg->SetStr("settings", "HMAC", *days <= 0 ? "" : buf + 64);
|
||||||
|
Mprintf("Update authorization: %s, HMAC: %s\n", passCode, buf+64);
|
||||||
delete cfg;
|
delete cfg;
|
||||||
g_bExit = S_SERVER_EXIT;
|
g_bExit = S_SERVER_EXIT;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ IDR_WAVE WAVE "Res\\msg.wav"
|
|||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,0,1,2
|
FILEVERSION 1,0,1,3
|
||||||
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.2"
|
VALUE "FileVersion", "1.0.1.3"
|
||||||
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"
|
||||||
|
|||||||
Binary file not shown.
@@ -948,7 +948,7 @@ BOOL CMy2015RemoteDlg::OnInitDialog()
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
SetTimer(TIMER_CHECK, 60 * 1000, NULL);
|
SetTimer(TIMER_CHECK, 10 * 1000, NULL);
|
||||||
#else
|
#else
|
||||||
SetTimer(TIMER_CHECK, 600 * 1000, NULL);
|
SetTimer(TIMER_CHECK, 600 * 1000, NULL);
|
||||||
#endif
|
#endif
|
||||||
@@ -1464,11 +1464,7 @@ std::string joinString(const std::vector<std::string>& tokens, char delimiter) {
|
|||||||
|
|
||||||
bool CMy2015RemoteDlg::CheckValid(int trail) {
|
bool CMy2015RemoteDlg::CheckValid(int trail) {
|
||||||
DateVerify verify;
|
DateVerify verify;
|
||||||
#ifdef _DEBUG
|
|
||||||
BOOL isTrail = verify.isTrail(0);
|
|
||||||
#else
|
|
||||||
BOOL isTrail = verify.isTrail(trail);
|
BOOL isTrail = verify.isTrail(trail);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!isTrail) {
|
if (!isTrail) {
|
||||||
const Validation *verify = GetValidation();
|
const Validation *verify = GetValidation();
|
||||||
@@ -1845,13 +1841,32 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
|
|||||||
if (n < 100) break;
|
if (n < 100) break;
|
||||||
char resp[100] = { 0 }, *devId = resp + 5, *pwdHash = resp + 32;
|
char resp[100] = { 0 }, *devId = resp + 5, *pwdHash = resp + 32;
|
||||||
ContextObject->InDeCompressedBuffer.CopyBuffer(resp, min(n, sizeof(resp)), 0);
|
ContextObject->InDeCompressedBuffer.CopyBuffer(resp, min(n, sizeof(resp)), 0);
|
||||||
int *days = (int*)(resp+1);
|
unsigned short* days = (unsigned short*)(resp + 1);
|
||||||
if (devId[0] == 0 || pwdHash[0] == 0)break;
|
unsigned short* num = (unsigned short*)(resp + 3);
|
||||||
// 密码形式:20250209 - 20350209: SHA256
|
BYTE msg[12] = {};
|
||||||
std::string hash = pwdHash;
|
memcpy(msg, resp, 5);
|
||||||
std::string password = getDateStr(0) + " - " + getDateStr(*days) + ": " + pwdHash;
|
memcpy(msg+8, resp+96, 4);
|
||||||
std::string finalKey = deriveKey(password, devId);
|
uint32_t now = clock();
|
||||||
std::string fixedKey = getDateStr(0) + std::string("-") + getDateStr(*days) + std::string("-") + getFixedLengthID(finalKey);
|
uint32_t tm = *(uint32_t*)(resp + 96);
|
||||||
|
if (now < tm || now - tm > 30000) {
|
||||||
|
Mprintf("Get authorization timeout[%s], devId: %s, pwdHash:%s", ContextObject->PeerName.c_str(),
|
||||||
|
devId, pwdHash);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
uint64_t signature = *(uint64_t*)(resp + 24);
|
||||||
|
if (devId[0] == 0 || pwdHash[0] == 0 || !VerifyMessage(m_superPass, msg, sizeof(msg), signature)){
|
||||||
|
Mprintf("Get authorization failed[%s], devId: %s, pwdHash:%s\n", ContextObject->PeerName.c_str(),
|
||||||
|
devId, pwdHash);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
char hostNum[10] = {};
|
||||||
|
sprintf(hostNum, "%04d", *num);
|
||||||
|
// 密码形式:20250209 - 20350209: SHA256: HostNum
|
||||||
|
std::string hash = std::string(pwdHash, pwdHash+64);
|
||||||
|
std::string password = getDateStr(0) + " - " + getDateStr(*days) + ": " + hash + ": " + hostNum;
|
||||||
|
std::string finalKey = deriveKey(password, std::string(devId, devId+19));
|
||||||
|
std::string fixedKey = getDateStr(0) + std::string("-") + getDateStr(*days) + "-" + hostNum +
|
||||||
|
std::string("-") + getFixedLengthID(finalKey);
|
||||||
memcpy(devId, fixedKey.c_str(), fixedKey.length());
|
memcpy(devId, fixedKey.c_str(), fixedKey.length());
|
||||||
devId[fixedKey.length()] = 0;
|
devId[fixedKey.length()] = 0;
|
||||||
std::string hmac = genHMAC(hash, m_superPass);
|
std::string hmac = genHMAC(hash, m_superPass);
|
||||||
@@ -2726,11 +2741,19 @@ void CMy2015RemoteDlg::OnOnlineAuthorize()
|
|||||||
|
|
||||||
CInputDialog dlg(this);
|
CInputDialog dlg(this);
|
||||||
dlg.Init("延长授权", "主控程序授权天数:");
|
dlg.Init("延长授权", "主控程序授权天数:");
|
||||||
|
dlg.Init2("并发上线机器数量:", std::to_string(100).c_str());
|
||||||
if (dlg.DoModal() != IDOK || atoi(dlg.m_str) <= 0)
|
if (dlg.DoModal() != IDOK || atoi(dlg.m_str) <= 0)
|
||||||
return;
|
return;
|
||||||
BYTE bToken[32] = { CMD_AUTHORIZATION };
|
BYTE bToken[32] = { CMD_AUTHORIZATION };
|
||||||
int days = atoi(dlg.m_str);
|
unsigned short days = atoi(dlg.m_str);
|
||||||
|
unsigned short num = atoi(dlg.m_sSecondInput);
|
||||||
|
uint32_t tm = clock();
|
||||||
|
// 2字节天数+2字节主机数+4字节时间戳+消息签名
|
||||||
memcpy(bToken+1, &days, sizeof(days));
|
memcpy(bToken+1, &days, sizeof(days));
|
||||||
|
memcpy(bToken+3, &num, sizeof(num));
|
||||||
|
memcpy(bToken + 8, &tm, sizeof(tm));
|
||||||
|
uint64_t signature = SignMessage(m_superPass, bToken, 12);
|
||||||
|
memcpy(bToken + 12, &signature, sizeof(signature));
|
||||||
SendSelectedCommand(bToken, sizeof(bToken));
|
SendSelectedCommand(bToken, sizeof(bToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2814,8 +2837,15 @@ void CMy2015RemoteDlg::OnOnlineUnauthorize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
BYTE bToken[32] = { CMD_AUTHORIZATION };
|
BYTE bToken[32] = { CMD_AUTHORIZATION };
|
||||||
int days = -1;
|
unsigned short days = 0;
|
||||||
|
unsigned short num = 1;
|
||||||
|
uint32_t tm = clock();
|
||||||
|
// 2字节天数+2字节主机数+4字节时间戳+消息签名
|
||||||
memcpy(bToken + 1, &days, sizeof(days));
|
memcpy(bToken + 1, &days, sizeof(days));
|
||||||
|
memcpy(bToken + 3, &num, sizeof(num));
|
||||||
|
memcpy(bToken + 8, &tm, sizeof(tm));
|
||||||
|
uint64_t signature = SignMessage(m_superPass, bToken, 12);
|
||||||
|
memcpy(bToken + 12, &signature, sizeof(signature));
|
||||||
SendSelectedCommand(bToken, sizeof(bToken));
|
SendSelectedCommand(bToken, sizeof(bToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1778,7 +1778,8 @@ void CFileManagerDlg::WriteLocalRecvFile()
|
|||||||
}
|
}
|
||||||
if (i == MAX_WRITE_RETRY && nRet <= 0)
|
if (i == MAX_WRITE_RETRY && nRet <= 0)
|
||||||
{
|
{
|
||||||
::MessageBox(m_hWnd, m_strReceiveLocalFile + " <20>ļ<EFBFBD>д<EFBFBD><D0B4>ʧ<EFBFBD><CAA7>", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", MB_OK|MB_ICONWARNING);
|
::MessageBox(m_hWnd, m_strReceiveLocalFile + " <20>ļ<EFBFBD>д<EFBFBD><D0B4>ʧ<EFBFBD><CAA7>!", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", MB_OK|MB_ICONWARNING);
|
||||||
|
m_bIsStop = true;
|
||||||
}
|
}
|
||||||
CloseHandle(hFile);
|
CloseHandle(hFile);
|
||||||
// Ϊ<>˱Ƚϣ<C8BD><CFA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
// Ϊ<>˱Ƚϣ<C8BD><CFA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ IMPLEMENT_DYNAMIC(CInputDialog, CDialogEx)
|
|||||||
|
|
||||||
CInputDialog::CInputDialog(CWnd* pParent /*=nullptr*/)
|
CInputDialog::CInputDialog(CWnd* pParent /*=nullptr*/)
|
||||||
: CDialogEx(IDD_DIALOG_INPUT, pParent)
|
: CDialogEx(IDD_DIALOG_INPUT, pParent)
|
||||||
|
, m_sSecondInput(_T(""))
|
||||||
{
|
{
|
||||||
m_hIcon = NULL;
|
m_hIcon = NULL;
|
||||||
}
|
}
|
||||||
@@ -23,6 +24,10 @@ CInputDialog::~CInputDialog()
|
|||||||
void CInputDialog::DoDataExchange(CDataExchange* pDX)
|
void CInputDialog::DoDataExchange(CDataExchange* pDX)
|
||||||
{
|
{
|
||||||
CDialogEx::DoDataExchange(pDX);
|
CDialogEx::DoDataExchange(pDX);
|
||||||
|
DDX_Control(pDX, IDC_STATIC_SECOND, m_Static2thInput);
|
||||||
|
DDX_Control(pDX, IDC_EDIT_SECOND, m_Edit2thInput);
|
||||||
|
DDX_Text(pDX, IDC_EDIT_SECOND, m_sSecondInput);
|
||||||
|
DDV_MaxChars(pDX, m_sSecondInput, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -39,6 +44,11 @@ BOOL CInputDialog::Init(LPCTSTR caption, LPCTSTR prompt) {
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CInputDialog::Init2(LPCTSTR name, LPCTSTR defaultValue) {
|
||||||
|
m_sItemName = name;
|
||||||
|
m_sSecondInput = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL CInputDialog::OnInitDialog()
|
BOOL CInputDialog::OnInitDialog()
|
||||||
{
|
{
|
||||||
CDialogEx::OnInitDialog();
|
CDialogEx::OnInitDialog();
|
||||||
@@ -47,6 +57,11 @@ BOOL CInputDialog::OnInitDialog()
|
|||||||
|
|
||||||
SetWindowText(m_sCaption);
|
SetWindowText(m_sCaption);
|
||||||
GetDlgItem(IDC_STATIC)->SetWindowText(m_sPrompt);
|
GetDlgItem(IDC_STATIC)->SetWindowText(m_sPrompt);
|
||||||
|
|
||||||
|
m_Static2thInput.SetWindowTextA(m_sItemName);
|
||||||
|
m_Static2thInput.ShowWindow(m_sItemName.IsEmpty() ? SW_HIDE : SW_SHOW);
|
||||||
|
m_Edit2thInput.SetWindowTextA(m_sSecondInput);
|
||||||
|
m_Edit2thInput.ShowWindow(m_sItemName.IsEmpty() ? SW_HIDE : SW_SHOW);
|
||||||
|
|
||||||
return TRUE; // return TRUE unless you set the focus to a control
|
return TRUE; // return TRUE unless you set the focus to a control
|
||||||
// 异常: OCX 属性页应返回 FALSE
|
// 异常: OCX 属性页应返回 FALSE
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ public:
|
|||||||
|
|
||||||
BOOL Init(LPCTSTR caption, LPCTSTR prompt);
|
BOOL Init(LPCTSTR caption, LPCTSTR prompt);
|
||||||
|
|
||||||
|
void Init2(LPCTSTR name, LPCTSTR defaultValue);
|
||||||
|
|
||||||
// 对话框数据
|
// 对话框数据
|
||||||
#ifdef AFX_DESIGN_TIME
|
#ifdef AFX_DESIGN_TIME
|
||||||
enum { IDD = IDD_DIALOG_INPUT };
|
enum { IDD = IDD_DIALOG_INPUT };
|
||||||
@@ -32,4 +34,8 @@ public:
|
|||||||
CString m_str;
|
CString m_str;
|
||||||
virtual BOOL OnInitDialog();
|
virtual BOOL OnInitDialog();
|
||||||
afx_msg void OnBnClickedOk();
|
afx_msg void OnBnClickedOk();
|
||||||
|
CStatic m_Static2thInput;
|
||||||
|
CEdit m_Edit2thInput;
|
||||||
|
CString m_sItemName;
|
||||||
|
CString m_sSecondInput;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1423,14 +1423,17 @@ void CFileManagerDlg::WriteLocalRecvFile()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i == MAX_WRITE_RETRY && !bResult) {
|
if (i == MAX_WRITE_RETRY && !bResult) {
|
||||||
::MessageBox(m_hWnd, m_strReceiveLocalFile + _T(" <20>ļ<EFBFBD>д<EFBFBD><D0B4>ʧ<EFBFBD><CAA7>"), _T("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"), MB_OK | MB_ICONWARNING);
|
::MessageBox(m_hWnd, m_strReceiveLocalFile + _T(" <20>ļ<EFBFBD>д<EFBFBD><D0B4>ʧ<EFBFBD><CAA7>!"), _T("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"), MB_OK | MB_ICONWARNING);
|
||||||
|
m_bIsStop = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dwOffsetLow = 0;
|
||||||
|
dwOffsetHigh = 0;
|
||||||
|
dwOffsetLow = SetFilePointer(m_hFileRecv, dwOffsetLow, &dwOffsetHigh, FILE_CURRENT);
|
||||||
|
// Ϊ<>˱Ƚϣ<C8BD><CFA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
m_nCounter += dwBytesWrite;
|
||||||
|
ShowProgress();
|
||||||
}
|
}
|
||||||
dwOffsetLow = 0;
|
|
||||||
dwOffsetHigh = 0;
|
|
||||||
dwOffsetLow = SetFilePointer(m_hFileRecv, dwOffsetLow, &dwOffsetHigh, FILE_CURRENT);
|
|
||||||
// Ϊ<>˱Ƚϣ<C8BD><CFA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
m_nCounter += dwBytesWrite;
|
|
||||||
ShowProgress();
|
|
||||||
}
|
}
|
||||||
if (m_bIsStop)
|
if (m_bIsStop)
|
||||||
SendStop(TRUE);
|
SendStop(TRUE);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "common/commands.h"
|
#include "common/commands.h"
|
||||||
|
|
||||||
#pragma comment(lib, "Advapi32.lib")
|
#pragma comment(lib, "Advapi32.lib")
|
||||||
|
#pragma comment(lib, "bcrypt.lib")
|
||||||
|
|
||||||
// ִ<><D6B4>ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD><EEA3AC>ȡӲ<C8A1><D3B2><EFBFBD><EFBFBD>Ϣ
|
// ִ<><D6B4>ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD><EEA3AC>ȡӲ<C8A1><D3B2><EFBFBD><EFBFBD>Ϣ
|
||||||
std::string execCommand(const char* cmd) {
|
std::string execCommand(const char* cmd) {
|
||||||
@@ -143,3 +144,61 @@ std::string getDeviceID() {
|
|||||||
std::string deviceID = getFixedLengthID(hashedID);
|
std::string deviceID = getFixedLengthID(hashedID);
|
||||||
return deviceID;
|
return deviceID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t SignMessage(const std::string& pwd, BYTE* msg, int len) {
|
||||||
|
BCRYPT_ALG_HANDLE hAlg = nullptr;
|
||||||
|
BCRYPT_HASH_HANDLE hHash = nullptr;
|
||||||
|
BYTE hash[32]; // SHA256 = 32 bytes
|
||||||
|
DWORD hashObjectSize = 0;
|
||||||
|
DWORD dataLen = 0;
|
||||||
|
PBYTE hashObject = nullptr;
|
||||||
|
uint64_t result = 0;
|
||||||
|
|
||||||
|
if (BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA256_ALGORITHM, nullptr, BCRYPT_ALG_HANDLE_HMAC_FLAG) != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, (PUCHAR)&hashObjectSize, sizeof(DWORD), &dataLen, 0) != 0) {
|
||||||
|
BCryptCloseAlgorithmProvider(hAlg, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hashObject = (PBYTE)HeapAlloc(GetProcessHeap(), 0, hashObjectSize);
|
||||||
|
if (!hashObject) {
|
||||||
|
BCryptCloseAlgorithmProvider(hAlg, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BCryptCreateHash(hAlg, &hHash, hashObject, hashObjectSize,
|
||||||
|
(PUCHAR)pwd.data(), static_cast<ULONG>(pwd.size()), 0) != 0) {
|
||||||
|
HeapFree(GetProcessHeap(), 0, hashObject);
|
||||||
|
BCryptCloseAlgorithmProvider(hAlg, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BCryptHashData(hHash, msg, len, 0) != 0) {
|
||||||
|
BCryptDestroyHash(hHash);
|
||||||
|
HeapFree(GetProcessHeap(), 0, hashObject);
|
||||||
|
BCryptCloseAlgorithmProvider(hAlg, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BCryptFinishHash(hHash, hash, sizeof(hash), 0) != 0) {
|
||||||
|
BCryptDestroyHash(hHash);
|
||||||
|
HeapFree(GetProcessHeap(), 0, hashObject);
|
||||||
|
BCryptCloseAlgorithmProvider(hAlg, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&result, hash, sizeof(result));
|
||||||
|
|
||||||
|
BCryptDestroyHash(hHash);
|
||||||
|
HeapFree(GetProcessHeap(), 0, hashObject);
|
||||||
|
BCryptCloseAlgorithmProvider(hAlg, 0);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VerifyMessage(const std::string& pwd, BYTE* msg, int len, uint64_t signature) {
|
||||||
|
uint64_t computed = SignMessage(pwd, msg, len);
|
||||||
|
return computed == signature;
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,3 +16,8 @@ std::string getFixedLengthID(const std::string& hash);
|
|||||||
std::string deriveKey(const std::string& password, const std::string& hardwareID);
|
std::string deriveKey(const std::string& password, const std::string& hardwareID);
|
||||||
|
|
||||||
std::string getDeviceID();
|
std::string getDeviceID();
|
||||||
|
|
||||||
|
// Use HMAC to sign a message.
|
||||||
|
uint64_t SignMessage(const std::string& pwd, BYTE* msg, int len);
|
||||||
|
|
||||||
|
bool VerifyMessage(const std::string& pwd, BYTE* msg, int len, uint64_t signature);
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user