Link to home
Start Free TrialLog in
Avatar of Stuart_Johnson
Stuart_Johnson

asked on

Adding files to an EXE

Hi All,

I need to write a program which will install an EXE onto a PC.  I need to write a "stub" program which asks all the question (like where to copy the file too), and does the actual copying.

That part is easy.  The tricky part is, how can I, at run time, add binary data to the end of the OPENED program?  For example.  My program is called UDSERVER.EXE.  I need to add a file called VSLICENCE.KEY to this EXE.  Is there a way of doing this at all?

Previously I would build the key file into a resource, add that to the project and recompile.  This is OK, but I would prefer to make it all self contained.

Any ideas?

Cheers,

Stu.
Avatar of Indefrei
Indefrei

writing a virus ?
nosing in ..
Avatar of Stuart_Johnson

ASKER

LOL.  Yeah.  Bit primative for a virus don't you think?

No I'm not.  I'm writing an install for our video server.  More specifically, the copy protection for it.

Hi Barry.  No answer this time?  I'm shocked.
Probably you wouldn't like this, but :-)

why don't you spawn another EXE (say ADD.EXE), and then quit UDSERVER.EXE.

ADD.EXE will make sure UDSERVER.EXE is closed, and then add the license key to it.  If you don't like to distribute two EXEs, then you can ofcourse include ADD.EXE inside your UDSERVER.EXE, and then extract it during runtime and then execute it.  

ADD.EXE ofcourse will self delete :-), once it has appended your license file to your original EXE.
Avatar of simonet
Hello, Stuart! How are you doing, mate?

>ADD.EXE ofcourse will self delete

Hmmm... I don't think that's possible. But everything else is quite feasible.

Can your EXE use a DLL, to which you'll add the license file? You could also statically import some other stuff from the DLL so the user can't delete it.

Are there limitations on the number of files you're allowed to distribute?

Alex

ahalya: Thanks for the comments.  At this stage, I would prefer to keep it as one file.  However, if the situtation dictates, then I will definately give this method a go.

Hi Alex!  Long time no talk.  I'm really well - thanks for asking!  And you?

At this stage there is no limitation, however, I would like to only use one.  I am quite happy to have files within the main EXE and then extract them as needed.

If it isn't possible to add them while it is running, how hard is it too add a file to the end of the EXE and then save that?  And how would I add the file in code?

Thanks for all the help guys.


Stu.
I'm not exactly sure what you want to do.....

I'm thinking that what you want is to create an install program for your .exe
file that is totally self contained and when you run this installer it pulls the data to create the new exe file from it's own musty innards and adds a unique identifier code (key) to the new exe as a sort of fingerprint....so that
you can look into any .exe file and see who it was sold to.

You can do this by placing the .exe file you wish to create inside a resource file in the installer program... then pull it out and write it to disk. Then modify
the new file by adding a key....

You could simply append the key to the end of an exe.  Or you could place a string inside your exe and overwrite it's value using the key. Or you could overwrite some bytes near the beginning of the new exe file....(look for the string of bytes 'This program cannot be run in DOS mode' and simply overwrite this with your key.... The best option is to compress your new exe using the free UPX compressor and using the long string near the beginning of the file that begins with 'This file is packed with the UPX executable packer...' and overwrite this long string with your key. Using UPX also will make your exe a bit harder to hack...especially if you overwrite the entire UPX ad string... and also the  'UPX0' and 'UPX1' strings that preceed it (use a hex editor like the free FHRED.exe to do this) overwriting these strings will
keep the UPX uncompress functions from being able to recognize the file...this affords you a tiny bit more anti-hacking insurance...

This scheme would work pretty well against the weak minded... but if a hacker had just 2 copies of the .exe with 2 different keys he would be able to compare them and remove the identity keys :-(   to get really good protection would require encryption and multiple keys spread all over the program....making it more work than it is worth to track them all down.

-------------------------------------------------------------------------------------------
If what you want to do is have a single exe file that modifies itself while it is running by adding a key to itself this is sort of do-able but tedious.

You could distribute a demo program that could be upgraded by emailing
a key to a purchaser. He would enter the key and the program would then add this key data to it's own exe file while it was running...and at the same time enable full functionality.

step 1
The purchaser enters the key... and the program then reads it's own exe file and makes a new copy using this method.

CopyFile(pchar(Application.ExeName),pchar('c:\windows\desktop\'+ExtractFileName(Application.ExeName)),false);

step 2
You then modify the new copy by adding the key...then you run it and shut down the original demo program.

step 3
the newly created fully registered exe file looks for the original demo exe file and deletes it.

step 4
The newly created file now copies itself to the original directory and runs the new copy and shuts itself down.

step5
The final copy in the original location deletes the temp copy from step 4 and
this whole Rube Goldberg scheme comes to a close ;-) ... whew

...Gwen..
Hi Gwen,

Wow!  Quite a literary piece that ;)

What I am trying to do is to create a Delphi executable which pops up a message saying "Select your installation directory and click OK to upgrade your licence key".  This key is then copied from my distribution application (the Delphi app) to the directory where the user specified.  

What I need to be able to do is to create this application and allow our administration staff to automatically append a new key file to the end of the executable whenever a customer wants to update their user count (from say 30 students to 100).  This application is then emailed to the client.

Because the application is being used by admin, they have no access to Delphi or the know-how to create the executables (and we don't want them playing with DOS or using batch files to create the resources).  Therefore, I want to append the keyfile to the end of the Application using another process.

The keyfile is a binary, variable length file.  It can vary depending upon options the school has chosen.  For instance, there maybe only 30 worksheets available for one school, but 300 for another, so the keyfile maybe 50bytes more than the original key.

I don't mind having to write another program which appends the keyfile to the executable, but I don't want to do it using resources.  I am already doing it that way and it means I have to do them.  Whenever a new order is placed it takes about 30 minutes per key to complete the entires process - time I don't have.

Thanks for your help,

Stuart.

It should be easy to just append a few bytes to the end of an exe file...
It does no harm to lengthen an exe... I have done it a few times.

It is a bit problematic though to get your program to read the bytes that have been added to it's length...



But I think that the following is what you really need to try.....


If I wanted to add things to an exe file that it could easily work with I would simply create a string variable and give it a holding value

mykey := 'allowed users is xxx';

then have your program read it's own exe file as I detailed above and
simply look for the string 'allowed users is xxx' and change it to something like 'allowed users is 050' ..... when the program runs it simply checks mykey
to see how many users are allowed :-)

! don't use a string like 'aaaaaaaaaaaaaaaaaaa' to create a string for this purpose because delphi will compress this to a shorter value when it compiles! ... strings with repeated values and identical strings are compressed to save space.




Here is a very simple program that shows what I'm getting at

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Buttons;

type
  TForm1 = class(TForm)
    SpeedButton1: TSpeedButton;
    procedure SpeedButton1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  mykey: string;

implementation

{$R *.DFM}

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
mykey := 'hello world';
speedbutton1.caption := mykey;
end;

end.



If you compile this to an exe and run it it simply displays 'hello world' as the caption of the button when you click it.... you can use a hex editor to find the string 'hello world' inside the exe file ... then change it to something else like 'hello there' and save it.. when you run the program now it displays 'hello there'

It is easy to make the program do this sort of simple alteration to it's own exe...and even simpler to write a small stand alone exe that does this to other exe files... it's like a simple patcher program....just use ordinary file handling techniques to search for the string to change and to alter the file :-)
Gwen,

It's a key file.  It's variable length (upto 16k).  The key file is encrypted.  That's why I want to attach the key file to the end of the application, then extract it from the program.

I know this can be done because I have seen it done before.  Example: WinZip self extractor.

If you use that as an example, you'll see what I want to do.

Stu.
It should be easy to just append a few bytes to the end of an exe file...
It does no harm to lengthen an exe... I have done it a few times.

It is a bit problematic though to get your program to read the bytes that have been added to it's length...



But I think that the following is what you really need to try.....


If I wanted to add things to an exe file that it could easily work with I would simply create a string variable and give it a holding value

mykey := 'allowed users is xxx';

then have your program read it's own exe file as I detailed above and
simply look for the string 'allowed users is xxx' and change it to something like 'allowed users is 050' ..... when the program runs it simply checks mykey
to see how many users are allowed :-)

! don't use a string like 'aaaaaaaaaaaaaaaaaaa' to create a string for this purpose because delphi will compress this to a shorter value when it compiles! ... strings with repeated values and identical strings are compressed to save space.




Here is a very simple program that shows what I'm getting at

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Buttons;

type
  TForm1 = class(TForm)
    SpeedButton1: TSpeedButton;
    procedure SpeedButton1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  mykey: string;

implementation

{$R *.DFM}

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
mykey := 'hello world';
speedbutton1.caption := mykey;
end;

end.



If you compile this to an exe and run it it simply displays 'hello world' as the caption of the button when you click it.... you can use a hex editor to find the string 'hello world' inside the exe file ... then change it to something else like 'hello there' and save it.. when you run the program now it displays 'hello there'

It is easy to make the program do this sort of simple alteration to it's own exe...and even simpler to write a small stand alone exe that does this to other exe files... it's like a simple patcher program....just use ordinary file handling techniques to search for the string to change and to alter the file :-)
I must admit that I didn't read all the comments, just my 2 cents:

http://www.undu.com/Articles/990212d.html

Regards, Madshi.
Hi Madshi,

How's it going?  Thanks for the URL.  I'll check it out and get back too you.

Stu.
>> How's it going?

Thanx for asking...   :-)   Not much fun now. Have to learn for my remote study.
Hello Stuart,

Adding a file to the end of the EXE is fairly simple.  The following is an example:


const FileDataHeader : string[10] = '*YourData*' ;
         CtrlZ         : char = ^Z                 ;

type
TFileInfo = record
   FileName : string[12]; //8.3
   FileSize : integer;
   end;


function  AttachFile(ExeName, DataFileName:string):boolean;

var f    : file ;
    size : DWord;
    data : pointer;

begin
AttachFile := false;
Size := FileSizeof(DataFileName);
AssignFile(f, DataFileName);

try
   GetMem(data, size);
   FileMode := 0; //Read only
   reset(f,1);
   BlockRead(f, Data^,Size);

   assign(f,ExeName);
   FileMode := 2        ;{Allow Read and Write}
   reset(f,1);
   Seek(f,FileSize(f));

   BlockWrite(f,FileDataHeader,SizeOf(FileDataHeader));
   BlockWrite(f, Data^,Size);

//write file name and size to the end, so that you can extract the
//file correctly.
   FileInfo.FileName := ExtractFileName(DataFileName);
   FileInfo.FileSize := Size;
   BlockWrite(f, FileInfo, sizeof(FileInfo));
   BlockWrite(f,CtrlZ,1);
   Result := true;
finally
   FreeMem(Data);
   close(f);
   end;
end;


//and you'll extract the file using a proc similar to this.

function  ExtractFile(ExeFile, DataFile:String; FSize:dword): boolean;

var     f: file;
        Data : pointer;

begin
Result := false;

assign(f,ExeFile);
reset(f,1);
seek(f,  FileSize(f)-(SizeOf(FileDataHeader)+1));
BlockRead(f ,Buffer,SizeOf(FileDataHeader));
if (Buffer <> FileDataHeader) then exit ;//not found ?
close(f);

try
    GetMem(Data, FSize);
    assign(f,ExeFile);
    reset(f,1);
    seek(f,FileSize(f)-(FSize+1)-(SizeOf(FileDataHeader));
    BlockRead(f,Data^,FSize);
    CloseFile(f); //TFileRec

    AssignFile(f, DataFile);
    FileMode := 1;
    ReWrite(f, 1);
    BlockWrite(f, Data^, FSize);
    Result := true;
    finally
      CloseFile(f);
      FreeMem(Data);
      end;
end;

//please note that i've "extracted" the above code from a .pas file. the code might need minor fixes.
and btw, contrary to what simonet said, an EXE can delete itself (either via another file, or during next reboot).
My opinion is to use external file to save and read the Key, and hide this key in a directory such as Windows\System

Motaz
Hi Madshi,

I just checked out that page, and although the reading is very good, it does not quite seem to be the answer I am looking for.  I guess it does sort of, but not really.  I'll have a proper read tomorrow and follow some of the links to see what else is on there.

Good luck with your studying!

ahalya: That seems excellent!  I'll check it out in the morning and see how it goes.

I see your point with the deleting of the file, but I also see Alex's interpretation.  I read it the same way - the file can delete itself.  I always delete unused files in the next reboot.

Thanks all.

Stu.
An application can delete itself, by launching this batchfile -- hidden, of course -- and then terminating:

(File to kill is passed as parameter)

-- killer.bat ---------------
@echo off
:dokill
del %1 > nul
if exists %1 goto dokill
rem File has been deleted
del killer.bat^Z
-----------------------------

This batch file will try to delete the give file until it succeeds, which is possible once the program exits.
The batch file then deletes itself, but make sure there is NO ENTER after the last line, just the EOF character (I used ^Z to display it).
About the key: You can (1) put it in the registry (encrypted of course) at some obscure location, or (2) in the \WINDOWS or \WINDOWS\SYSTEM directory with a silly name like bvcxzuy.jkl. On second thoughts, give it a .sys or .dll or .vxd extension: Thanks to M$ everyone takes these files for granted! :-)
It is possible to add files directly from the Delphi IDE, makind the process easier than all the other solutions.

I wrote a component able to do that. It uses the DefineProperties method to achieve this result.
It can be found on www.delphipages.com, looking for my name (Guillien). The name of the component is TRessourceStore.

Regards,

Alexandre Guillien
Hiding the key was never an issue.  It can be called "THIS IS YOUR SECURITY KEY" if we wanted to.  They key has nothing to do with people copying the software - it prevents them from watching MPEG streams which they are not licenced for.

Deleting the EXE is not a problem either because I don't want to do it that way.

And as I said before, I do NOT want to use Delphi for this.  I want it to be a stand alone application.  It is admin staff who will be making the key and the distribution program, not a programmer, so it has to be simple.

Stu.
Adjusted points from 100 to 200
ahalya.  Your code looks interesting.  I have had a quick read through it and have a question.  Correct me if I am wrong, but you cant actually use Rewrite/Reset on an open file can you?  It returns a share error (or something like that).  The code that I am after must be able to extract the keyfile from it's own application (like WinZIP SE does).

I am going to increase the points on this because I really need an answer soon.  ahalya, your code is the closest to what I want, but I still need to know how to extract the stuff from the end of the EXE while it is running.

Cheers,

Stu.
ASKER CERTIFIED SOLUTION
Avatar of ahalya
ahalya
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi ahalya,

Yeah, that would be fantastic.  Can you email me at jonstu@acay.com.au?  I'd appreciate it!

Cheers,

Stu.
Siva,

Thank you very much!  What you sent me was perfect and worked first time without modification.  I can almost use what you have given me without changing anything.  I will just build a new front end for it.

Thanks VERY much!

All the best,


Stuart.
Hi ahalya :-)

Would you please send me those two project files ?
I'd love to see them..

gwena@gurlmail.com
Staurt:  Glad it Helped.
Gwena: Have sent them to you a few minues ago.
To the person who sent me an email about this question today.  I'm sorry, but I accidently deleted your email.  I am also sorry, but I no longer have the source code.  Maybe you could post a comment here and ask ahalya if they still have the source code at all.

Sorry about that.

Stuart.
Hi! I recently purchased this question and would like to know if maybe ahalya, Gwena, or Stuart could send me the sample code mentioned. Thanks! My e-mail address is delfreak@thedoghousemail.com
Please help me out! I really need that source code. I would really appreciate it if you would. Thank you!
It would be really good if like DelFreak says, somebody posted that source code, it sounds very interesting.
Hi frangers99 :-)
  Golly it's been a long time ago that I looked at this Q.
I'm afraid I don't have the files any longer... but there are a few demos on my web site that may be of interest...the self-modifying exe stuff may be the sort of thing you want... using it you could have an exe modify itself and add just about anything to itself...all while appearing to the user to do it as it is running... no restart of windows needed.... and like ahalya said ..it is indeed possible for an exe to delete itself... I like to do it by having the exe spawn new and modified versions of itself that then do the job...

http://delphi.does.it
Hi DelFreak,

I dont have the source anymore as it was a project I did for a company I worked for over a year ago.  Alex may still have he source.  The answer posted was too large to post on here from memory.

Stu.