// efg, May 1997 unit Execrcfm; interface uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) GroupBoxEXEInfo: TGroupBox; LabelCRCValue: TLabel; LabelCRC: TLabel; LabelEXEName: TLabel; ButtonCalc: TButton; GroupBoxSentinel: TGroupBox; LabelSentinel: TLabel; EditSentinel: TEdit; LabelCount: TLabel; ButtonCount: TButton; LabelHex: TLabel; LabelBytes: TLabel; LabelStatus: TLabel; LabelNote: TLabel; ButtonPatchEXE: TButton; LabelPatchInfo: TLabel; procedure ButtonCalcClick(Sender: TObject); procedure ButtonCountClick(Sender: TObject); procedure ButtonPatchEXEClick(Sender: TObject); private CRC32 : INTEGER; SentinelValue: INTEGER; public { Public declarations } end; var Form1: TForm1; implementation uses CRC32; {$R *.DFM} procedure TForm1.ButtonCalcClick(Sender: TObject); VAR iError : INTEGER; iTotalBytes: INTEGER; begin LabelEXEName.Caption := ParamStr(0); SentinelValue := StrToInt(EditSentinel.Text); CalcFileCRC32 (Paramstr(0), SentinelValue, CRC32, iTotalBytes, iError); LabelCRCValue.Caption := IntToHex(CRC32, 2*SizeOf(INTEGER)); LabelBytes.Caption := 'Bytes = ' + IntToStr(iTotalBytes); IF CRC32 = CRCCheckArray[2] THEN LabelStatus.Caption := 'CRC Check OK' ELSE LabelStatus.Caption := 'CRC Check Failed'; GroupBoxSentinel.Enabled := TRUE end; procedure TForm1.ButtonCountClick(Sender: TObject); VAR ByteCount : INTEGER; BytesRead : INTEGER; error : INTEGER; FromFile : FILE; i : INTEGER; IntegerBuffer: ^TIntegerBuffer; IntegerCount : INTEGER; IOBuffer : ^TByteBuffer; SentinelCount: INTEGER; TotalBytes : INTEGER; begin FileMode := 0; {Turbo default is 2 for R/W; 0 is for R/O} AssignFile (FromFile, Paramstr(0)); {$I-} RESET (FromFile,1); {$I+} error := IOResult; IF error = 0 THEN BEGIN SentinelValue := StrToInt(EditSentinel.Text); New (IOBuffer); {Allocate the Buffer} ByteCount := 0; IntegerCount := 0; SentinelCount := 0; REPEAT BlockRead (FromFile, IOBuffer^, SizeOf(TByteBuffer), BytesRead); IntegerBuffer := Addr(IOBuffer^); FOR i := 0 TO BytesRead DIV 4 - 1 DO BEGIN INC(IntegerCount); IF IntegerBuffer^[i] = SentinelValue THEN INC(SentinelCount) END; INC (ByteCount, BytesRead) UNTIL BytesRead = 0; Closefile (FromFile); Dispose (IOBuffer); {Free the Buffer} END; LabelHex.Caption := 'Hex = ' + IntToHex(SentinelValue, 2*SizeOf(INTEGER)); LabelCount.Caption := 'Bytes = ' + IntToStr(ByteCount) + ', Integers = ' + IntToStr(IntegerCount) + ', Sentinels = ' + IntToStr(SentinelCount) end; procedure TForm1.ButtonPatchEXEClick(Sender: TObject); VAR BytesRead : INTEGER; error1 : INTEGER; error2 : INTEGER; FromFile : FILE; i : INTEGER; IntegerBuffer: ^TIntegerBuffer; IOBuffer : ^TByteBuffer; ReplaceFlag : BOOLEAN; SentinelCount: INTEGER; ToFile : FILE; begin FileMode := 0; {Turbo default is 2 for R/W; 0 is for R/O} AssignFile (FromFile, Paramstr(0)); {$I-} RESET (FromFile,1); {$I+} error1 := IOResult; AssignFile (ToFile, 'Patched.EXE'); {Hardwire for now} {$I-} REWRITE (ToFile, 1); {$I+} error2 := IOResult; IF (error1 = 0) AND (error2 = 0) THEN BEGIN ReplaceFlag := FALSE; SentinelValue := StrToInt(EditSentinel.Text); New (IOBuffer); {Allocate the Buffer} SentinelCount := 0; REPEAT BlockRead (FromFile, IOBuffer^, SizeOf(TByteBuffer), BytesRead); {Look at buffer and if sentinel found, replace next integer with CRC-32} IntegerBuffer := Addr(IOBuffer^); FOR i := 0 TO BytesRead DIV 4 - 1 DO BEGIN IF ReplaceFlag THEN BEGIN IntegerBuffer^[i] := CRC32; ReplaceFlag := FALSE; INC (SentinelCount) END ELSE ReplaceFlag := (IntegerBuffer^[i] = CRCCheckArray[1]) END; BlockWrite (ToFile, IOBuffer^, BytesRead) UNTIL BytesRead = 0; CloseFile (FromFile); CloseFile (ToFile); Dispose (IOBuffer); {Free the Buffer} END; IF SentinelCount = 1 THEN LabelPatchInfo.Caption := 'One Integer Patched' ELSE LabelPatchInfo.Caption := 'CAUTION: Integers Patched = ' + IntToStr(SentinelCount); end; end.