-1

a lot of times ago, i found an extract of C code, that could read the content of an executable file and that can store it as an array of char, in another file (ex: output.txt). It should work, but when i tried it, it corrupts the output, and it can't copy exactly the content of the exe as a char without damaging it. I don't know where could be the problem.

This is my extract of code in C

    #include <stdio.h>
    #include <stdlib.h> 
    #include <assert.h>

    int main(int argc, char *argv[]) 
    {

        if(argc != 3)
        {
            fprintf(stderr, "Usage >NameProgram firstParam Executable.exe\n");
            return -1;
        }


        FILE *output = fopen("output.txt", "a");
        [..]

        char* input_file = argv[2]; //the name of the exe
        FILE* f_input = fopen(input_file, "rb");

        fprintf(output,"char byn[] = {\n");

        unsigned long n = 0;
        while(!feof(f_input)) 
        {
            unsigned char c;
            if(fread(&c, 1, 1, f) == 0)
               break;

            fprintf(output,"0x%.2X,", (int)c);
            ++n;

            if(n % 10 == 0)
            fprintf(output,"\n");
         }

         fclose(f_input);
         fclose(output);

         //truncating file
         FILE *output = fopen("output.txt", "r+");

         fseek(output, -1, SEEK_END);
         fprintf(output,"};\n\n");

         fclose(output);
         [..]
usern3t
  • 19
  • 4
  • 2
    http://stackoverflow.com/q/5431941/3185968 – EOF Feb 26 '16 at 17:09
  • Note that the code does actually check the result of `fread()` directly (making the `!feof(f_input)` condition in the loop redundant). – Jonathan Leffler Feb 26 '16 at 18:00
  • 1
    It seems funny to reopen the file just to add the closing `"};\n\n"` string; do that before closing the file. It shouldn't be a cause of your problem, though. – Jonathan Leffler Feb 26 '16 at 18:04
  • Are you running into problems because the operational file length is not a multiple of 128 (256?) bytes and yet the `fread()` scans past the end of file? You're playing with `.exe` files which indicates a Windows system, and the rules for binary files are fiddly. You should really show us what you get that seems to be wrong — maybe the first 3 lines of output and the last 3, if the trouble is visible there. Maybe the trouble isn't in this code; maybe the trouble is in the code that is using this output? Note that it is best to provide an MCVE ([MCVE]) — this is close, but not quite, there. – Jonathan Leffler Feb 26 '16 at 18:06
  • ok thank you @JonathanLeffler you are really helpful. So... i can substitute the `while(!feof(f_input))` with `while(fread(&c, 1, 1, f) != 0)` ? It's correct? I'm not sure how to substitue the `while(!feof(f_input))` because the answer that you posted explains good why it's wrong !feof but not so good how to substitute it. And i'll modify the code to match the requisites – usern3t Feb 26 '16 at 18:35
  • 1
    Yes, `while (fread(&c, 1, 1, f) == 1)` (or `!= 0`) is a correct loop control. – Jonathan Leffler Feb 26 '16 at 18:36

1 Answers1

0

using your posted code as a guide, I produced the following:

#include <stdio.h>
#include <stdlib.h>


int main(int argc, char *argv[])
{

    if(argc != 3)
    {
        fprintf( stderr, "USAGE: %s outFilename inFileName\n", argv[0] );
        exit( EXIT_FAILURE );
    }


    FILE *fp_out = fopen( argv[1], "a");

    FILE* fp_in  = fopen( argv[2], "rb");

    fprintf(fp_out, "char byn[] = {\n" );

    unsigned long n = 0;
    unsigned char c;
    while(fread(&c, 1, 1, fp_in) == 1)
    {
        fprintf( fp_out,"0x%.2X,", (int)c);
        ++n;

        if(n % 10 == 0)
        fprintf( fp_out,"\n");
    }

    fprintf( fp_out, "};\n\n");
    fclose(fp_in);
    fclose(fp_out);

} // end function: main

which I ran on a few executable files

Note: I'm running Ubuntu Linux 14.04

It seems to work correctly.

As with your example, I skipped the error checking (which you should really include in your actual code.)

user3629249
  • 16,402
  • 1
  • 16
  • 17
  • What are the significant differences between your code and the original? I can see that you don't reopen the file to write the trailer to the data, but what else? — I note that if there are, say, 288 bytes in the executable, then the last line of output will have 8 numbers plus the `};` and a couple of newlines. When I care about the output format (which is most of the time), I add the equivalent of `if (n % 10 != 0) putchar('\n');` after the loop. – Jonathan Leffler Feb 27 '16 at 04:56
  • @JonathanLeffler, The main difference is that the code I posted does not clobber the output. I.E. the output is a faithful representation of the input. – user3629249 Feb 27 '16 at 05:42
  • I Found the error! comparing the files with an hex editor i found that the last byte is not copied. It's missing the last 0x00 respect from the original file and there is one ',' more at the end of the file . Finally the solution. – usern3t Feb 27 '16 at 11:34