读取 PE COFF Header 并获取特征标志
Reading PE COFF Header and getting characteristics flag
我正在尝试从 Windows 上的 PE .exe 文件中读取 COFF header,它工作得很好,直到我到达 header 的特征标志:看起来我读到一个错误的值,因为它没有出现在 here 列出的预期值列表中。
代码:
#include <stdio.h>
#include <stdint.h>
#include <windows.h>
#include <stdlib.h>
typedef struct
{
uint16_t mType;
uint16_t nSections;
uint32_t timeDateStamp;
uint32_t ptrToSymbolTable;
uint32_t nOfSymbols;
uint16_t sizeOfOptionalH;
uint16_t characteristics;
}COFFHeader;
void printHInfos(COFFHeader *header)
{
printf("\n\nCPU Type: ");
switch(header -> mType)
{
case IMAGE_FILE_MACHINE_UNKNOWN:
printf("Cannot determine CPU Target of PE\n");
break;
case IMAGE_FILE_MACHINE_AM33:
printf("Matsushita AM33\n");
break;
case IMAGE_FILE_MACHINE_AMD64:
printf("x64\n");
break;
case IMAGE_FILE_MACHINE_ARM:
printf("ARM Little Endian\n");
break;
case IMAGE_FILE_MACHINE_ARM64:
printf("ARM64 Little Endian\n");
break;
case IMAGE_FILE_MACHINE_ARMNT:
printf("ARM Thumb-2 little endian\n");
break;
case IMAGE_FILE_MACHINE_EBC:
printf("EFI byte code\n");
break;
case IMAGE_FILE_MACHINE_I386:
printf("Intel 386 or later processor\n");
break;
case IMAGE_FILE_MACHINE_IA64:
printf("Intel Itanium processor family\n");
break;
case IMAGE_FILE_MACHINE_M32R:
printf("Mitsubishi M32R Little Endian\n");
break;
case IMAGE_FILE_MACHINE_MIPS16:
printf("MIPS16\n");
break;
case IMAGE_FILE_MACHINE_MIPSFPU:
printf("MIPS with FPU\n");
break;
case IMAGE_FILE_MACHINE_MIPSFPU16:
printf("MIPS16 with FPU\n");
break;
case IMAGE_FILE_MACHINE_POWERPC:
printf("Power PC little endian\n");
break;
case IMAGE_FILE_MACHINE_POWERPCFP:
printf("Power PC with floating point support\n");
break;
case IMAGE_FILE_MACHINE_R4000:
printf("MIPS Little Endian\n");
break;
case IMAGE_FILE_MACHINE_SH3:
printf("Hitachi SH3\n");
break;
case IMAGE_FILE_MACHINE_SH3DSP:
printf("Hitachi SH3 DSP\n");
break;
case IMAGE_FILE_MACHINE_SH4:
printf("Hitachi SH4\n");
break;
case IMAGE_FILE_MACHINE_SH5:
printf("Hitachi SH5\n");
break;
case IMAGE_FILE_MACHINE_THUMB:
printf("Thumb\n");
break;
case IMAGE_FILE_MACHINE_WCEMIPSV2:
printf("MIPS Little-Endian WCE v2\n");
break;
}
printf("Number of sections: %u\n",header->nSections);
printf("Elapsed seconds since 01/01/70 up to file creation: %u\n",header->timeDateStamp);
printf("COFF Symbol Table offset: 0x%02X\n",header->ptrToSymbolTable);
printf("Number of symbols in table: %u\n",header->nOfSymbols);
printf("Size of optional header: %u\n",header->sizeOfOptionalH);
printf("Characteristics flag: 0x%02X",header->characteristics);
return;
}
int main(int argc, char *argv[])
{
uint32_t *headerLoc = malloc(sizeof(uint32_t));
COFFHeader header;
// Finding header offset
FILE *fp = fopen(argv[1],"rb");
fseek(fp, 0x3c, SEEK_SET);
fread(headerLoc,sizeof(uint32_t),1,fp);
fseek(fp, (*headerLoc) + 4, SEEK_SET);
free(headerLoc);
fread(&header, sizeof(COFFHeader), 1, fp);
printHInfos(&header);
fclose(fp);
}
正如我所说,header 的所有字段都打印正确,CPU 目标与我期望的和 yada yada yada 匹配,除了特征字段,有时会出现向上为“0x30F”,有时为“0x10F”等。
该程序可能有什么问题?我认为这可能是字节顺序问题,但事实并非如此。在此先感谢您的帮助。
OS:Win 7 x64,IDE:Code::Blocks,编译器:mingw32-x86_64
您描述的值是位标志,您必须单独确定它们。
即:
0x10F = IMAGE_FILE_RELOCS_STRIPPED|IMAGE_FILE_EXECUTABLE_IMAGE|IMAGE_FILE_LOCAL_SYMS_STRIPPED|IMAGE_FILE_32BIT_MACHINE
0x30f = IMAGE_FILE_RELOCS_STRIPPED|IMAGE_FILE_EXECUTABLE_IMAGE|IMAGE_FILE_LOCAL_SYMS_STRIPPED|IMAGE_FILE_32BIT_MACHINE|IMAGE_FILE_DLL
所以要打印正确的值,您必须使用类似的东西:
if (header->characteristics & IMAGE_FILE_RELOCS_STRIPPED)
printf("IMAGE_FILE_RELOCS_STRIPPED");
if (header->characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)
printf("IMAGE_FILE_EXECUTABLE_IMAGE");
...
我正在尝试从 Windows 上的 PE .exe 文件中读取 COFF header,它工作得很好,直到我到达 header 的特征标志:看起来我读到一个错误的值,因为它没有出现在 here 列出的预期值列表中。 代码:
#include <stdio.h>
#include <stdint.h>
#include <windows.h>
#include <stdlib.h>
typedef struct
{
uint16_t mType;
uint16_t nSections;
uint32_t timeDateStamp;
uint32_t ptrToSymbolTable;
uint32_t nOfSymbols;
uint16_t sizeOfOptionalH;
uint16_t characteristics;
}COFFHeader;
void printHInfos(COFFHeader *header)
{
printf("\n\nCPU Type: ");
switch(header -> mType)
{
case IMAGE_FILE_MACHINE_UNKNOWN:
printf("Cannot determine CPU Target of PE\n");
break;
case IMAGE_FILE_MACHINE_AM33:
printf("Matsushita AM33\n");
break;
case IMAGE_FILE_MACHINE_AMD64:
printf("x64\n");
break;
case IMAGE_FILE_MACHINE_ARM:
printf("ARM Little Endian\n");
break;
case IMAGE_FILE_MACHINE_ARM64:
printf("ARM64 Little Endian\n");
break;
case IMAGE_FILE_MACHINE_ARMNT:
printf("ARM Thumb-2 little endian\n");
break;
case IMAGE_FILE_MACHINE_EBC:
printf("EFI byte code\n");
break;
case IMAGE_FILE_MACHINE_I386:
printf("Intel 386 or later processor\n");
break;
case IMAGE_FILE_MACHINE_IA64:
printf("Intel Itanium processor family\n");
break;
case IMAGE_FILE_MACHINE_M32R:
printf("Mitsubishi M32R Little Endian\n");
break;
case IMAGE_FILE_MACHINE_MIPS16:
printf("MIPS16\n");
break;
case IMAGE_FILE_MACHINE_MIPSFPU:
printf("MIPS with FPU\n");
break;
case IMAGE_FILE_MACHINE_MIPSFPU16:
printf("MIPS16 with FPU\n");
break;
case IMAGE_FILE_MACHINE_POWERPC:
printf("Power PC little endian\n");
break;
case IMAGE_FILE_MACHINE_POWERPCFP:
printf("Power PC with floating point support\n");
break;
case IMAGE_FILE_MACHINE_R4000:
printf("MIPS Little Endian\n");
break;
case IMAGE_FILE_MACHINE_SH3:
printf("Hitachi SH3\n");
break;
case IMAGE_FILE_MACHINE_SH3DSP:
printf("Hitachi SH3 DSP\n");
break;
case IMAGE_FILE_MACHINE_SH4:
printf("Hitachi SH4\n");
break;
case IMAGE_FILE_MACHINE_SH5:
printf("Hitachi SH5\n");
break;
case IMAGE_FILE_MACHINE_THUMB:
printf("Thumb\n");
break;
case IMAGE_FILE_MACHINE_WCEMIPSV2:
printf("MIPS Little-Endian WCE v2\n");
break;
}
printf("Number of sections: %u\n",header->nSections);
printf("Elapsed seconds since 01/01/70 up to file creation: %u\n",header->timeDateStamp);
printf("COFF Symbol Table offset: 0x%02X\n",header->ptrToSymbolTable);
printf("Number of symbols in table: %u\n",header->nOfSymbols);
printf("Size of optional header: %u\n",header->sizeOfOptionalH);
printf("Characteristics flag: 0x%02X",header->characteristics);
return;
}
int main(int argc, char *argv[])
{
uint32_t *headerLoc = malloc(sizeof(uint32_t));
COFFHeader header;
// Finding header offset
FILE *fp = fopen(argv[1],"rb");
fseek(fp, 0x3c, SEEK_SET);
fread(headerLoc,sizeof(uint32_t),1,fp);
fseek(fp, (*headerLoc) + 4, SEEK_SET);
free(headerLoc);
fread(&header, sizeof(COFFHeader), 1, fp);
printHInfos(&header);
fclose(fp);
}
正如我所说,header 的所有字段都打印正确,CPU 目标与我期望的和 yada yada yada 匹配,除了特征字段,有时会出现向上为“0x30F”,有时为“0x10F”等。 该程序可能有什么问题?我认为这可能是字节顺序问题,但事实并非如此。在此先感谢您的帮助。
OS:Win 7 x64,IDE:Code::Blocks,编译器:mingw32-x86_64
您描述的值是位标志,您必须单独确定它们。
即:
0x10F = IMAGE_FILE_RELOCS_STRIPPED|IMAGE_FILE_EXECUTABLE_IMAGE|IMAGE_FILE_LOCAL_SYMS_STRIPPED|IMAGE_FILE_32BIT_MACHINE
0x30f = IMAGE_FILE_RELOCS_STRIPPED|IMAGE_FILE_EXECUTABLE_IMAGE|IMAGE_FILE_LOCAL_SYMS_STRIPPED|IMAGE_FILE_32BIT_MACHINE|IMAGE_FILE_DLL
所以要打印正确的值,您必须使用类似的东西:
if (header->characteristics & IMAGE_FILE_RELOCS_STRIPPED)
printf("IMAGE_FILE_RELOCS_STRIPPED");
if (header->characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)
printf("IMAGE_FILE_EXECUTABLE_IMAGE");
...