Solved

Inserting data into exe

Posted on 2004-10-25
317 Views
Last Modified: 2010-04-01
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.
0
Question by:-Thespian-
    16 Comments
     
    LVL 14

    Expert Comment

    by:RichieHindle
    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.
    0
     
    LVL 5

    Author Comment

    by:-Thespian-
    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).
    0
     
    LVL 14

    Expert Comment

    by:RichieHindle
    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.
    0
     
    LVL 5

    Author Comment

    by:-Thespian-
    I'll try this. Than I'll post the result.
    0
     
    LVL 5

    Author Comment

    by:-Thespian-
    It doesn't work. Maybe, you have the source example?
    0
     
    LVL 14

    Expert Comment

    by:RichieHindle
    No, sorry.  As I said, it's untested.
    0
     
    LVL 5

    Author Comment

    by:-Thespian-
    I have increased the point value.
    0
     
    LVL 14

    Expert Comment

    by:RichieHindle
    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);
       free(Data);
       fclose(Exe);  
       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);
       fclose(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".
    main

    ********

    (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-)
    0
     
    LVL 5

    Author Comment

    by:-Thespian-
    About points - OK.
    BUT.

    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.
    0
     
    LVL 14

    Expert Comment

    by:RichieHindle
    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.
    0
     
    LVL 5

    Author Comment

    by:-Thespian-
    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.
    0
     
    LVL 14

    Expert Comment

    by:RichieHindle
    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.
    0
     
    LVL 5

    Author Comment

    by:-Thespian-
    > 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.
    0
     
    LVL 14

    Expert Comment

    by:RichieHindle
    > 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.
    0
     
    LVL 14

    Accepted Solution

    by:
    -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.
    0
     
    LVL 5

    Author Comment

    by:-Thespian-
    Sorry me for not responding long. I have work with another project. Thanks all and exspecially "RichieHindle".
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone. Privacy Policy Terms of Use

    Featured Post

    How your wiki can always stay up-to-date

    Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
    - Increase transparency
    - Onboard new hires faster
    - Access from mobile/offline

      Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
    Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
    The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
    The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

    877 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    13 Experts available now in Live!

    Get 1:1 Help Now