Mega Code Archive

 
Categories / Delphi / Examples
 

How To Make Your Own Self Extractor (sfx)

Title: How To Make Your Own Self Extractor (sfx) Question: How to create an SFX (Self Extracting Executable) Answer: How to make your own SelF eXtracting (SFX) File by William Anthony This tutorial will teach you the basics and structure of a SFX, in two parts, in theory (this file) and in practice (the project files) STEP 1 o_o Choices [File Format] We must take accountable what type of SFX where going to use, in this tutorial we will use the standard compression/storage standard. Fields per Frame (File) File Name [Options] Fixed String Storage (255 Byte Standard) Advantages FAST EASY TO UNDERSTAND ZOMBIE READ (NO PROC) Disadvantages WASTED SPACE WASTED MEMORY Dynamic String Storage (1 to 256 Bytes) Advantages OPTIMAL SPACE USAGE LESS CHANGE OF CORRUPTION FASTER DOWNLOAD FASTER UPLOAD Disadvantages A LITTLE SLOWER PROCESSING READ (PROC) Data Size [Options] Fixed Cardinal Storage (4 Byte Standard) Advantages FAST EASY TO UNDERSTAND ZOMBIE READ (NO PROC) Disadvantages WASTED SPACE Dynamic Cardinal Read (Advanced 1 - 5 Bytes) Advantages OPTIMAL SPACE USAGE LESS CHANCE OF CORRUPTION FASTER DOWNLOAD FASTER UPLOAD Disadvantages A LITTLE SLOWER PROCESSING READ (PROC) ADVANCED MEMORY ROUTINES Size Check [Options] Uncompressed Size (Cardinal) Advantages FAST EASY Disadvantages UNSAFE CRC 32 (Cardinal) Advantages SAFE GET TO LEARN CRC32 Disadvantages SLOW OVERKILL You must look well into what you need and what out of the SFX to be able to choose the proper format to build, EVEN IF PEOPLE DON'T NOTICE, DO IT RIGHT! STEP 2 o_0 Frame Format Structure Layout Field Type Size File Name DString 1 - 256 Bytes Data Size Cardinal 4 Bytes Uncompressed Size Cardinal 4 Bytes We will introduce you step by step to the wild world of Dynamic Variables Simple? YES Useless? NO Since this format doesn't have a POSITION field, we will use the old fashioned DATA HEADER approach to the SFX. This means it will be that it is meant to DUMP the files not to LOOK UP the files. There are ways we can CONVERT this Frame Format to use in a FAT like table, but lets keep it simple (FOR NOW) STEP 3 0_0 SFX File Format Structure Data Type Size SFX ID Char 2 Frame Count Word 2 Frame Data Raw UNKNOWN SFX Data Size Cardinal 4 SFX ID is used to detect if the executable (image file) contains valid SFX Data Frame Count is used to tell us how many frames to process Frame Data is the Frame Header (Structure) + Raw/Compressed File Data SFX Data Size is NEEDED (you will see) STEP 4 0_! How to add data to and Image File Module (EXE) A little known fact of the all mighty image file (EXE) is that like a GOOD file format, it is that only what is specified is needed. By that I mean that you can add what ever you want at the end and nothing will happen, no ZIP drive bursting in flames or even worse a "BLUE SCREEN" (c) Micro$oft 1991-2002 Now you see why I need the SFX Length at the END? yes its to go to the end of the READ-ONLY Image File (EXE) and read the Length, then look up the SFX ID to see if any SFX data is present on that Image File (EXE) STEP 5 !_! Now to build an SFX module Well this is an easy and important part of the process, make it as SMALL as POSSIBLE, yes kiddies "YOU CAN PACK THE IMAGE FILE (EXE)" TIP: UPX is great for SFX MODULES Use less DELPHI libraries as possible, API is the way to go! but since this is a intro tutorial we MUST make it simple. Make a procedure to read and process the data, in this case we can use it to READ, UNCOMPRESSED, WRITE the files. FINAL STEP CODING! How to read and write a Dynamic String function ReadDString(Stream: TStream): String; var LEN: Byte; // Length Byte begin Stream.Read(LEN, 1); // Read Length (255 Max) SetLength(Result, LEN); // Set Delphi D-String Array Size Stream.Read(PChar(Result)^, LEN); // Read Data to D-String Array end; Procedure WriteDString(Stream: TStream; const Str: String); var LEN: Byte; // Length Byte begin LEN := Length(Str); // Set Length Byte what Str[0] used to be Stream.Write(LEN, 1); // Write Length Byte (255 Max) Stream.Write(PChar(Str)^, LEN); // Write D-String Array Data end; COMMENT: Why the "PChar(Str)^" why not just use Str? Well since the Str is a Delphi Dynamic-String Array (array of char), it stores its pointer, so if you attempt to use Str you are actually writing its pointer NOT the data, so what i do is I get the Pointer of the first Character on the array "PChar(Str)" then I release it as a VARIABLE or CONSTANT, as if it where a normal variable!. Download Download project files for both the SFX Maker and the SFX it self it is your job to try to understand the code, (i re-use variables allot), the main idea is this: CREATE NEW SFX FILE WRITE SFX MODULE (MODULE EXE) WRITE SFX DATA SFX DATA WRITE ID ('SF') WRITE FILE COUNT WRITE FILE WRITE LENGTH WRITE FILE WRITE FILENAME WRITE COMPRESSED LENGTH WRITE UNCOMPRESSED LENGTH WRITE COMPRESSED FILE DATA