Inserting data into exe

Hi, everyone!

      I have made the program #1 that must show the user some string, but I don't knew what it will be the string and it's length can be unlimited.
      Another my program (#2) must change the string in #1 to what the user give it.

      Where can I write the segment of data in #1 without breaking asm directives?

      The problem is that I have a piece of data in prg#1 that must be loaded from exe file when the program starts (maybe as array or something).

Thank you.
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

You can simply append data to the end of the .exe file (I assume you're talking about Windows here).  Windows doesn't care about data appended like that - it's how self-extracting archives work, for example.

To make it easy to find the data when you need to read it back in, precede it with a marker string that you can search for.

Or alternatively, write the file offset of the data into the last 4 bytes of the file, then read those bytes and seek to that offset to read the appended data, then strip off the 4 bytes from what you read.
-Thespian-Author Commented:
The metter is that I have an upx-packed copy on the disk. So:
1. I change that data in #1.
2. I pack #1 with upx, so I can't read the data in file on disk.

I want to load data in memory with the loading of exe (as exe#1 internal data).
I wish you'd said up front that you were using upx.

Here's an idea:
 o Append the data to the .exe, and note its offset
 o Write the offset at position 112 in the .exe file (more on that below)
 o At runtime, the executable image should live at address 0x1000000 (or possibly some other fixed address used by upx).
 o Add 112 to 0x1000000 to get 0x1000070, and read the data offset from there.
 o Add that offset to 0x1000000 to get the address of the data.

That's untested.  The unknown factors are:
 o Whether upx always puts an image of the executable file at 0x1000000 (or some other fixed offset, which is also OK but you need to find out what it is)
 o Whether upx will get upset that you've appended data to the executable (it's easy to test this - use upx to compress a self-extracting archive)

Position 112 is within the DOS stub, which only gets used if you try to run the program under DOS (meaning *real* DOS - a Command Prompt doesn't count).  That position is within the error message - you could write in a shorter error message instead, if you're worried about people running the program under DOS.
Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

-Thespian-Author Commented:
I'll try this. Than I'll post the result.
-Thespian-Author Commented:
It doesn't work. Maybe, you have the source example?
No, sorry.  As I said, it's untested.
-Thespian-Author Commented:
I have increased the point value.
OK, here's something that works.  The system looks like this:

 o The main program, main.exe, is compressed with upx
 o The modifyer program, modifiy.exe, appends the data to the compressed main.exe and then appends the offset of the data after that.
 o When main.exe runs, it opens the main.exe file for reading and reads the pointer to the data from the last 4 bytes of the file.
 o Following that pointer, it reads the data.

This system works with or without upx.  Here's a self-contained example:

**** main.c ****

#include "stdio.h"
#include "windows.h"

int main(void)
   FILE* Exe = NULL;
   DWORD PointerOffset = 0;
   DWORD DataOffset = 0;
   long DataSize = 0;
   char* Data = NULL;
   char ExeFilename[MAX_PATH];

   /* Open the executable file. */
   GetModuleFileName(0, ExeFilename, MAX_PATH);
   Exe = fopen(ExeFilename, "rb");

   /* The 4-byte pointer to the data is at the end of the exe file. */
   fseek(Exe, -4, SEEK_END);
   PointerOffset = ftell(Exe);
   fread(&DataOffset, 4, 1, Exe);
   /* The data goes from its offset to the pointer */
   DataSize = PointerOffset - DataOffset;
   Data = malloc(DataSize);
   fseek(Exe, DataOffset, SEEK_SET);
   fread(Data, DataSize, 1, Exe);
   MessageBox(0, Data, "Hello!", MB_ICONINFORMATION);
   return 0;

**** modify.c ****

/* Usage: modify "The string to add to main.exe" */

#include "stdio.h"
#include "windows.h"

int main(int argc, char* argv[])
   long DataOffset = 0;
   /* Open main.exe and note the offset of the end of the file. */
   FILE* MainExe = fopen("main.exe", "r+b");
   fseek(MainExe, 0, SEEK_END);
   DataOffset = ftell(MainExe);
   /* Write the given string to the end of the file. */
   fputs(argv[1], MainExe);
   fputc(0, MainExe);
   /* Write the offset of the data after the data itself. */
   fwrite(&DataOffset, 4, 1, MainExe);
   return 0;

**** test.bat ****

rem Build and compress main.exe
cl main.c -link user32.lib
upx main.exe

rem Add some data to main.exe
cl modify.c -link user32.lib
modify "This is a test"

rem Run it - it will pop up a box saying "This is a test".


(If this earns me the points, could you wait until 1st November to award them?  Then they'll count towards earning me free Premium Services for November 8-)
-Thespian-Author Commented:
About points - OK.

I have already made such method. The problem of this - I want that data (block) to be secured with the program. I already have one program that secures exes but I don't want to rewrite it (the same word to word) the second time.
I don't understand what you mean by "secured within the program".  The data is embedded within main.exe.

Do you mean you want it to be encrypted?  In that case, you could make modify.exe encrypt the data, and then make main.exe decrypt it when it reads it.
-Thespian-Author Commented:
I understand it. BUT:

I have one program that decrypts exe's with some data. I don't want to write the duplicate of this program only for data. I need to insert some block into compiled exe as its own data.
You've completely lost me.  "I need to insert some block into compiled exe as its own data."  I've shown you exactly how to do that.  You wanted it to work with upx, and it does.  You seem to have some other requirements that you haven't stated.
-Thespian-Author Commented:
> I've shown you exactly how to do that.
  It is not exactly that. To read that data I must have access to it on disk. I want such scheem:
- Compile main.exe;
- Adding data with modify.exe;
- Packing with upx or ASPack (it will be my own crypter);
- Executing packed exe and showing data to user.

Maybe, I haven't tell this at the beginning.
> Maybe, I haven't tell this at the beginning.

It would have been very helpful if you had.

The only readily-available program I can think of that can do what you want is a linker.  Compile main.obj, making a reference to the data like this:

  extern const char* data;
  extern const int data_len;

main.c can then contain code that references the data and its length.

Then write a modify.exe that converts your data into a C source file that looks like this:

  const char* data = "This is my data";
  const int data_len = 15;

You can then compile that source file into an object file data.obj, and link it with main.obj to produce main.exe.  Then you can pack the whole thing using upx or ASPack.
-Thespian-: For what it's worth, I believe I've answered the question.  I've posted working code that achieves exactly what the poster asked for, and which will be useful to others if/when this question becomes a PAQ.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
-Thespian-Author Commented:
Sorry me for not responding long. I have work with another project. Thanks all and exspecially "RichieHindle".
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.