Reputation: 536
(Working on Windows 8) I'm trying to get the size of section headers in an exe file (PE32 Format) with c. From what I read, the offset from this field is 60 so I tried reading from there.
This is the code I used:
unsigned char offset;
fseek(file, 60, SEEK_SET);
fread(&offset, sizeof(offset), 1, file);
printf("%hu", offset);
My Question is how can i get the size of the section headers? if its not on offset 60, how can i find this?
Upvotes: 1
Views: 1012
Reputation: 50831
This should work:
void main()
{
FILE *file = fopen("your_exe_file.exe", "rb") ;
long peheaderoffset ;
// read the offset of the PE header which is located at offset 0x3c
fseek(file, 0x3c, SEEK_SET) ;
fread(&peheaderoffset, sizeof(long), 1, file) ;
char PEHeader[4] ; // PE header: contains normally 'P','E',0,0
fseek(file, peheaderoffset, SEEK_SET) ;
fread(&PEHeader, 4, 1, file) ;
short machine ;
short NumberofSections ;
fread(&machine, sizeof(short), 1, file) ; // read machine identifier
fread(&NumberofSections, sizeof(short), 1, file) ; // read Number of sections
printf ("PE Header = %s\n", PEHeader) ; // should always print "PE"
// we should check if PEHEeader actually
// contains "PE". If not it's not a PE file
printf ("machine = %x\n", machine) ; // 14c for Intel x86
printf ("Number of sections = %d\n", NumberofSections) ;
// skip to size of optional header
fseek(file, 12, SEEK_CUR) ;
short SizeOfOptionalHeader ;
fread (&SizeOfOptionalHeader, sizeof(short), 1, file) ;
printf ("Sizeof optional PE header = %d\n", SizeOfOptionalHeader) ;
short characteristics ;
fread (&characteristics, sizeof(short), 1, file) ;
printf ("Characteristics = %x\n", characteristics) ;
// now we are at the PE optional header
short signature ;
fread (&signature, sizeof(short), 1, file) ;
printf ("Signature of optioan PE Header = %d (should be 267)\n", signature) ;
// skip to image Base at offset 0x1c
// (the -2 is because we have already read the signature just above)
fseek(file, 0x1c - 2, SEEK_CUR) ;
long imageBase ;
fread (&imageBase, sizeof(long), 1, file) ;
printf ("Image base = %x\n", imageBase) ;
}
Upvotes: 2
Reputation: 93534
fscanf() is inappropriate - it reads ASCII data, while the PE32 is a binary format - you want to read a single 32bit integer, not a numeric string (similarly for printing "%s" is an inappropriate format specifier.
You also have to be sure to open the file in binary mode, otherwise and sequence will be translated to a single and fseek()
will not work as expected.
uint32_t sizeOfHeaders = 0 ;
FILE* file = fopen( filename, "rb" ) ; // Open in binary mode
fseek( file, 60, SEEK_SET ) ;
fread( &sizeOfHeaders, sizeof(sizeOfHeaders), 1, file ) ;
printf("%u", sizeOfHeaders ) ;
Upvotes: 0
Reputation: 13481
The field you are trying to read is 4 bytes long, but you are trying to read a NULL terminated string from there. You probably got the right value, but then you print it as if it was a printable string (maybe you were expecting something like "216" or "D8" to be printed, but strings such as these are not what is stored).
Printable strings contains a sequence of codes, each representing a character (in ASCII, at least), followed by a '\0' terminator. This is what "%s" scanf/printf formatting option deals with. But that is not how data is usually stored in binary files. You may try this to get the number you want:
unsigned int offset;
fseek(file, 60, SEEK_SET);
fread(&offset, sizeof(offset), 1, file);
printf("%u", offset);
Probably the best name to use would be uint32_t
, but that would require from you to include <inttype.h>
to work.
Upvotes: 0
Reputation: 945
try using fread instead of fscanf, and (as Joachim) pointed out it's a binary file, so make sure you've opened the file in binary mode (file=fopen (filename, "rb"))
Upvotes: 0