前言
在前两篇的《授权注册-软件保护工具》系列中,介绍了关于授权注册的开发思路、逻辑点以及框架结构、技术点。一个大体框架已搭建,但还有待稳固以及丰富,同时在需求激励的过程中,再次审视框架的完备性、逻辑的合理性,以及适时地重构。
关于这一章的写作的背景,毫无疑问是在新需求——时间策略的激励下,对现有架构的重新审视。发现原有的框架还过于简化、单一,并不能承载时间策略的增加,需要尝试重构,而后加入时间策略。
整个开发过程其实很简单,涉及的技术难度不大(加密算法除外),因为我个人认为授权注册最重要的还是授权逻辑的合理自洽,我喜欢从逻辑的角度解释为“整体逻辑是否是封闭的”。对于破译这个授权码的成本,如果尝试从逻辑角度切入成本是很高的,或者根本可以证明是无法切入的,那么就可以得出结论,这一套授权注册框架是满足最基本也是最关键的需求的。
整体工程结构:
以下是授权注册的整体工程结构,目前开发平台是VS2010+Qt5,但核心库是纯C++,不依赖于Qt框架,所以跨平台的问题不大。
核心库【RegisterCore100】:授权注册的核心库,包含设备唯一识别信息提取、加解密库(可视体量大小进行模块搬移)、注册模块、反射创建授权策略机制、授权时长对象类。主要提供授权注册的核心要素:设备唯一信息提取,授权策略管控。
授权工具【RegisterAuthorTool】:依赖于Qt开发的带界面授权工具,管理员使用。综合现在的一系列需求,涵盖的功能点,简单的界面如下:
其实仅在原来的基础上添加了时间策略。
注册对话框【WarrantDialog】:嵌入到被保护软件的注册API,包含了使用Qt开发的提示界面,在这里是完成逻辑完备性的关键,后面会着重介绍,先给出嵌入到main函数的示例:
WarrantDialog warrantDlg("BA23556B-3BC5-4E8F-B54B-490FBB5733EF");
warrantDlg.InitialUiInfo("", "APP");
WarrantDialog::E_WARRANT_RES eRes = warrantDlg.JudgeAuthorWarrant(); // 判断授权情况
if (eRes < WarrantDialog::E_WARRANT_BEYOUND_DURATION) // 未验证成功则启动验证
{
warrantDlg.DeleteAuthorFile(); // 删除可能存在的授权文件(视为新授权)
warrantDlg.raise();
bool bWarrant = warrantDlg.ExecWarrantDialog();
if (!bWarrant)
{
return -1;
}
}
if (!warrantDlg.IsPermanentAccess()) // 非永久授权则显示持续时长提示
{
warrantDlg.raise();
bool bInfo = warrantDlg.ExecDurationDialog();
if (!bInfo)
{
return -1;
}
}
if (eRes == WarrantDialog::E_WARRANT_BEYOUND_DURATION) // 授权时长超时则清空授权文件(视下次登录需新授权)
{
warrantDlg.DeleteAuthorFile();
return -1;
}
// =======
[被保护软件]
// =======
if (!warrantDlg.RecordQuitAuthorInfo()) // 防止时间篡改导致的记录谬误
{
QMessageBox msgBox(&warrantDlg);
msgBox.setText(QStringLiteral("授权记录有误,视为无效授权。"));
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok); // 破坏授权逻辑,下次登录重新授权
warrantDlg.DeleteAuthorFile();
}
再梳理授权注册逻辑:
较之前版本增加了“时间策略”,且经过重新审视原有架构后,对整体逻辑、流程又有了新的认识,仔细推敲后,做了较大的调整。先上一个脑图描述下,然后介绍体现在API、代码里的逻辑。
*较原版本,将MachineCode和RequestCode的概念分开,增加了VariableCode,与MachineCode共同决定RequestCode。
*其他的增加都是缘于增加时间策略需求而增加的。
从API角度看逻辑
RegisterCore100中的IRegisterModule:提供ISecurityStrategy的反射创建机制,提供机械码生成:
#ifndef IRegisterModule_h__
#define IRegisterModule_h__
#include "RegisterCoreExport.h"
#include <string>
#include <vector>
class ISecurityStrategy;
class REGISTERCORE_EXPORT IRegisterModule
{
public:
virtual ~IRegisterModule(void) {};
// Brief:安全策略版本管控[反射工厂] [2019/11/22 Being]
virtual void GetAllSecurityStrategyVersion(std::vector<const std::string>& vec0) const = 0;
virtual ISecurityStrategy* CreateSecurityStrategy(const std::string& strVersion) = 0;
virtual bool IsExistSecurityStrategy(const std::string& strVersion) const = 0;
virtual void DestroySecurityStrategy(ISecurityStrategy* pStrategy) = 0;
// Brief:机械码统一生成 [2019/11/22 Being]
virtual std::string GenerateMachineCode() = 0;
};
extern REGISTERCORE_EXPORT IRegisterModule* GetGlobalRegisterModule();
extern REGISTERCORE_EXPORT void DestroyGlobalRegisterModule();
#endif // IRegisterModule_h_
与原版本改动最大的是ISecurityStrategy接口部分:
#ifndef ISecurityStrategy_h__
#define ISecurityStrategy_h__
#include "RegisterCoreExport.h"
#include <string>
class REGISTERCORE_EXPORT ISecurityStrategy
{
public:
virtual ~ISecurityStrategy() {}
public: // Brief:策略基本信息 [2020/1/14 Being]
virtual std::string GetStrategyVersion() = 0;
virtual std::string GetStrategyName() const = 0;
virtual std::string GetStrategyDescription() const = 0;
public: // Brief:请求码生成 [2020/1/14 Being]
virtual void SetMachineCode(const std::string& strRequestCode) = 0;
virtual std::string GetMachineCode() const = 0;
virtual void SetVolatileFlag(const std::string& strVolatile) = 0;
virtual std::string GetVolatileFlag() const = 0;
virtual std::string CombineAsRequestCode() const = 0;
public: // Brief:注册码(包含注册时长)生成 [2020/1/14 Being]
virtual void SetDurationMinute(int nDurationMinute) = 0;
virtual int GetDurationMinute() const = 0;
virtual std::string GenerateRegisterCode(const std::string& strRequestCode) = 0;
virtual int AnalyseDuration(const std::string& strRegisterCode) = 0;
};
#endif // ISecurityStrategy_h__
总结
到目前为止,可以作为注册机 2.0 Beta版本发表使用,满足当前的需求。当然,个人的知识水平也还有限,并没有做到我所希望的“逻辑完全闭合”,仍然是可以有切口可以突破整体逻辑的,不过还没有推出过大的逻辑谬误。还是同样的希望,各位读者若发现明显逻辑谬误,欢迎积极讨论,共同精进。