在 C Lang 中读取文件时,使用 "rb" 属性读取的文件的数据类型是什么?



我正在制作一个用C解析PE结构的程序。示例(DOS标头是0x40(64(字节长,所以我尝试从binary_buf[0]binary_buf[39]处理它。我应该读取什么数据类型的文件?

我不知道该写什么,因为无论我使用int还是char都是一样的。如果你能告诉我为什么我应该使用这种数据类型,我将不胜感激。

unsigned char *binary_buf = NULL; 
fp = fopen(filename, "rb"); 
if (fp == NULL) {
printf("이 파일은 열 수 없습니다.n");
return 0;
}
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fseek(fp, 0, SEEK_SET);
binary_buf = malloc(size+1);
fread(binary_buf, 1, size, fp);
fclose(fp);
printf("%d", binary_buf[0]); //77 = 0x4D == 'M'

谢谢你阅读我的问题。祝你今天过得愉快!

您正在读取一个二进制文件,unsigned char数组似乎正是您所需要的。

请注意,分配一个额外的字节似乎不是这个作业所必需的,因为您不是从文件内容创建C字符串。

将PE头的内容读取为单个字节是最好的可移植方法:由于对齐和端序问题,头数据的特定布局可能无法由C结构正确匹配。

检查签名后,应该从标头中的已知偏移量中提取相关值,并使用适当的整数算法构造文件偏移量。

DOS标题为64字节长,布局如下:

typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
WORD   e_magic;                     // Magic number
WORD   e_cblp;                      // Bytes on last page of file
WORD   e_cp;                        // Pages in file
WORD   e_crlc;                      // Relocations
WORD   e_cparhdr;                   // Size of header in paragraphs
WORD   e_minalloc;                  // Minimum extra paragraphs needed
WORD   e_maxalloc;                  // Maximum extra paragraphs needed
WORD   e_ss;                        // Initial (relative) SS value
WORD   e_sp;                        // Initial SP value
WORD   e_csum;                      // Checksum
WORD   e_ip;                        // Initial IP value
WORD   e_cs;                        // Initial (relative) CS value
WORD   e_lfarlc;                    // File address of relocation table
WORD   e_ovno;                      // Overlay number
WORD   e_res[4];                    // Reserved words
WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
WORD   e_oeminfo;                   // OEM information; e_oemid specific
WORD   e_res2[10];                  // Reserved words
LONG   e_lfanew;                    // File address of new exe header
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

其中WORD是16位小端数整数,LONG是32位小端整数。

这是一个修改版本:

#include <limits.h>
#include <stdio.h>
int read_PE_file(const char *filename) {
unsigned char *binary_buf = NULL; 
FILE *fp = fopen(filename, "rb"); 
if (fp == NULL) {
fprintf(stderr, "Error opening file %sn", filename);
return -1;
}
fseek(fp, 0, SEEK_END);
long length = ftell(fp);
unsigned long size;
fseek(fp, 0, SEEK_SET);
if (length < 0) {
fprintf(stderr, "Error seeking file %sn", filename);
fclose(fp);
return -1;
}
size = length;
if (size < 64) {
fprintf(stderr, "file %s too short, size=%lun", filename, size);
fclose(fp);
return -1;
}
#if LONG_MAX > SIZE_MAX
if (size > SIZE_MAX) {
fprintf(stderr, "file %s too large, size=%lun", filename, size);
fclose(fp);
return -1;
}
#endif
if ((binary_buf = malloc(size)) == NULL) {
fprintf(stderr, "Error allocating %lu byte buffer for file %sn", size, filename);
fclose(fp);
return -1;
}
if (fread(binary_buf, 1, size, fp) != size) {
fprintf(stderr, "Error reading file %sn", filename);
free(binary_buf);
fclose(fp);
return -1;
}
fclose(fp);
if (binary_buf[0] != 0x4D || binary_buf[1] != 0x5A) {
fprintf(stderr, "File %s does not have MZ signaturen", filename);
free(binary_buf);
fclose(fp);
return -1;
}
unsigned long offset = binary_buf[60] +
(binary_buf[61] << 8) + 
((unsigned long)binary_buf[62] << 16) + 
((unsigned long)binary_buf[63] << 24);

if (offset > size) {
fprintf(stderr, "new executable offset %lu greater than file size %lu for file %sn", offset, size, filename);
free(binary_buf);
fclose(fp);
return -1;
}
printf("new executable offset: %lun", offset);
[...]
free(binary_buf);
return 0;
}

最新更新