Exemod - Colocando arquivos e strings dentro do exe em runtime |
Top Previous Next |
|
unit ExeMod; { This is the first beta of the full version 1.00 That allows an ExeMod exe to work properly even from a CD..for info on how an exe on CD is handled please see the notes in the Interface section.
Written by G.A. Carpenter (works on D2 thru D7) This is FreeWare for any purpose...use as you will. Consider it public domain... feel free to make any changes you want... if you improve it I'd love to get a copy of the improvements :-)
gacarpenter386@yahoo.com <gwen carpenter (Gwena)>
You can use this in any program, commercial or freeware, and you DO NOT need to mention where it came from. (no attribution needed)
If you use NT/2000/XP please read the NT-NOTE below!
This unit enables you to make a delphi application that can alter its own exe file on disk... this appears to happen at runtime but actually the switch quickly takes place after a shutdown of the running app during which a copy of the exe deletes the old version and replaces it with a new version.
While it is also possible to alter a running exe directly by altering the hd sectors that hold the exe's data. I abandoned that scheme because although it worked quickly and transparently it proved to be risky :-(
This unit lets you easily create... -Self altering exe files -Program Generators -Apps that update live over the internet -Apps that keep an internal record of data (no ini file or registry usage needed) -File handling utils -Copy protection schemes -Self extracting archives -Programs that alter and store data in other programs and files. ...and many other strange things ;-)
NOTE! ExeMod will not delete a demarc delimited string from an external file if the deletion would take the file down to 0 bytes in length! This is because some disk cleanup utils can be set to automatically remove 0 length files. If you intend to use an external file to hold data that will be handled by ExeMod you should begin by placing at least a single byte of data at the beginning of the file.
------ NT-NOTE!
If you use ExeMod.pas on an NT machine then you may need to run the exe outside the delphi ide... for some reason NT causes the debugger to faint at the sight of my code :-) the exe files run just fine on NT but just not from inside the ide....
------- Here are some simple demos for you to look over.
(Remember to put ExeMod.pas into your compiler's path or into your project's directory... then add ExeMod to your program's uses clause) ------------------------------------------------------------------------ -Code to alter a byte in an exe and then alter the exe at runtime and put the change onto the exe's file on disk
procedure TForm1.Button1Click(Sender: TObject); begin ReadExe; //Read exe file from disk and put into global string named Exe Exe[3] := 'A'; //Change byte 3 of Global string Exe AlterExe; //Alter the exe file on disk then quickly restart program end; ------------------------------------------------------------------------ -Code to add a file from disk to the end of the exe at runtime. Assume a small txt file named C:\myfile.txt exists and contains the text 'test'
procedure TForm1.Button1Click(Sender: TObject); begin AddFile2Exe('gac1','C:\myfile.txt'); AlterExe; end;
The string 'gac1' serves to locate the data at the end of the exe. I call gac1 a 'Demarc name' because when combined with a few other characters it serves as a demarcation line in the exe file... this gives you an easy way to search through the file and find the location of the start of your data.
Here is what is added to the exe at runtime when you click the button
SO!#GAC1¶testEO!#GAC1
The data from the file is the 4 bytes 'test' all the rest is just delimiter data so that ExeMod can locate the data in the exe file. The Character '¶' in the string is to tell the program where the name given to the data string ('GAC1') ends. it is chr(182) please do NOT use chr(182) as a character in any demarc name or you will cause an error!
AddFile2Exe will load the exe from disk if it has not already been loaded... it checks to see if Exe = '' and if so does a ReadExe; ----------------------------------------------------------------------- -Code to extract an ExeMod data block from the exe at runtime and save it to a file on disk... then remove the block from the exe and alter the exe on disk so that it no longer contains any trace of the data block.
procedure TForm1.Button1Click(Sender: TObject); begin ExtractAndStrip('gac1','myfile2.txt'); AlterExe; end;
This extracts the ExeMod data block gac1 to a file named 'myfile2.txt' the file is placed into the directory where the program's exe file is located.
This sort of code is good for making a self-extracting installation program in delphi. All of your help files,dlls..etc can be extracted during the first run of your program... exe size will be small because the data will be removed from the exe after extraction. All files will be extracted to the program's dir unless a full path name is given. ----------------------------------------------------------------------- Code to save a copy of the running exe
procedure TForm1.Button1Click(Sender: TObject); begin Exe2File('MyNewExe.exe'); Exe := ''; //set Exe to empty string (save space if data no longer needed) end;
Saves a copy of the running exe as myNewExe.exe in the same directory where the running exe is. If Exe has been altered the altered version will be saved... if Exe has not been loaded yet then ReadExe is called. ----------------------------------------------------------------------- Code to save a modified copy of the running exe... this simple code gives you a program generator.
procedure TForm1.Button1Click(Sender: TObject); begin ReadExe; //add code here to modify the string named 'Exe' Exe2File('MyNewExe.exe'); Exe := ''; //set Exe to empty string (save space if data no longer needed) end;
This simple code is actually VERY powerful and VERY useful... -----------------------------------------------------------------------
---> Much more Demo code and many more procedures to come..soon as I get some more free time :-)
}
interface
uses Windows, SysUtils, Classes, Forms, ShellAPI, Dialogs;
var Exe: string;
procedure Delay(ms: longint); procedure ReadExe; procedure String2File(String2BeSaved, FileName: string); function WinDrv: char; function GetDemarcCount: integer; procedure GetDemarcName(DNumber: Integer; var DName: String); function File2String(FileName: string): string; function PeekExeByte(Byte2Get: Integer): byte; function PeekExeWord(Word2Get: Integer): word; procedure PeekExeString(StartByte,Count: Integer; var ReturnedStr: String); procedure PokeExeByte(Byte2set: Integer; ByteVal: Byte); procedure PokeExeByteI(Byte2set: Integer; ByteVal: Byte); procedure PokeExeString(StartByte: Integer; String2Insert: String); procedure PokeExeStringI(StartByte: Integer; String2Insert: String); procedure ExtractFromExe(DemarcStr: string; var ExtractedStr: string); procedure ExtractFromFile(DemarcStr: string; DataFile: string; var ExtractedStr: string); procedure DelFromString(DemarcStr: string; var String2Change: string); procedure DelFromExe(DemarcStr: string); procedure DelFromFile(DemarcStr, FileName: string); procedure Add2File(DemarcStr, FileName, String2Add: string); procedure ReplaceInFile(DemarcStr, FileName, ReplacementString: string); procedure TackOnFile(DemarcStr, FileName, File2Add: string); procedure Add2String(DemarcStr, String2Add: string; var String2Alter: string); procedure ReplaceInString(DemarcStr, ReplacementString: string; var String2Alter: string); procedure ReplaceInExe(DemarcStr, ReplacementString: string); procedure InsOrReplaceInString(DemarcStr, ReplacementString: string; var String2Alter: string); procedure InsOrReplaceInExe(DemarcStr, ReplacementString: string); procedure AlterExe; procedure ExtractAndStrip(DemarcStr, FileName: string); procedure Exe2File(FileName: string); procedure Extract2File(DemarcStr, FileName: string); procedure AddFile2Exe(DemarcStr, FileName: string); procedure Add2Exe(DemarcStr, String2Add: string); procedure Stream2Exe(TempStream: TMemoryStream); procedure String2Stream(a: String;var b: TMemoryStream); procedure Stream2String(b: TMemoryStream;var a: String);
implementation
//================================================== //This is just a simple procedure to implement a delay
procedure Delay(ms: longint); var TheTime: LongInt; begin TheTime := GetTickCount + ms; while GetTickCount < TheTime do Application.ProcessMessages; end; //===================================================
//=================================================== //This code returns the char of the drive where //windows is installed
function WinDrv: char; var WinDir : String; n : Integer; begin SetLength(WinDir,256); n := GetWindowsDirectory(PChar(WinDir),256); SetLength(WinDir,n); Result := WinDir[1]; end; //===================================================
//=================================================== //This function returns the number of data strings that //are stored in the exe under demarc names... if demarc //delimited data strings have been added to the global //string Exe but not yet flushed to disk by an AlterExe //command, they will still be included in this count!
function GetDemarcCount: integer; var Count,X: Integer; begin Count := 0; If Exe = '' then ReadExe; For X := 1 to Length(Exe)-10 do begin If (Exe[X] = 'S') and (Exe[X+1] = 'O') and (Exe[X+2] = '!') and (Exe[X+3] = '#') then begin Inc(Count); end; end; Result := Count; end; //===================================================
//=================================================== //You pass a number (DNumber) to this procedure and it //returns a string (DName) that contains the DNumber'th //demarc name from the exe file. If the DNumber'th //demarc string does not exist then an empty string //is returned. This procedure lets you easily look through //the running exe or any other file to discover the demarc //names under which data has been stored.
procedure GetDemarcName(DNumber: Integer; var DName: String); var Count,X,Y: Integer; begin Count := 0; If Exe = '' then ReadExe; For X := 1 to Length(Exe)-10 do begin If (Exe[X] = 'S') and (Exe[X+1] = 'O') and (Exe[X+2] = '!') and (Exe[X+3] = '#') then begin Inc(Count); If Count = DNumber then begin Y := X+4; While Exe[Y] <> chr(182) do begin DName := DName+Exe[Y]; Inc(Y); end; end; end; end; end; //===================================================
//=================================================== //This code loads the Exe file from disk and into //the global string var 'Exe'
procedure ReadExe; var ExeStream: TFileStream; begin ExeStream := TFileStream.Create(Application.ExeName, fmOpenRead or fmShareDenyNone); try SetLength(Exe, ExeStream.Size); ExeStream.ReadBuffer(Pointer(Exe)^, ExeStream.Size); finally ExeStream.Free; end; end; //===================================================
//=================================================== //This code can write any string to disk as a file
procedure String2File(String2BeSaved, FileName: string); var MyStream: TMemoryStream; begin if String2BeSaved = '' then exit; SetCurrentDir(ExtractFilePath(Application.ExeName)); MyStream := TMemoryStream.Create; try MyStream.WriteBuffer(Pointer(String2BeSaved)^, Length(String2BeSaved)); MyStream.SaveToFile(FileName); finally MyStream.Free; end; end; //===================================================
//=================================================== //This code can read any file from disk and into a string
function File2String(FileName: string): string; var MyStream: TMemoryStream; MyString: string; begin MyStream := TMemoryStream.Create; try MyStream.LoadFromFile(FileName); MyStream.Position := 0; SetLength(MyString, MyStream.Size); MyStream.ReadBuffer(Pointer(MyString)^, MyStream.Size); finally MyStream.Free; end; Result := MyString; end; //===================================================
//=================================================== //This code lets you read a byte from the running exe //directly from the ram. Byte 1 = first byte of exe //DO NOT attempt to read values lower than 1 or function //will fail and produce random data. Be advised that //bytes that are appended to the exe file cannot be read //using this function as that data is not in ram at runtime! //Do not attempt to read within or beyond a few hundred bytes //of the end of your exe (minus any appended data) as data //beyond that range cannot be retrieved with this simple //function... there is no range checking for the upper //bound so use caution.
function PeekExeByte(Byte2Get: Integer): byte; Begin If Byte2Get < 1 then Exit; Result := byte(pointer(Hinstance+Byte2Get-1)^); End; //===================================================
//=================================================== //This function is nearly identical to the one above //so the comments for PeekExeByte apply here as well.
function PeekExeWord(Word2Get: Integer): word; Begin If Word2Get < 1 then Exit; Result := word(pointer(Hinstance+Word2Get-1)^); End; //===================================================
//=================================================== //This code returns a string from the exe image in RAM //cautions are similar to PeekExeByte
procedure PeekExeString(StartByte,Count: Integer; var ReturnedStr: String); var X: Integer; Begin If StartByte < 1 then Exit; For X := StartByte to StartByte+Count-1 do begin ReturnedStr := ReturnedStr+(char(pointer(Hinstance+X-1)^)); end; End; //===================================================
//=================================================== //This code can stuff a string into the exe starting at //a specified point... changes are NOT immediately saved //to disk.
procedure PokeExeString(StartByte: Integer; String2Insert: String); var X: Integer; Begin If Exe = '' then ReadExe; If StartByte + Length(String2Insert) > Length(Exe) then Exit; If StartByte < 1 then Exit; For X := 1 to Length(String2Insert) do begin Exe[X+StartByte-1] := String2Insert[X]; end; end; //===================================================
//=================================================== //This code can stuff a string into the exe starting at //a specified point... changes ARE immediately saved //to disk... Take care!
procedure PokeExeStringI(StartByte: Integer; String2Insert: String); var X: Integer; Begin If Exe = '' then ReadExe; If StartByte + Length(String2Insert) > Length(Exe) then Exit; If StartByte < 1 then Exit; For X := 1 to Length(String2Insert) do begin Exe[X+StartByte-1] := String2Insert[X]; end; AlterExe; end; //===================================================
//=================================================== //Pokes a byte value into a specified byte in the string //named Exe. This string holds the image of the running //executable. The altered version of exe is NOT immediately //written to disk!
procedure PokeExeByte(Byte2set: Integer; ByteVal: Byte); Begin If Exe = '' then ReadExe; If Byte2Set > Length(Exe) then Exit; Exe[Byte2Set] := chr(ByteVal); end; //===================================================
//=================================================== //Identical to PokeExeByte procedure except the changed //byte IS immediately written to disk! USE CARE as the //state of the exe will be lost on restart unless you //store all desired data inside the string named Exe.
procedure PokeExeByteI(Byte2set: Integer; ByteVal: Byte); Begin If Exe = '' then ReadExe; If Byte2Set > Length(Exe) then Exit; Exe[Byte2Set] := chr(ByteVal); AlterExe; end; //===================================================
//=================================================== //This code gets data from the exe that was stored under a //specified demarc name and places it into a string
procedure ExtractFromExe(DemarcStr: string; var ExtractedStr: string); var d, e: integer; begin if Length(Exe) = 0 then ReadExe; if Pos(uppercase('so!#' + DemarcStr + chr(182)), Exe) > 0 then begin d := Pos(uppercase('so!#' + DemarcStr + chr(182)), Exe) + length(uppercase('so!#' + DemarcStr + chr(182))); e := Pos(uppercase('eo!#' + DemarcStr), Exe); ExtractedStr := Copy(Exe, d, e - d); end; end; //===================================================
//=================================================== //This code gets a demarc delimited data string from //an external file and loads it into a string
procedure ExtractFromFile(DemarcStr: string; DataFile: string; var ExtractedStr: string); var d, e: integer; Temp: String; begin Temp := File2String(DataFile); if Pos(uppercase('so!#' + DemarcStr + chr(182)), Temp) > 0 then begin d := Pos(uppercase('so!#' + DemarcStr + chr(182)), Temp) + length(uppercase('so!#' + DemarcStr + chr(182))); e := Pos(uppercase('eo!#' + DemarcStr), Temp); ExtractedStr := Copy(Temp, d, e - d); end; end; //===================================================
//=================================================== //This code deletes a demarc delimited string from any other string
procedure DelFromString(DemarcStr: string; var String2Change: string); var a, b: string; begin a := UpperCase('so!#' + DemarcStr + chr(182)); b := UpperCase('eo!#' + DemarcStr); delete(String2Change, pos(a, String2Change), (pos(b, String2Change) + length(b) - pos(a, String2Change))); end; //===================================================
//=================================================== //This code deletes a demarc delimited string from global //string named Exe
procedure DelFromExe(DemarcStr: string); begin If Exe = '' then ReadExe; DelFromString(DemarcStr,Exe); end; //===================================================
//=================================================== //This code deletes a demarc delimited string from a //file on disk
procedure DelFromFile(DemarcStr, FileName: string); var MyString: string; begin MyString := File2String(FileName); DelFromString(DemarcStr, MyString); String2File(MyString, FileName); end; //===================================================
//=================================================== //This code adds a demarc delimited string to a file
procedure Add2File(DemarcStr, FileName, String2Add: string); var MyString: string; begin If DemarcStr = '' then Exit; MyString := File2String(FileName); MyString := MyString + uppercase('so!#' + DemarcStr + chr(182)) + String2Add + uppercase ('eo!#' + DemarcStr); String2File(MyString, FileName); end; //===================================================
//=================================================== //This code adds a demarc delimited string to a file //if the string already exists it is replaced
procedure ReplaceInFile(DemarcStr, FileName, ReplacementString: string); begin If DemarcStr = '' then Exit; DelFromFile(DemarcStr, FileName); Add2File(DemarcStr, FileName, ReplacementString); end; //===================================================
//=================================================== //This code adds a demarc delimited file to another file
procedure TackOnFile(DemarcStr, FileName, File2Add: string); var Mystring: string; begin If DemarcStr = '' then Exit; MyString := File2String(File2add); Add2File(DemarcStr, FileName, MyString); end; //===================================================
//=================================================== //This code adds a demarc delimited string to any other //string.
procedure Add2String(DemarcStr, String2Add: string; var String2Alter: string); begin If DemarcStr = '' then Exit; String2Alter := String2Alter + uppercase('so!#' + DemarcStr + chr(182)) + String2Add + uppercase('eo!#' + DemarcStr); end; //===================================================
//=================================================== //This code replaces the data held within a demarc delimited //string with new data... the demarc string must exist.
procedure ReplaceInString(DemarcStr, ReplacementString: string; var String2Alter: string); begin If DemarcStr = '' then Exit; if pos(uppercase('so!#' + DemarcStr + chr(182)), String2Alter) = 0 then exit; DelFromString(DemarcStr, String2Alter); Add2String(DemarcStr, ReplacementString, String2Alter); end; //===================================================
//=================================================== //This code replaces the data held within a demarc delimited //string with new data... the demarc string must exist. this //is identical to ReplaceInString except it defaults to //the global string named Exe.
procedure ReplaceInExe(DemarcStr, ReplacementString: string); begin If DemarcStr = '' then Exit; if pos(uppercase('so!#' + DemarcStr + chr(182)), Exe) = 0 then exit; DelFromString(DemarcStr, Exe); Add2String(DemarcStr, ReplacementString, Exe); end; //===================================================
//=================================================== //This code will replace the data held within a demarc delimited //string with new data... if the demarc delimited string does not //exist it will be created.
procedure InsOrReplaceInString(DemarcStr, ReplacementString: string; var String2Alter: string); begin If DemarcStr = '' then Exit; DelFromString(DemarcStr, String2Alter); Add2String(DemarcStr, ReplacementString, String2Alter); end; //===================================================
//=================================================== //This code will replace the data held within a demarc delimited //string with new data... if the demarc delimited string does not //exist it will be created. This is identical with InsOrReplaceInString //except it defaults to the global string Exe.
procedure InsOrReplaceInExe(DemarcStr, ReplacementString: string); begin If DemarcStr = '' then Exit; If Exe = '' Then ReadExe; DelFromString(DemarcStr, Exe); Add2String(DemarcStr, ReplacementString, Exe); end; //===================================================
//=================================================== //This code swaps the current version of the running exe //on disk for the version that is held in the global //string named 'Exe' Your application quickly shuts down and //re-starts as the new version. ANY DATA THAT YOU WANT THE NEW //VERSION TO BE AWARE OF MUST BE PASSED AS DATA INCLUDED //IN 'Exe' before calling this procedure!!!
procedure AlterExe; begin if (Exe) <> '' then begin String2File(Exe, 'temp0a0.exe'); ShellExecute(0, 'open', PChar('temp0a0.exe'), PChar('"'+ExtractFilename(Application.ExeName)+'"'), nil, SW_SHOW); Application.Terminate; end; end; //===================================================
//=================================================== //This code extracts a demarc delimited string from the //global string 'Exe' to a file. The data is then stripped //out of 'Exe' .. this procedure is very useful for //making self extracting archives that remove all the //archived files from the exe after extraction... reducing //hd space required... just store all your dll's, images //etc in the exe and extract and strip them the first //time the user runs the program :-)
procedure ExtractAndStrip(DemarcStr, FileName: string); var Temp: string; begin ExtractFromExe(DemarcStr, Temp); if Length(Temp) <> 0 then begin DelFromString(DemarcStr, Exe); String2File(Temp, FileName); end; end; //===================================================
//=================================================== //This code saves the global string exe to disk as a //new exe.
procedure Exe2File(FileName: string); begin if Exe = '' then ReadExe; String2File(Exe, FileName); end; //===================================================
//=================================================== //This code extracts a demarc delimited string from the //exe and saves it as a file.
procedure Extract2File(DemarcStr, FileName: string); var MyString: string; begin ExtractFromExe(DemarcStr, MyString); if MyString <> '' then String2File(MyString, FileName); end; //===================================================
//=================================================== //This code adds a file to the global string exe as //a demarc delimited string.
procedure AddFile2Exe(DemarcStr, FileName: string); var MyString: string; begin If DemarcStr = '' then Exit; MyString := File2String(FileName); if Exe = '' then ReadExe; Add2String(DemarcStr, MyString, Exe); end; //===================================================
//=================================================== //This code adds a demarc delimited string to the //global string Exe.
procedure Add2Exe(DemarcStr, String2Add: string); begin If DemarcStr = '' then Exit; if Exe = '' then readExe; Add2String(DemarcStr, String2Add, Exe); end; //===================================================
//=================================================== //This code replaces the current exe file on disk with //one that is held in a TMemoryStream. This makes it //easy to update an exe by downloading a new version //over the internet and into a stream... use any of //the free internet packs... like Fpiettes or Synapse lib
procedure Stream2Exe(TempStream: TMemoryStream); begin SetCurrentDir(ExtractFilePath(Application.ExeName)); TempStream.SaveToFile('temp0a0.exe'); ShellExecute(0, 'open', PChar('temp0a0.exe'), PChar(ExtractFilename(Application.ExeName)), nil, SW_SHOW); Application.Terminate; end; //===================================================
//============================================================================== //This code copies a string to a stream
procedure String2Stream(a: String;var b: TMemoryStream); begin b.Position := 0; b.WriteBuffer(Pointer(a)^,Length(a)); b.Position := 0; end;
//==============================================================================
//============================================================================== //This code copies a stream to a string
procedure Stream2String(b: TMemoryStream;var a: String); begin b.Position := 0; SetLength(a,b.Size); b.ReadBuffer(Pointer(a)^,b.Size); b.Position := 0; end;
//============================================================================== //This is the ExeMod.pas Initialization code...this code runs each time your //exe is started... this code handles the actual swapping of one version of //the exe for another. This is done by an exe file swap and re-start carried //out by a temporary copy of the exe named temp0a0.exe. The initialization //code can look for and delete a file named temp0a0.exe if it is found //in the current dir. This is how temp0a0.exe is removed after an exe swap.
initialization begin SetCurrentDir(ExtractFilePath(Application.ExeName));
//****************************************************************************** //NOTE--> WinDrv = The drive where Windows is installed! // //Beginning of code that lets an ExeMod exe work properly even //if it is on a read-only CD ... this code will cause the exe //on the CD to create a dir on WinDrv with the same name as the running //exe. Then it moves a copy of the exe to that dir and runs that //copy before shutting down. Thereafter any time the exe on CD is //run it will act only as a shortcut to the version on WinDrv. //If you do not want this functionality then just comment out this //code or delete it from this unit. You can also disable this code //by changing byte 3 of your exe so that it holds a zero value. //'MZP' becomes 'MZ' followed by a zero byte. //Programs that do not attempt to alter themselves at runtime and //which do not attempt to save files in the current dir should //disable this code... otherwise the app will always needlessly copy //itself to WinDrv and run from there!
if (FileGetAttr(Application.ExeName) and faReadOnly) > 0 then begin if PeekExeByte(3) = 0 then Exit; FileSetAttr(Application.ExeName, FileGetAttr(Application.ExeName) xor faReadOnly); if (FileGetAttr(Application.ExeName) and faReadOnly) > 0 then begin If FileExists(Windrv+':\'+ExtractFileName(Application.ExeName)+ '\'+ExtractFileName(Application.ExeName)) then begin ShellExecute(0, 'open', PChar((WinDrv+':\'+ExtractFileName(Application.ExeName)+ '\'+ExtractFileName(Application.ExeName))),nil, nil, SW_SHOW); Application.Terminate; end else begin CreateDir(WinDrv+':\'+ExtractFileName(Application.ExeName)); Exe2File(WinDrv+':\'+ExtractFileName(Application.ExeName)+ '\'+ExtractFileName(Application.ExeName)); ShellExecute(0, 'open', PChar((WinDrv+':\'+ExtractFileName(Application.ExeName)+ '\'+ExtractFileName(Application.ExeName))),nil, nil, SW_SHOW); Application.terminate; end; end; end; //This is the end of the code that allows proper operation from a CD. //******************************************************************************
if ParamStr(1) = 'deltemp' then begin while not (deletefile('temp0a0.exe')) do begin if (FileGetAttr('temp0a0.exe') and faReadOnly) > 0 then FileSetAttr('temp0a0.exe', FileGetAttr('temp0a0.exe') xor faReadOnly); delay(10); end; deletefile('temp0a0.exe'); end; if UpperCase(ExtractFileName(Application.ExeName)) = ('TEMP0A0.EXE') then begin ReadExe; while not (deletefile(ParamStr(1))) do begin if (FileGetAttr(ParamStr(1)) and faReadOnly) > 0 then FileSetAttr(ParamStr(1), FileGetAttr(ParamStr(1)) xor faReadOnly); delay(10); end; String2File(Exe, ParamStr(1)); ShellExecute(0, 'open', PChar(ParamStr(1)), PChar('deltemp'), nil, SW_SHOW); Application.Terminate; end; end;
end.
// exemplo de password dentro do proprio EXE:
procedure TForm1.FormCreate(Sender: TObject); Var Temp: String; begin ExtractFromExe('MyPwrd',Temp); If Temp = '' then Button1.Caption := 'You Must Create A Password For This Program. Enter It Below And Click Here' else begin Button1.Caption := 'Enter Your Password Below And Click Here To Access Program'; Form1.Color := $00aec2ff; end; end;
procedure TForm1.Button1Click(Sender: TObject); Var Temp: String; begin If Button1.Caption[1] = 'Y' then begin If Edit1.Text = '' then Exit; Add2Exe('MyPwrd',Edit1.Text); //add a pw to the exe AlterExe; //alter and restart the exe end else begin ExtractFromExe('MyPwrd',Temp); If Temp = Edit1.Text Then begin Form1.Height := 350; Edit1.Visible := False; Button1.Visible := False; Image1.Visible := True; Label1.Visible := True; Exe := ''; //set exe string to empty string end; end; end;
procedure TForm1.Button2Click(Sender: TObject); begin DelFromExe('MyPwrd'); end;
/////////// exemplo que grava numero de acessos e data/hora dentro do exe
procedure TForm1.FormCreate(Sender: TObject); var temp: string; begin If paramstr(1) = '' then begin ExtractFromExe('FirstDateTime',Temp); If Temp = '' then Add2Exe('FirstDateTime', DateToStr(Date) + ' ' + TimeToStr(Time)); Exe := Exe + '[' + DateToStr(Date) + ' ' + TimeToStr(Time) + ']'+chr(13)+chr(10); AlterExe; end else if ParamStr(1) = 'deltemp' then WindowState := WsNormal; ExtractFromExe('FirstDateTime',Temp); Form1.Caption := 'First Run Time ' + Temp + ' ->This Run Time ' + DateToStr(Date) + ' ' + TimeToStr(Time); end;
procedure TForm1.SpeedButton1Click(Sender: TObject); begin ReadExe; Exe := Copy(Exe,(Pos(UpperCase('eo!#firstdatetime'),Exe))+17, Length(Exe)-(Pos(UpperCase('eo!#firstdatetime'),Exe))+17); Exe2File('runtimes.txt'); Exe := ''; ShellExecute(0, 'open', PChar('runtimes.txt'),nil,nil, SW_SHOW); end;
//////////////// exemplo que grava um jpg e extrai dentro do exe
//This procedure handles adding a file to an exe //============================================================================== procedure TForm1.SpeedButton1Click(Sender: TObject); Var Temp: String; begin
if Exe = '' then ReadExe; //These 2 lines make sure that a new file cannot if Exe[3] <> 'P' then Exit; //be added to a finalized exe..
OpenDialog1.Execute; If OpenDialog1.FileName <> '' then begin Add2Exe('YourFileName'+IntToStr(Count),ExtractFileName(OpenDialog1.FileName)); AddFile2Exe('YourFile'+IntToStr(Count),OpenDialog1.FileName); Inc(Count); end; end; //==============================================================================
//This procedure rebuilds the exe at runtime by adding all the files. //============================================================================== procedure TForm1.SpeedButton2Click(Sender: TObject); Var Temp: String; begin ExtractFromExe('YourFileName0',Temp); If Temp = '' then Exit; Exe[3] := Chr(Count); AlterExe; end; //==============================================================================
//This procedure extracts a finished archive to disk and views it with browser.. //the first file you stuffed into the exe is what will be executed so make //certain you put the main page as the first saved file... usually this is //index.htm/l ... but it could be anything at all... including another exe :-) //============================================================================== procedure TForm1.SpeedButton3Click(Sender: TObject); Var Temp: String; X,Y: Byte; begin ReadExe; If Exe[3] = 'P' then Exit; Y := ord(Exe[3])-1; For X := 0 to Y do begin ExtractFromExe('YourFileName'+IntToStr(X),Temp); Extract2File('YourFile'+IntToStr(X),Temp); end; ExtractFromExe('YourFileName0',Temp); ShellExecute(Form1.Handle,nil,pchar(Temp), nil,nil, SW_SHOWNORMAL); end; //==============================================================================
//This procedure returns the running exe to its original state .. to activate //this just double click somewhere on the form of either a finalized program //or do it if you make a mistake while building an exe and want to start over. //============================================================================== procedure TForm1.FormDblClick(Sender: TObject); Var Temp: String; X,Y: Byte; begin Y := ord(Exe[3])-1; For X := 0 to Y do begin DelFromString('YourFileName'+IntToStr(X),Exe); DelFromString('YourFile'+IntToStr(X),Exe); Exe[3] := 'P'; end; AlterExe; end; //============================================================================== //This procedure always runs first and it checks to see if the exe is a //finalized ebook... if it is it alters the appearance of the form to reflect //that fact :-) //============================================================================== procedure TForm1.FormCreate(Sender: TObject); begin ReadExe; if Exe[3] <> 'P' then begin Form1.Height := 85; SpeedButton3.Top := 14; Form1.Color := $00BFDABA; SpeedButton3.Visible := True; SpeedButton1.Visible := False; SpeedButton2.Visible := False; end; end; |