首页  编辑  

Delphi编译的EXE允许运行时修改代码段

Tags: /超级猛料/Format.格式,单位/File.文件格式/   Date Created:

我们知道PE在运行的时候,为了安全起见,是不允许修改代码段的,但Windows并没有对不能修改代码段作真正的限制,只是在PE的头部使用了一个标记来表明是否允许修改代码段而已!

Delphi编译出来的EXE,其text段是代码段,修改text段的一个标记60为E0即可,参考下图:

下面的代码是演示如何修改代码段:

unit Unit1;

interface

uses

 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

 Dialogs, StdCtrls;

type

 TForm1 = class(TForm)

   btnTest: TButton;

   btnCopyCode: TButton;

   btnRestoreCode: TButton;

   procedure btnTestClick(Sender: TObject);

   procedure btnCopyCodeClick(Sender: TObject);

   procedure btnRestoreCodeClick(Sender: TObject);

 private

   { Private declarations }

     Buf: PChar;

     L : Integer;

 public

   { Public declarations }

 end;

var

 Form1: TForm1;

implementation

uses lyhTools;

{$R *.dfm}

function DlgError(const s: string): Integer;

begin

 Result := MessageBox(GetActiveWindow, PCHAR(s), 'Error', MB_OK or MB_ICONERROR);

end;

procedure ErrorEnd;

begin

 // 空的占位符号,用于计算DlgError的代码的大小!

end;

procedure TForm1.btnTestClick(Sender: TObject);

begin

 DlgError('Error');

end;

procedure TForm1.btnCopyCodeClick(Sender: TObject);

var

 P : Pointer;

begin

 P := @DlgError;  // 保存的代码的首地址

 L := Integer(@ErrorEnd) - Integer(@DlgError);  // 求代码段的大小

 GetMem(Buf, L);  // 申请内存块保存代码!

 Move(P^, Buf^, L); // Copy代码段

 WriteToFile(Buf, L, 'C:\Demo.dat', False);  // 保存到文件

 FillChar(P^, L, 0);  // 把代码段置空

end;

procedure TForm1.btnRestoreCodeClick(Sender: TObject);

var

 P : Pointer;

begin

 P := @DlgError;

 Move(Buf^, P^, L);

 FreeMem(Buf);

end;

end.

上面的代码编译后,如果不修改60为E0,那么程序运行点击CopyCode按钮会出现AV错误,不能写入对应的地址;修改60为E0后,程序可以正常运行!

img_11739.bmp (824.1KB)