• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 305
  • Last Modified:

Reading binary info from file

i wanna read this "box.exe" file but cant figure out how i have something like so:


 FILE *stream;
   int i;
   int mask = 0x00FF;

   if( (stream = fopen( "Box.exe", "rb" )) == NULL )
      printf( "Couldn't open file\n" );
   else
   {
      /* Read a word from the stream: */
      i = _getw( stream );

      /* If there is an error... */
      if( ferror( stream ) )
      {
         printf( "_getw failed\n" );
         clearerr( stream );
      }
      else
         printf( "First data word in file: 0x%x\n", i);
      fclose( stream );
   }

this gives the value in hex but it is reversed it gives :
0x905A4D should be 0x4D5A90   ?
0
scooter1
Asked:
scooter1
  • 5
  • 3
  • 2
  • +1
1 Solution
 
sdussingerCommented:
This sounds like an endian issue. By reading an integer, you're telling the OS to apply constraints about how integers are stored. On some machines integers are stored with the high-byte first on others they are stored with the low-byte first.  When a machine reads an integer from storage, it interprets the bytes as an integer based on whether its a big-endian or little-endian machine.

Try this:

FILE *stream;
int i;
int mask = 0x00FF;

if( (stream = fopen( "Box.exe", "rb" )) == NULL )
   printf( "Couldn't open file\n" );
else
{
  // Read the four bytes and place them into the int.
  // By doing it this way, the OS can't know that we're
  // actually reading an int, so no endian modifications
  // will be made.
  int bytes = fread ((void *) &i, 1, sizeof (int), stream);

  if (ferror (stream) || bytes != sizeof (int))
  {
    printf ("fread failed");
    clearerr (stream);
  }
  else
    printf ("First data word in file: 0x%x\n", i);

  fclose( stream );
}

This allows us to read the first four bytes of the file without the OS doing it's endian constraints.

HTH.

--Steve
0
 
scooter1Author Commented:
that yields same results
0
 
scooter1Author Commented:
that yields same results
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
sdussingerCommented:
How are you reading the first four bytes to know what the order should be?

--Steve
0
 
scooter1Author Commented:
hex editor
0
 
sdussingerCommented:
It's been a while since I messed with this stuff...

The bytes are being read in correctly. I modified the code I posted earlier to display the bytes individually, and they come out in the order one would expect.

I created a dummy file with the letters ABCD in it, and read it using the code from earlier. When printing out the bytes individually I get 0x41 0x42 0x43 0x44. This is what I expected to see. When I print out the int using the %x I get 0x44434241. Backwards.

The problem must be then when the %x accesses the 4 bytes. It's performing the endian modifications and swapping the bytes.

Unfortunately, using a hex editor to look at the file doesn't always get you what you want. Because of the endian stuff, the order which the bytes are stored on disk may be different from the way they are interpreted as ints, etc.

The real question is what do you need to do with this information your read from the file? In order to compare the info read in from the file, you'll need to compare the bytes 1-by-1 or use some sort of endian-mapping macros to figure out the order of bytes. There is a whole set of macros in the GCC compiler to handle endian-ness, maybe they could help you.

Unfortunately, I'm a little rustier than I thought with this stuff. :-(

--Steve
0
 
scooter1Author Commented:
how did you print out the bytes individually?
0
 
BlackDiamondCommented:
scooter,
In order to avoid the endian problems (as sdussinger pointed out this is), you need to avoid the built in data types.  These types will automatically be swapped in memory to the native endian order.  The way to avoid this is to allocate your own memory, and handle the information byte by byte. This way you are guaranteed to get the information in Big Endian, no matter which platform you are on.  Here is a modified example of your code..


   FILE *stream;
   int i;
   unsigned char * bytes;
   int mask = 0x00FF;

   if( (stream = fopen( "Box.exe", "rb" )) == NULL )
      printf( "Couldn't open file\n" );
   else
   {
      /* Read a word from the stream: */
      //i = _getw( stream );
     
      /* Create my own "integer" instead */
      bytes = malloc(sizeof(int));
      fread(bytes, sizeof(int), 1, stream);


      /* If there is an error... */
      if( ferror( stream ) )
      {
         printf( "_getw failed\n" );
         clearerr( stream );
      }
      else
      {
         printf( "First data word in file: ");
         /* Print the info byte by byte */
         printhex(bytes,sizeof(int));
         printf("\n");
      }
      fclose( stream );
      free(bytes);
   }
}

void
printhex(unsigned char * bytes, int length)
{
   int count;

   for (count = 0;count<length;count++)
   {
      printf("0x%x ",bytes[count]);
   }
}
0
 
BlackDiamondCommented:
Just as a side note, you will now get the data in exactly the order it is stored, but if you need to do any data manipulation or calculations, you will need to be very careful of your byte ordering.

Good Luck,
BD
0
 
jkrCommented:
You have to re-arrange the byte order using the appropriate function:


#include <winsock.h>

//...

int bytes = fread ((void *) &i, 1, sizeof (int), stream);

//...

/*
The Windows Sockets ntohl function converts a u_long from TCP/IP network order to host byte order (which is big-endian).
*/

i = ntohl ( i);
0
 
scooter1Author Commented:
So what i ended up doing is:

 FILE *stream;
 
   if( (stream = fopen( line, "rb" )) != NULL )
   {
       /* read in 1 character*/
       numread = fread( list, sizeof(unsigned char ), 1, stream );

        for(double x = 0; x < numbytes; x++)
        {
         fprint(stream2,"%.2x%c",list[0],' ');

          /* read in 1 character*/
         numread += fread( list, sizeof(unsigned char ), 1, stream );
    }
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

  • 5
  • 3
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now