最近,我考虑使用OnGuard来帮助诚实的人遵守他们的原则。我同意许多人在此表达的观点,即没有许可系统可以保护您免受那些想要使用您的软件并且不想付费的人的影响。另一方面,我想避免让别人为我的程序创建有效密钥太容易。
在研究了手册和示例之后,我在主表单的代码中添加了以下内容:
const
TheKey: TKey = ($4A,$62,$F3,$2B,$9C,$D2,$84,$BF,$CB,$04,$0A,$C3,$3D,$11,$47,$1A);
function TfrmMain1.MakeCode(sName, sNumber: String; dtExpiration: TDate): String;
var Key: TKey;
Code: TCode;
sCode: String;
begin
Key := TheKey;
InitRegCode(Key, sName + ' - ' + sNumber, dtExpiration, Code);
sCode := BufferToHex(Code, SizeOf(Code));
Insert('-', sCode, 13);
Insert('-', sCode, 09);
Insert('-', sCode, 05);
Result := sCode
end;
function TfrmMain1.TestCode(sName, sNumber, sTestCode: String; dtExpiration: TDate): Boolean;
var Key: TKey;
Code: TCode;
sCode: String;
begin
sCode := MakeCode(sName, sNumber, dtExpiration);
Result := SameText(sCode, sTestCode);
end;
这提出了一些问题:
看起来似乎是正确的方法吗?我宁愿不将他们的组件添加到我的表单中。
由于OnGuard源可用,黑客无法对我选择的密钥进行反向工程并生成有效的发布代码吗?因此,我是否应该在代码中添加一些额外的混淆,或者我可能只是削弱系统。
此处将Key设置为常量。它不会在代码中显示为连续的字节并且易于复制吗?
我的计划需要(至少)年度更新,我的计划是每年订阅一次。将年份作为常量添加到我的程序中并在一些地方测试该年份的用户条目是否会更强。
这里有4个问题密切相关且非常具体。看起来在四个单独的条目中询问那些并且必须添加上下文的引用似乎更尴尬但是如果这样做会更好,我将很乐意这样做。谢谢你的帮助。
杰克答案 0 :(得分:2)
constructor TLincenceManager.Create;
begin
FSpecialCode := TOgSpecialCode.Create(nil);
FSpecialCode.OnGetModifier := OgNetCodeGetModifier;
FSpecialCode.OnChecked := OgNetCodeChecked;
FSpecialCode.OnGetCode := OgNetCodeGetCode;
FSpecialCode.OnGetKey := OgNetCodeGetKey;
FSpecialCode.AutoCheck := False;
end;
function TLincenceManager.InitializeLicenceCode: Boolean;
begin
Result := FSpecialCode.CheckCode(True) = ogValidCode;
end;
procedure TLincenceManager.OgNetCodeChecked(Sender: TObject; Status: TCodeStatus);
begin
case Status of
ogValidCode : FMaxUsers := FSpecialCode.GetValue;
ogInvalidCode : FMaxUsers := 0;
ogPastEndDate : FMaxUsers := 0;
ogDayCountUsed : FMaxUsers := 0;
ogRunCountUsed : FMaxUsers := 0;
ogNetCountUsed : FMaxUsers := 0;
ogCodeExpired : FMaxUsers := 0;
else
FMaxUsers := 0;
end;
end;
procedure TLincenceManager.OgNetCodeGetCode(Sender: TObject; var Code: TCode);
var
FileName: string;
SerialData: string;
LicenceData: TStringList;
begin
FileName := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0)));
FileName := FileName + cLicenseFileName;
SerialData := '';
LicenceData := TStringList.Create;
try
if FileExists(FileName) then
begin
LicenceData.LoadFromFile(FileName);
SerialData := LicenceData.Values['Serial'];
end;
{convert to proper form}
HexToBuffer(SerialData, Code, SizeOf(Code));
finally
LicenceData.Free;
end;
end;
procedure TLincenceManager.OgNetCodeGetKey(Sender: TObject; var Key: TKey);
const
CKey : TKey = ($4A,$62,$F3,$2B,$9C,$D2,$84,$BF,$CB,$04,$0A,$C3,$3D,$11,$47,$1A);
begin
Key := CKey;
end;
procedure TLincenceManager.OgNetCodeGetModifier(Sender: TObject; var Value: Integer);
begin
Value := GenerateMachineModifierPrim;
end;
我发布了我的方式。我不使用“视觉”组件。我这样做是要走的路,在你的情况下你只需要应用日期修饰符(我有机器修改器)
理论上没有。您生成许可证的关键是至关重要的。如果您有密钥,则可以破解许可证。但只有代码你不能。这就像加密算法一样。你可以知道算法是如何工作的,但是如果你没有密钥,你就无法破解它。看看XTEA。这很简单,但很难破解。
是的,如果知道正在做什么,可以从二进制中提取密钥。你可以在这里使用某种混淆。但我不会打扰。对于大多数人来说这样的保护就足够了,所以如果你不打造下一个MS Office,我就不会打扰了。人们对他们的产品是偏执狂的。先卖掉它然后再考虑一下。哦,因为它不是一个字符串,反正有点难以找到。
只需查看onGuard附带的计时器演示,了解如何进行限时许可。但请注意,只需简单地操作电脑时钟就足以愚弄它了。在我看来,最好的试用软件就是这样,缺少一些重要的功能(保存按钮......)。在我看来,很难做出好的时间试验。
答案 1 :(得分:2)
我使用较低级别的OnGuard API而不是Runner建议的类。要么工作正常,这些类最终会调用较低级别的API。以下是我对这些低级API方法的包装实用程序函数。
{ Used by you to generate the unlock code you send to your customer, do not include in the customer software }
function GenerateReleaseCode(const inAppKey : string; inExpiryDate : TDateTime; inRegCode : string) : string;
(* inAppKey is the byte sequence key you already have
inRegCode can be anything, typically customers name
Returns the release code for the customer to type into the software *)
var
releaseCode : TCode;
key : TKey;
begin
HexToBuffer(inAppKey, key, SizeOf(TKey));
InitRegCode(key, inRegCode, inExpiryDate, releaseCode);
Result := BufferToHex(unlockCode, SizeOf(releaseCode));
end;
{ Used in your program to authenticate if the release code is valid - does not check for expiry }
function AuthenticateReleaseCode(const inReleaseCodeHexString : string; const inAppKey : TKey) : Boolean;
var
releaseCode : TCode;
begin
HexToBuffer(inReleaseCodeHexString, releaseCode, SizeOf(releaseCode));
Result := IsRegCodeValid(inAppKey, releaseCode);
end;
{ Used in your program to test if the license has expired }
function UnlockCodeExpiryDate(const inReleaseCodeHexString : string; const inAppKey : TKey) : TDateTime;
var
releaseCode : TCode;
begin
HexToBuffer(inReleaseCodeHexString, releaseCode, SizeOf(releaseCode));
Result := GetExpirationDate(inAppKey, releaseCode);
end;
我广泛使用OnGuard,但仅适用于盗版不是这样的企业软件。如果您正在销售消费者软件并且担心盗版,我建议使用更强大的解决方案,例如加密exe的商业版权保护库。
即便如此,你也可以放慢捣蛋鬼的速度,但是你无法阻止它们。
答案 2 :(得分:2)
3)你应该“分散”密钥,并且可能有一部分计算它。更简单的识别密钥,当然更简单的绕过保护。但是,如果适当位置的简单JMP指令绕过整个保护检查,即使是复杂的密钥也是无用的。这些检查也应该不止一次,并且再次分散在各地。
4)小心这类许可证 - 通常用户不喜欢它们,除非年费也意味着一些感知价值(即防病毒软件为您提供更新签名,或GPS应用程序更新地图)。强迫用户每年付费可能看起来不错,但对用户来说却不是这样,即使您添加了他们可能认为不实用的新功能。如果应用程序停止工作更糟糕。当具有相同功能但没有年费的Windows应用程序可用时,这是杀死许多Unix应用程序的问题之一。我知道很多公司都在考虑回归这个模式 - 如果它成功还有待观察。