我正在制作一個程式來用 C 決議 PE 結構。我將把它帶入二進制檔案并決議它的長度。示例)DOS 標頭的長度為 0x40(64) 位元組,因此我嘗試從 to 接近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'
感謝您閱讀我的問題。祝你有美好的一天!
uj5u.com熱心網友回復:
您正在讀取一個二進制檔案,一個unsigned char陣列似乎正是您所需要的。
請注意,該作業似乎不需要分配一個額外的位元組,因為您不是從檔案內容創建 C 字串。
將 PE 頭的內容作為單個位元組讀取是最好的可移植方法:頭資料具有特定的布局,由于對齊和位元組順序問題,C 結構可能無法正確匹配該布局。
檢查簽名后,您應該從標頭中的已知偏移量中提取相關值,并使用適當的整數算術構造檔案偏移量。
DOS Header 長 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 位小端整數和LONG32 位小端整數。
這是修改后的版本:
#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 %s\n", 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 %s\n", filename);
fclose(fp);
return -1;
}
size = length;
if (size < 64) {
fprintf(stderr, "file %s too short, size=%lu\n", filename, size);
fclose(fp);
return -1;
}
#if LONG_MAX > SIZE_MAX
if (size > SIZE_MAX) {
fprintf(stderr, "file %s too large, size=%lu\n", filename, size);
fclose(fp);
return -1;
}
#endif
if ((binary_buf = malloc(size)) == NULL) {
fprintf(stderr, "Error allocating %lu byte buffer for file %s\n", size, filename);
fclose(fp);
return -1;
}
if (fread(binary_buf, 1, size, fp) != size) {
fprintf(stderr, "Error reading file %s\n", 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 signature\n", 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 %s\n", offset, size, filename);
free(binary_buf);
fclose(fp);
return -1;
}
printf("new executable offset: %lu\n", offset);
[...]
free(binary_buf);
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/456847.html
上一篇:將數字讀入陣列并排序
下一篇:檢查是否設定了N(大)位
