简体   繁体   English

在C中使用exe文件

[英]Working with exe files in c

(Working on Windows 8) I'm trying to get the size of section headers in an exe file (PE32 Format) with c. (在Windows 8上运行)我正在尝试使用c获取exe文件(PE32格式)中节标题的大小。 From what I read, the offset from this field is 60 so I tried reading from there. 根据我的阅读,该字段的偏移量是60,所以我尝试从那里读取。

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? 如果它不在偏移量60上,我怎么能找到这个?

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) ;   
}

尝试使用fread而不是fscanf,并且(如Joachim所指出的)它是一个二进制文件,因此请确保已以二进制模式打开该文件(file = fopen(文件名,“ rb”))

The field you are trying to read is 4 bytes long, but you are trying to read a NULL terminated string from there. 您尝试读取的字段的长度为4个字节,但是您尝试从此处读取以NULL结尾的字符串。 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). 您可能得到了正确的值,但是随后将其打印为好像是可打印的字符串(也许您希望打印“ 216”或“ D8”之类的东西,但是诸如此类的字符串不是存储的)。

Printable strings contains a sequence of codes, each representing a character (in ASCII, at least), followed by a '\\0' terminator. 可打印的字符串包含一系列代码,每个代码代表一个字符(至少是ASCII),后跟一个'\\ 0'终止符。 This is what "%s" scanf/printf formatting option deals with. 这就是“%s” scanf / printf格式设置选项所处理的。 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. 最好使用的名称可能是uint32_t ,但这要求您包括<inttype.h>才能起作用。

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. fscanf()是不合适的-它读取ASCII数据,而PE32是二进制格式-您想读取单个32位整数,而不是数字字符串(类似地,打印“%s”是不合适的格式说明符。

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. 您还必须确保以二进制模式打开文件,否则,序列将转换为单个文件,而fseek()将无法按预期工作。

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 ) ;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM