(在Windows 8上工作) 我试图用c语言在exe文件(PE32格式)中获取节头的大小。 从我读到的,这个字段的偏移是60,所以我试着从那里读。
这是我使用的代码:
unsigned char offset;
fseek(file, 60, SEEK_SET);
fread(&offset, sizeof(offset), 1, file);
printf("%hu", offset);
我的问题是如何获得节标题的大小?如果它不在偏移60,我怎么能找到这个?
答案 0 :(得分:2)
这应该有效:
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) ;
}
答案 1 :(得分:0)
尝试使用fread而不是fscanf,并且(正如Joachim所指出的那样)是一个二进制文件,因此请确保您已经以二进制模式打开文件(file = fopen(filename," RB&#34))
答案 2 :(得分:0)
您尝试读取的字段长度为4个字节,但您尝试从那里读取以NULL结尾的字符串。你可能得到了正确的值,但是你打印它就好像它是一个可打印的字符串(也许你期望打印出像“216”或“D8”这样的字符串,但是这些字符串不是存储的字符串。) / p>
可打印字符串包含一系列代码,每个代码代表一个字符(至少用ASCII格式),后跟一个'\ 0'终止符。这就是“%s”scanf / printf格式化选项所处理的内容。但这并不是数据通常存储在二进制文件中的方式。你可以尝试这个来获得你想要的数字:
unsigned int offset;
fseek(file, 60, SEEK_SET);
fread(&offset, sizeof(offset), 1, file);
printf("%u", offset);
使用的最佳名称可能是uint32_t
,但您需要将<inttype.h>
包括在内。
答案 3 :(得分:0)
fscanf()是不合适的 - 它读取ASCII数据,而PE32是二进制格式 - 你想要读取一个32位整数,而不是数字字符串(类似于打印&#34;%s&#34;是一个不合适的格式说明符。
您还必须确保以二进制模式打开文件,否则序列将被翻译为单个,而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 ) ;