一、概述 软件作为一种人类智力劳动成果的一种表现形式,融会了设计者和开发者辛勤的劳动和汗水,然而,由于用户观念上的差异和盗版软件的泛滥,软件开发者的权益往往得不到有效的保护,因此,作为必要的手段-----软件的自身保护也就在特定的环境下被重视起来。 然而,正所谓,“魔高一尺,道高一丈”,保护和破解的矛盾关系在始终持续着,要想找到一种万能的保护方法,却也不是那么简单的事。但是,如果开发者使用的保护手段连一般用户都能破解的话(如:修改系统日期),这样的保护则显然达不到保护软件版权的目的。 基于此,笔者利用Delphi5.0面向对象的特性,设计开发了一个实用的版权保护控件,以为程序开发者提供一种简易的软件保护手段。 二、实现方法 1.在Delphi5.0中新建一个单元文件,书写代码如下,保存: unit RegObj;
interface
uses Windows, Messages, SysUtils, Classes, Forms;
type TRegObj = class private FSerial: string; //主板序列号 FKey: string; //密码 FMaxTimes: Integer; //最大运行次数 FCompany: string; //公司名称 FEmail: string; //联系用的电子邮件 protected procedure SetSerial; //取得主扳的序列号 procedure GetKey; //从用户序列号文件中读取序列号 function GetTimes: Integer; //从文件中读取程序的运行次数 function CheckKey: Boolean; //检查序列号和密码是否匹配的函数 public constructor Create; function Execute: Boolean; //运行对象方法 published property Company: string read FCompany write FCompany; property MaxTimes: Integer read FMaxTimes write FMaxTimes; property Email: string read FEmail write FEmail; end;
implementation
//TRegObj. constructor TRegObj.Create; begin inherited; end;
function TRegObj.GetTimes: Integer; Const //用于存储运行次数的文件,开发人员可自定义或使用注册表存储运行次数 //起此名字用于迷惑破解者,使用前不要和系统的动态链接库同名 Tmp = 'ispnet.dll'; var Ch: Char; Dir: array [0..255] of Char; Fn: string; I : Integer; List: Tstrings; begin //取得Windows系统的目录 GetSystemDirectory(@Dir, 255); For I := 0 to 255 do begin if Ord(Dir[I]) = 0 then Break; Fn := Fn + Dir[I]; end; Fn := Fn + '\' + Tmp; try List := TStringList.Create; if Not FileExists(Fn) then Ch := Chr(1) else begin List.LoadFromFile(Fn); Ch := List.Text[1]; Ch := Chr(Ord(Ch) + 1); end; List.Text := Ch; //存储运行次数 List.SaveToFile(Fn); Result := Ord(Ch); finally List.Free; end; end;
procedure TRegObj.SetSerial; begin //取得主板的序列号 FSerial := String(Pchar(Ptr($FEC71))); end;
//取得密码 procedure TRegObj.GetKey; const Sn = 'Key.dat'; var List: TStrings; Fn, Path: string; begin Path := ExtractFilePath(Application.ExeName); Fn := Path + Sn; if Not FileExists(Fn) then begin FKey := ''; Exit; end; try List := TStringList.Create; List.LoadFromFile(Fn); FKey := List.Values['Key']; finally List.Free; end; end;
function TRegObj.CheckKey: Boolean; begin //开发人员根据自己的需要进行修改,在这里是为了简单起见 Result := FKey = FSerial; end;
function TRegObj.Execute: Boolean; var Msg: string; T: Integer; begin T := GetTimes; GetKey; SetSerial; if FKey <> FSerial then begin Msg := ' 您这是第' + IntToStr(T) + '次运行此程序(最大次数:' + IntToStr(FMaxTimes) + ')!'; Application.MessageBox(PChar(Msg), '用户信息', Mb_Ok + Mb_IconWarning); Msg := '欢迎使用' + Company + '的软件,如果您觉得满意的话,请注册或购买正版软件!'; Application.MessageBox(PChar(Msg), '建议', Mb_Ok + Mb_IconInformation); if T > FMaxTimes then begin if Application.MessageBox(' 是否注册?', '注册', Mb_YesNo + Mb_IconQuestion) = Id_Yes then begin Msg := '您的注册号是:“' + FSerial + '”' + Chr(13) + Chr(10) + '请您将以上序列号通过电子邮件寄给以下信箱:' + FEmail; Application.MessageBox(PChar(Msg), '软件 注册', Mb_Ok + Mb_Iconinformation); end; Application.Terminate; end; end; end;
end. 2.控件的使用 在Delphi5.0中新建一个应用程序,在程序的引用单元中加入上述单元的引用,在主窗体的OnCreate事件中编写如下代码: procedure TForm1.FormCreate(Sender: TObject); var AObj: TRegObj; begin try AObj := TRegObj.Create; AObj.MaxTimes := 30; AObj.Company := '吉星软件工作室'; AObj.Email := 'test@1112.net'; AObj.Execute; finally AObj.Free; end; end; 三、结束语 上述控件通过取得用户计算机的主板序列号作为注册码,通过文件存储程序运行次数和密钥,防止了同样的注册码和密钥在不同的计算机上都可以使用的问题,而且,用户通过简单的日期修改无法使程序继续,基本达到了软件版权保护的目的。 |