以前搞过很多小软件,除了收费的软件做了保护模块,一般免费的软件,公司内部用的软件我都没有添加保护模块。
保护模块主要的作用是:对程序自身进行保护,防止别人修改或破解,如果发现程序被修改过就自动中止,最暴力的是程序发生自己被修改后就启动自毁模块,自己删除自己,哈哈。
常用的方法是加壳,以前还专门买了一套加壳软件Zprotect,不过现在这个软件基本已经销声敛迹了。我一般用aspack压缩一下资源,把程序变小一点,方便进行网络传输。
可以通过文件大小来进行判断是否被修改,当然这种方法相比比较简单,适合不加壳的软件,比较弱,修改字节也能保持文件大小不变,所以这种方法不能做到严格意义上的自我保护。
最近研究了一下,可以通过在线验证MD5值,每个程序的MD5指纹都不一样,只要修改过一个字节,MD5指纹就会发现变化,通过这样的思路来进行验证程序是否被修改。
第一种方法:将文件大小保存在程序里进行验证
program Project1;
uses
Forms, Windows,
Classes,
SysUtils,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
var
ExeStream: TMemoryStream;
const
ExeSize = 10000; //你事先测定的程序的长度
begin
Application.Initialize;
ExeStream := TMemoryStream.Create;
ExeStream.LoadFromFile(Application.ExeName);
if ExeStream.Size <> ExeSize then begin
Application.MessageBox('本程序被修改了!无法使用了!','程序被修改',MB_ICONERROR);
Exit;
end;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
第二种方法:通过MD5指纹验证程序是否被修改,获取程序自行的MD5指纹,从服务器http://192.168.100.1/MD5.txt获取程序最新的指纹信息,对程序进行校验检查,如果发现程序被修改或被病毒感染,则自动退出。
use IdHashMessageDigest,IdGlobal,IdHash;
//检查程序是否被修改
function Sa_CheckMyAPP:Boolean;
var myversion:string;
filesen:TFileStream;
appmd5str:string;
MD5Encode:TMD5;
long:T4x4LongWordRecord;
begin
//获取文件自身的MD5值
try
filesen:=TFileStream.Create(Application.ExeName,fmopenread or fmshareExclusive);
MD5Encode:=TMD5.Create;
long:=md5encode.HashValue(filesen);
appmd5str:=Trim(MD5Encode.AsHex(long));
finally
MD5Encode.Free;
filesen.Free;
end;
try
myversion:= Trim(Sa_GetUrlSource('http://192.168.100.1/MD5.txt'));
if UpperCase(myversion)<>UpperCase(appmd5str) then
begin
ShowMessage(‘程序被修改’);
ShellExecute(Application.Handle, nil, 'http://192.168.100.1/', nil, nil, SW_SHOWNORMAL);
Application.Terminate;
end;
except
end;
end;
//获取网页内容
function Sa_GetUrlSource(surl: string): string;
var htmlsrc:string;
HttpClient: THttpCli; // ICS的网络组件
DataLen: Int64;
FailMsg: string;
begin
HttpClient := THttpCli.Create(nil);
HttpClient.URL := surl;
HttpClient.RcvdStream := TMemoryStream.Create; // 创建TMemoryStream
try
Application.ProcessMessages;
try
HttpClient.Timeout:=5000;
HttpClient.Get;
DataLen := HttpClient.RcvdStream.Size;
SetLength(htmlsrc, DataLen);
HttpClient.RcvdStream.Position := 0;
HttpClient.RcvdStream.Read(PChar(htmlsrc)^, DataLen);
htmlsrc:=UTF8Decode(htmlsrc);
htmlsrc:=StringReplace(htmlsrc,'"','"',[rfReplaceAll]);
Result := htmlsrc;
except
Result:='';
end;
finally
HttpClient.RcvdStream.Free;
HttpClient.RcvdStream := nil;
HttpClient.Free;
end;
end;