利用"流"实现exe文件的加密解密

来源:互联网 发布:像上瘾一样的网络剧 编辑:程序博客网 时间:2024/03/29 07:46
 利用"流"实现exe文件的加密解密

  使用本方法加密exe文件时,要先建立两个exe文件,一个用来添加资源到另外一个exe文件里 面,称为添加程序。另一个被添加的exe文件称为头文件,该文件的功能是在解密时把添加到自己里面的文件读出来。加密时,首先建立头文件,再将明文追加到 头文件尾部并设置一个密码,生成密文;解密时,先校验密码,如正确,则将密文从头文件中读出,生成明文,否则报错。为了exe文件的加密,需要建立三个函 数,其原型及功能如下:

  (a)Function Jmf_AddtoFile(SourceFile,PassWord,TargetFile:string):Boolean;
实现分别把文件SoureceFile和字符串PassWord添加到文件TargetFile尾部,如果添加成功就返回True;否则返回false。

  (b)Function Jmf_LoadFromFile(SourceFile,TargetFile:string):Boolean;
实现从SourceFile中取出文件并另保存为TargetFile。如果取出成功返回True,否则返回false。

  (c)Function Jmf_PassFromFile(var Password:string;SourceFile:string):Boolean;
实现从SourceFile中取出密码,保存在Password中。如果取出成功就返回True,否则返回false。
首 先建立头文件。使用Delphi新建一工程,在窗口上放上一个TMaskEdit控件(属性name设置为password)和两个Button控件(属 性name分别为:Unbind和Cancel;属性Caption分别为"解密"和"取消"),并在Unbind的Click事件中写入代码(参见代码 部分),编译此程序生成head.exe头文件,并保留生成的head.res资源文件。

  再建一个工程,添加以下控件:二个 Tedit控件(属性name分别设置为password和position)、一个OpenFileDialog控件、两个Tbutton控件(其中属 性name分别设置为:Select和Encrypt;属性Caption分别设置为"选择文件"和"加密")。在Select的Click事件中实现对 被加密exe文件的选择,在Encrpyt的Click事件中实现将明文和密码追加至head.exe文件结尾,需要注意的是,在该事件处理例程中调用了 ExtractRes函数,其作用是把head.exe从资源文件中提取出来(在源程序中将head.res资源文件跟程序一起编译),生成编译程序生成 可执行文件AddEncrypt.exe。

  在对文件进行加密时,先执行程序AddEncrypt,选择需要加密的exe文件,并在 password中输入加密密码,点击"加密"按钮。源exe文件将被同名密文取代。解密时,执行加密程序,会弹出对话框询问密码,用户输入密码后,如密 码正确则程序正常运行,否则程序将报错,无法运行。需要注意的是,上面的程序只不过简单地把一个文件添加到另一个文件的尾部,实际应用中可改成添加多个文 件,实现过程中只要根据实际大小和个数定义好偏移地址就可以了。因为篇幅有限,文中只给出了源程序的关键代码,有兴趣的读者可自行扩弃完善。源程序清单如 下:

Function Jmf_AddtoFile(SourceFile,PassWord,TargetFile:String):Boolean;
 Var
  Target,Source:TFileStream;
  MyFileSize,PassWordSize:integer;
 Begin
  Try
   Source:=TFileStream.Create(SoureceFile,fmOpenRead or fmShareExclusive);
   Target:=TFileStream.Create(TargetFile,fmOpenWrite of fmShareExclusive);
   Try
    Target.Seek(0,soFromEnd);{往尾部添加资源}
    Target.CopyFrom(Source,0);
    MyFileSize:=Source.Size++Sizeof(MyFileSize);{计算资源大小,并写入辅程尾部}
    Target.WriteBuffer(MyFilesSize,sizefo(MyFileSize));
    PassWordSize:=Sizeof(PassWord)+sizeof(PassWordSize);
    Target.Seek(0,soFromEnd);
    Target.WriteBuffer(PassWord,Sizeof(PassWord));
    Target.WriteBuffer(PassWordSize,sizeof(PassWordSize));
   Finally
    Target.Free;
    Source.Free;
   End;
   Except
    Result:=False;
    Exit;
   End;
  Reslut:=True;
  End; 
Function Jmf_LoadFromFile(SourceFile,TargetFile:string):Boolean;
 Var Source:TFileStream;
  Target:TmemoryStream;
  MyFilesize,Position:integer;
 Begin
  Try
   Target:=TmemoryStream.Create;
   Source:=TFileStream(SourceFile,fmOpenRead or fmShareDenyNone);
   Try
    Source.Seek(-sizeof(Position),soFromEnd);
    Source.ReadBuffer(Position,sizeof(Position));
    Source.Seek(-Position-sizefo(MyFileSize),soFromEnd);
    Source.ReadBuffer(MyFileSize,sizeof(MyFileSize));{读出资源大小}
    Source.Seek(-Position-MyFileSize,soFromEnd);{定位到资源位置}
    Target.CopyFrom(Source,MyFileSize-sizefo(MyFileSize));{取出资源}
    Target.SaveToFile(TargetFile);{存放到文件}
   finally
    Target.Free;
    Source.Free;
   end;
  except
   Result:=false;
   Exit;
  end;
  Result:=true;
 end;

Function Jmf_PassFromFile(var password:string;SourceFile:string):Boolean;
 Var 
  Source:TFileStream;
  PassWordSize:interger;
 Begin
  Try
   Source:=TFileStream.Create(SourceFile,fmOpenRead or fmShareDenyNone);
  Try
   Source.Seek(0,soFromEnd);{定位到资源位置}
   Source.Read(PassWordSize,Sizeof(PassWordSize));
   Source.Seek(-PassWordSize,soFromEnd);
   Source.Read(PassWord,PassWordSize-Sizeof(PassWordSize));
  Finally
   Source.Free;
  End;
  Except
   Result:=false;
  Exit;
 End;
  Result:=true;
 End;

Procedure Tfom1.unbindClick(Sender:TObject);
 Var
  S:string;
  pass,inpass:string;
 begin
  inpass:=password.text;
  S:=ChangeFileExt(Application.ExeName,'Jmf');
  If Jmf_PassFromFile(pass,Application.ExeName) then
   If pass=password.text then
   Begin
    Jmf_LordFromFile(Application.ExeName,S);{取出文件保存在当前路径下并命名"原文件.Jmf"}
    Winexec(pchar(S),SW_Show);{运行"原文件.Jmf"}
    Application.Terminate;{退出程序}
   end
  else
   Application.MessageBox('密码错误,重新输入!','密码错误',MB_OK);
  end;

Procedure Tform1.openClick(Sender:TObject);
 begin
  If OpenDialog1.Execute then position.Text:=OpenDialog1.FileName;
 end;

procedure Tform1.secretClick(Sender:TObject);
 var s:string;
  spass:string;
 begin
  s:=ExtractFilePath(position.text);
  spass:=pass.Text;
  if ExtractRes('exefile','head',s+'head.exe') then
   if Jmf_AddtoFile(position.text,s+'head.exe',spass) then
    if DeleteFile(position.text)then 
     if RenameFile(s+'head.exe',position.text)then
      Application.MessageBox('文件加密成功!!','信息',MB_OK)
     Else
      Begin
       If FileExists(s+'head.exe')
        then DeleteFile(S+'head.exe');
         Application.MessageBox('文件加密失败!!','信息',MB_OK)
       end;

Function ExtractRes(Restype,Resname,ResNewName:string):Boolean;
 Var Res:TresourceStream;
 begin
 try 
  Res:=TresourceStream.Create(Hinstance,Resname,Pchar(ResType));
  try 
   Res.SaveToFile(ResNewName);
   Result:=true;
  Finally
   Res.Free;
  end;
  except
   Result:=False;
 end;
 
小结:
  本文论述了exe文件加密的方法,它的实现原理与文件捆绑机的道理是一致的,就是把两个或者多个程序添加到一个头文件里面,自解压程序和安装程序的原理也是一样的,只需在文件添加和文件读取时,调用解压缩程序就可以了。
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 电信宽带账号登录密码忘记了怎么办 电信校园宽带超时了怎么办 宽带连接账号密码忘了怎么办 移动宽带路由器上不了网怎么办 移动宽带太卡了怎么办 电信adsl密码忘记了怎么办 移动宽带无法连接网络怎么办 移动宽带电视无信号怎么办 联通网线故障电话打不通怎么办 w10系统ip地址错误怎么办 移动流量太贵了怎么办 修改wifi密码ip地址怎么办 苹果6s接电话声音小怎么办 k歌录音器失败怎么办 想报警但不能说话怎么办 微粒贷要家人电话怎么办 4g网络信号差怎么办 手机移动网络信号不好怎么办 移动的4g网络差怎么办 4g移动网络慢怎么办 房间没有4g网络怎么办 oppo显示2g网络怎么办 oppo只有2g网络怎么办 移动卡4g网络慢怎么办 易信专线电话用完了怎么办 手机拨打电话时黑屏怎么办 网易号文章一直审核中怎么办 登陆积分会员忘记密码怎么办 易信密码忘记了怎么办 滴滴永久封停的号怎么办 微信版本过低怎么办 报关时通关单号没录怎么办 公司注销了行政许可证怎么办呢 报关项数超过50项怎么办 出口报关件数报多了怎么办 关税少交被海关缉私查到怎么办 外贸报关hs编码报错怎么办 报关金额少报了怎么办 进口报关金额少报了怎么办 报关重量报少了怎么办 金额报多100倍怎么办