Board index » delphi » Appending exe to exe file

Appending exe to exe file

Hello All.

Is the anybody here knows how to append EXE file
to the another EXE file, and they both will works,
please answer me. I'll be very glad to get a simple of this.

Thanx .

 

Re:Appending exe to exe file


Quote
Sergei Salnikov wrote:
> Hello All.

> Is the anybody here knows how to append EXE file
> to the another EXE file, and they both will works,
> please answer me. I'll be very glad to get a simple of this.

> Thanx .

3gpacmu!
That's a difficult task but not impossible.Since exe files have
a crc checksum in their file header dos knows exactly the end of the
file and treats the rest of it as garbage.It's difficult to do that with
a basic pascal knowage.You should dig asm.If you do you can use int 21h
ah=4bh (Don't ask me how since I'm not an asm coder!).The simpliest
solution in pascal is probably to find the end of the exe you're
running,copy the data after it in a temporary exe file and execute it ;)
Hope you don't want to do any destructive tool.

Regards,
Peter M.

Re:Appending exe to exe file


Quote
Peter Moraliyski wrote:
> Sergei Salnikov wrote:

> > Hello All.

> > Is the anybody here knows how to append EXE file
> > to the another EXE file, and they both will works,
> > please answer me. I'll be very glad to get a simple of this.

> > Thanx .

> 3gpacmu!

(I won't try to decypher that little bit.)

Quote
> That's a difficult task but not impossible.Since exe files have
> a crc checksum in their file header dos knows exactly the end of the
> file and treats the rest of it as garbage.

Not quite true.  AFAIK, CRC never enters into the picture.  The size of the
base executable is determind by a page count plus a possible overflow value,
both of which are obtained from the EXE header.  I've used a unit with the
following functions:

function flength (var name : pathstr) : longint;

var
  s : searchrec;

begin
  findfirst (name,anyfile,s);
  if DOSError=0 then
    flength := s.size
  else
    flength := -1;
end;

function EXElength (var name : pathstr) : longint;

type
  EXEheader = record
    ID : word;
    bytemod : word;
    pages : word;
    relocitems : word;
    size : word;
    minparagraphs : word;
    maxparagraphs : word;
    stackseg : word;
    SPreg : word;
    checksum : integer;
    IPreg : word;
    codeseg: word;
    firstreloc: word;
    ovlnum: word;
  end;

var
  f : file of EXEheader;
  header : EXEheader;

begin
  assign (f,name);
  reset (f);
  read (f,header);
  close (f);
  with header do
    EXElength := longint(bytemod)+(longint(pred(pages))*512);
end;

function appendedfile (var name : pathstr) : boolean;

begin
  appendedfile := EXElength(name)<>flength(name);
end;

Quote
> It's difficult to do that with a basic pascal knowage.

It's not that information after the actual EXE is garbage, it's just undefined
as far as the EXE header and loader are concerned.

Quote
> You should dig asm.If you do you can use int 21h
> ah=4bh (Don't ask me how since I'm not an asm coder!).The simpliest
> solution in pascal is probably to find the end of the exe you're
> running,copy the data after it in a temporary exe file and execute it ;)
> Hope you don't want to do any destructive tool.

I've just looked over the information for this call (AH=4Bh), and it looks
rather odd.  From what I can tell, you give it the pathname, but you can't
specify an offset.  So the result, *if* you could get it to work, would be to
end up reloading the same program.

Copying and calling the second .EXE could be a possibility, but is probably
sloppier than just having a separate program in the first place.  I have never
really understood the rationale for wanting to paste two EXEs together like
this in the first place.

Quote
> Regards,
> Peter M.

--
Scott Earnest            | SPAM protection in effect. Remove  |
setech@_ix.netcom.com    | "_" as needed for true addresses.  |
earnests@_homenet.lm.com |    UIN:1136443  EFnet:pale_blue    |
sinykal@_{*word*104}space.org  | URL: http://www.netcom.com/~setech |

Re:Appending exe to exe file


Quote
Scott Earnest <setech@_ix.netcom.com> wrote:
>Copying and calling the second .EXE could be a possibility, but is probably
>sloppier than just having a separate program in the first place.  I have never
>really understood the rationale for wanting to paste two EXEs together like
>this in the first place.

Only thing I can think of is someone wanting to paste a password
front-end to an existing program.

One point that hasn't been mentioned yet is that most of the
garbage appended to the end of the exe uses a signature-type
record defined in the object unit as --
 THeader = record
   Signature: Word;
   case Integer of
     0: (
       LastCount: Word;
       PageCount: Word;
       ReloCount: Word);
     1: (
       InfoType: Word;
       InfoSize: Longint);
 end;

This record prefixes components such as debug information,
overlays, resource files, help files, etc.  Using this record on
the exe, you'll find the exe's "MZ" signature is $5A4D and that
subsequent "FB" signatures are $4246.  To locate a section you set
the position to 0 and walk the exe looking for the appropriate
InfoType.

The TVision resource file defines:
  RStreamMagic   : Longint = $52504246; { 'FBPR' }
  RStreamBackLink: Longint = $4C424246; { 'FBBL' }

TVision helpfile defines:
  HelpFileMagic  = $46484246;           { 'FBHF' }

For example, the following was removed from tStream.Init to allow
searching a DOS real mode exe for any specified resource. The new
method allows appending a TVision help file as well as a resource
file or user define block. (note that BasePos must be initialized
before calling).  Of course there are other pieces missing.  But
if you have the RTL you have everything you need.

Function tStream.AlignResource
  (VAR BasePos: Longint; Magic: Longint): Boolean;

VAR Found, Stop: Boolean;
    Header     : THeader;
BEGIN
    Found := False;
    REPEAT
       Stop := True;
       If BasePos <= GetSize - SizeOf(THeader) Then
       Begin
          Seek(BasePos);
          Read(Header, SizeOf(THeader));
          Case Header.Signature of
             $5A4D:
             Begin
                Inc(BasePos, LongMul(Header.PageCount, 512) -
                   (-Header.LastCount and 511));
                 Stop := False;
             End;
             $4246:
                If  (Header.InfoType = LongRec(Magic).Hi)
                and (LongRec(Magic).Lo = $4246)
                Then
                    Found := True
                Else Begin
                    Inc(BasePos, Header.InfoSize + 8);
                    Stop := False;
                End;
          End{Case};
       End;
    UNTIL Stop;
    AlignResource := Found;
End;

    ...red

--
Support the anti-Spam amendment
  Join at http://www.cauce.org/

Other Threads