【C】C语言写的打印PE文件头信息的程序
这是个命令行程序。用法就是用以下命令启动它。PrintPE 某PE文件.后缀
好。直接贴出源代码。大家编译运行一下就知道效果了。
#include<stdio.h>
#include<windows.h>
IMAGE_DOS_HEADER g_DOSH;
IMAGE_FILE_HEADER g_PEH;
const char*pDirTableDesc[]=
{
"Export Directory",
"Import Directory",
"Resource Directory",
"Exception Directory",
"Security Directory",
"Base Relocation Table",
"Debug Directory",
"Architecture Specific Data",
"RVA of GP",
"TLS Directory",
"Load Configuration Directory",
"Bound Import Directory in headers",
"Import Address Table",
"Delay Load Import Descriptors",
"COM Runtime descriptor"
};
void Usage()
{
fputs(
"USAGE:\n"
"PrintPE PEFILE\n",stderr);
}
void ReadDOSH(FILE*fp)
{
fread(&g_DOSH,1,sizeof(g_DOSH),fp);
printf(
"--------------------------------DOS .EXE header--------------------------------\n"
"Magic number:0x%04X\n"
"Bytes on last page of file:0x%04X\n"
"Pages in file:0x%04X\n"
"Relocations:0x%04X\n"
"Size of header in paragraphs:0x%04X\n"
"Minimum extra paragraphs needed:0x%04X\n"
"Maximum extra paragraphs needed:0x%04X\n"
"Initial (relative) SS value:0x%04X\n"
"Initial SP value:0x%04X\n"
"Checksum:0x%04X\n"
"Initial IP value:0x%04X\n"
"Initial (relative) CS value:0x%04X\n"
"File address of relocation table:0x%04X\n"
"Overlay number:0x%04X\n"
"OEM identifier (for e_oeminfo):0x%04X\n"
"OEM information; e_oemid specific:0x%04X\n"
"File address of new exe header:0x%08X\n",
g_DOSH.e_magic, // Magic number
g_DOSH.e_cblp, // Bytes on last page of file
g_DOSH.e_cp, // Pages in file
g_DOSH.e_crlc, // Relocations
g_DOSH.e_cparhdr, // Size of header in paragraphs
g_DOSH.e_minalloc, // Minimum extra paragraphs needed
g_DOSH.e_maxalloc, // Maximum extra paragraphs needed
g_DOSH.e_ss, // Initial (relative) SS value
g_DOSH.e_sp, // Initial SP value
g_DOSH.e_csum, // Checksum
g_DOSH.e_ip, // Initial IP value
g_DOSH.e_cs, // Initial (relative) CS value
g_DOSH.e_lfarlc, // File address of relocation table
g_DOSH.e_ovno, // Overlay number
g_DOSH.e_oemid, // OEM identifier (for e_oeminfo)
g_DOSH.e_oeminfo, // OEM information, e_oemid specific
g_DOSH.e_lfanew); // File address of new exe header
if(g_DOSH.e_crlc)//如果DOS的EXE头有16位EXE的重定向表
{
WORD wRelocs=g_DOSH.e_crlc;
DWORD*pdwRelocTable=(DWORD*)malloc(sizeof(DWORD)*wRelocs);
fseek(fp,g_DOSH.e_lfarlc,SEEK_SET);//转到16位EXE的重定向表
printf("DOS Relocations:\n");
if(pdwRelocTable)
{
DWORD*pPtr=pdwRelocTable;
fread(pdwRelocTable,1,sizeof(DWORD)*wRelocs,fp);
while(wRelocs--)
{
printf("0x%08X:0x%08X\n",(*pPtr>>16)&0xFFFF,*pPtr&0xFFFF);
pPtr++;
}
free(pdwRelocTable);
}
else
{
DWORD dwReloc;
while(wRelocs--)
{
fread(&dwReloc,1,sizeof(dwReloc),fp);
printf("0x%08X:0x%08X\n",(dwReloc>>16)&0xFFFF,dwReloc&0xFFFF);
}
}
}
}
void ReadPEH(FILE*fp)
{
fread(&g_PEH,1,sizeof(g_PEH),fp);
fputs(
"----------------------------------PE Header------------------------------------\n"
"Machine:",stdout);
switch(g_PEH.Machine)
{
default:
case IMAGE_FILE_MACHINE_UNKNOWN:
fputs("Unknown machine type\n",stdout);
break;
case IMAGE_FILE_MACHINE_I386:
fputs("Intel 386.\n",stdout);
break;
case IMAGE_FILE_MACHINE_R3000:
fputs("MIPS little-endian, 0x160 big-endian\n",stdout);
break;
case IMAGE_FILE_MACHINE_R4000:
fputs("MIPS little-endian\n",stdout);
break;
case IMAGE_FILE_MACHINE_R10000:
fputs("MIPS little-endian\n",stdout);
break;
case IMAGE_FILE_MACHINE_WCEMIPSV2:
fputs("MIPS little-endian WCE v2\n",stdout);
break;
case IMAGE_FILE_MACHINE_ALPHA:
fputs("Alpha_AXP\n",stdout);
break;
case IMAGE_FILE_MACHINE_POWERPC:
fputs("IBM PowerPC Little-Endian\n",stdout);
break;
case IMAGE_FILE_MACHINE_SH3:
fputs("SH3 little-endian\n",stdout);
break;
case IMAGE_FILE_MACHINE_SH3E:
fputs("SH3E little-endian\n",stdout);
break;
case IMAGE_FILE_MACHINE_SH4:
fputs("SH4 little-endian\n",stdout);
break;
case IMAGE_FILE_MACHINE_ARM:
fputs("ARM Little-Endian\n",stdout);
break;
case IMAGE_FILE_MACHINE_THUMB:
fputs("Thumb\n",stdout);
break;
case IMAGE_FILE_MACHINE_IA64:
fputs("Intel 64\n",stdout);
break;
case IMAGE_FILE_MACHINE_MIPS16:
fputs("MIPS 16\n",stdout);
break;
case IMAGE_FILE_MACHINE_MIPSFPU:
fputs("MIPS FPU\n",stdout);
break;
case IMAGE_FILE_MACHINE_MIPSFPU16:
fputs("MIPS FPU 16\n",stdout);
break;
case IMAGE_FILE_MACHINE_ALPHA64:
fputs("ALPHA64\n",stdout);
break;
}
printf(
"Number of sections:0x%04X\n"
"Time date stamp:0x%08X\n"
"Pointer to symbol table:0x%08X\n"
"Number of symbols:0x%08X\n"
"Size of optional header:0x%04X\n"
"Characteristics:0x%04X\n",
g_PEH.NumberOfSections,
g_PEH.TimeDateStamp,
g_PEH.PointerToSymbolTable,
g_PEH.NumberOfSymbols,
g_PEH.SizeOfOptionalHeader,
g_PEH.Characteristics);
if(g_PEH.Characteristics&IMAGE_FILE_RELOCS_STRIPPED)
fputs("\tRelocation info stripped from file.\n",stdout);
if(g_PEH.Characteristics&IMAGE_FILE_EXECUTABLE_IMAGE)
fputs("\tFile is executable(i.e. no unresolved externel references).\n",stdout);
if(g_PEH.Characteristics&IMAGE_FILE_LINE_NUMS_STRIPPED)
fputs("\tLine numbers stripped from file.\n",stdout);
if(g_PEH.Characteristics&IMAGE_FILE_LOCAL_SYMS_STRIPPED)
fputs("\tLocal symbols stripped from file.\n",stdout);
if(g_PEH.Characteristics&IMAGE_FILE_AGGRESIVE_WS_TRIM)
fputs("\tAgressively trim working set\n",stdout);
if(g_PEH.Characteristics&IMAGE_FILE_LARGE_ADDRESS_AWARE)
fputs("\tApp can handle >2gb addresses\n",stdout);
if(g_PEH.Characteristics&IMAGE_FILE_BYTES_REVERSED_LO)
fputs("\tBytes of machine word are reversed.\n",stdout);
if(g_PEH.Characteristics&IMAGE_FILE_32BIT_MACHINE)
fputs("\t32 bit word machine.\n",stdout);
if(g_PEH.Characteristics&IMAGE_FILE_DEBUG_STRIPPED)
fputs("\tDebugging info stripped from file in .DBG file\n",stdout);
if(g_PEH.Characteristics&IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP)
fputs("\tIf Image is on removable media, copy and run from the swap file.\n",stdout);
if(g_PEH.Characteristics&IMAGE_FILE_NET_RUN_FROM_SWAP)
fputs("\tIf Image is on Net, copy and run from the swap file.\n",stdout);
if(g_PEH.Characteristics&IMAGE_FILE_SYSTEM)
fputs("\tSystem File.\n",stdout);
if(g_PEH.Characteristics&IMAGE_FILE_DLL)
fputs("\tFile is a DLL.\n",stdout);
if(g_PEH.Characteristics&IMAGE_FILE_UP_SYSTEM_ONLY)
fputs("\tFile should only be run on a UP machine\n",stdout);
if(g_PEH.Characteristics&IMAGE_FILE_BYTES_REVERSED_HI)
fputs("\tBytes of machine word are reversed.\n",stdout);
}
void ReadOPT32(FILE*fp,IMAGE_OPTIONAL_HEADER32*pOPT32)
{
UINT uDirEntry;
printf(
"Major linker version:0x%02X\n"
"Minor linker version:0x%02X\n"
"Size of code:0x%08X\n"
"Size of initialized data:0x%08X\n"
"Size of uninitialized data:0x%08X\n"
"Address of entry point:0x%08X\n"
"Base of code:0x%08X\n"
"Base of data:0x%08X\n"
"Image base:0x%08X\n"
"Section alignment:0x%08X\n"
"File alignment:0x%08X\n"
"Major operating system version:0x%04X\n"
"Minor operating system version:0x%04X\n"
"Major image version:0x%04X\n"
"Minor image version:0x%04X\n"
"Major subsystem version:0x%04X\n"
"Minor subsystem version:0x%04X\n"
"Win32 version value:0x%08X\n"
"Size of image:0x%08X\n"
"Size of headers:0x%08X\n"
"Check sum:0x%08X\n"
"Subsystem:0x%04X\n",
pOPT32->Magic,
pOPT32->MajorLinkerVersion,
pOPT32->MinorLinkerVersion,
pOPT32->SizeOfCode,
pOPT32->SizeOfInitializedData,
pOPT32->SizeOfUninitializedData,
pOPT32->AddressOfEntryPoint,
pOPT32->BaseOfCode,
pOPT32->BaseOfData,
pOPT32->ImageBase,
pOPT32->SectionAlignment,
pOPT32->FileAlignment,
pOPT32->MajorOperatingSystemVersion,
pOPT32->MinorOperatingSystemVersion,
pOPT32->MajorImageVersion,
pOPT32->MinorImageVersion,
pOPT32->MajorSubsystemVersion,
pOPT32->MinorSubsystemVersion,
pOPT32->Win32VersionValue,
pOPT32->SizeOfImage,
pOPT32->SizeOfHeaders,
pOPT32->CheckSum,
pOPT32->Subsystem);
switch(pOPT32->Subsystem)
{
default:
case IMAGE_SUBSYSTEM_UNKNOWN:
fputs("\tUnknown subsystem.\n",stdout);
break;
case IMAGE_SUBSYSTEM_NATIVE:
fputs("\tImage doesn't require a subsystem.\n",stdout);
break;
case IMAGE_SUBSYSTEM_WINDOWS_GUI:
fputs("\tImage runs in the Windows GUI subsystem.\n",stdout);
break;
case IMAGE_SUBSYSTEM_WINDOWS_CUI:
fputs("\tImage runs in the Windows character subsystem.\n",stdout);
break;
case IMAGE_SUBSYSTEM_OS2_CUI:
fputs("\timage runs in the OS/2 character subsystem.\n",stdout);
break;
case IMAGE_SUBSYSTEM_POSIX_CUI:
fputs("\timage runs in the Posix character subsystem.\n",stdout);
break;
case IMAGE_SUBSYSTEM_NATIVE_WINDOWS:
fputs("\timage is a native Win9x driver.\n",stdout);
break;
case IMAGE_SUBSYSTEM_WINDOWS_CE_GUI:
fputs("\tImage runs in the Windows CE subsystem.\n",stdout);
break;
}
printf("Dll characteristics:0x%04X\n",pOPT32->DllCharacteristics);
if(pOPT32->DllCharacteristics&1)
fputs("\tDLL_PROCESS_ATTACH\n",stdout);
if(pOPT32->DllCharacteristics&2)
fputs("\tDLL_THREAD_ATTACH\n",stdout);
if(pOPT32->DllCharacteristics&4)
fputs("\tDLL_THREAD_DETACH\n",stdout);
if(pOPT32->DllCharacteristics&8)
fputs("\tDLL_PROCESS_DETACH\n",stdout);
if(pOPT32->DllCharacteristics&IMAGE_DLLCHARACTERISTICS_WDM_DRIVER)
fputs("\tWDM_Driver\n",stdout);
printf(
"Size of stack reserve:0x%08X\n"
"Size of stack commit:0x%08X\n"
"Size of heap reserve:0x%08X\n"
"Size of heap commit:0x%08X\n"
"Loader flags:0x%08X\n"
"Number of RVA and sizes:0x%08X\n"
"Data directories:\n",
pOPT32->SizeOfStackReserve,
pOPT32->SizeOfStackCommit,
pOPT32->SizeOfHeapReserve,
pOPT32->SizeOfHeapCommit,
pOPT32->LoaderFlags,
pOPT32->NumberOfRvaAndSizes);
for(uDirEntry=0;uDirEntry<pOPT32->NumberOfRvaAndSizes;uDirEntry++)
{
printf(
"%s:\n"
"Virtual address:0x%08X\tSize:0x%08X\n",
uDirEntry<sizeof(pDirTableDesc)/sizeof(char*)?pDirTableDesc:"Unknown",
pOPT32->DataDirectory.VirtualAddress,
pOPT32->DataDirectory.Size);
}
}
void ReadOPT64(FILE*fp,IMAGE_OPTIONAL_HEADER64*pOPT64)
{
UINT uDirEntry;
printf(
"Major linker version=0x%02X\n"
"Minor linker version=0x%02X\n"
"Size of code=0x%08X\n"
"Size of initialized data=0x%08X\n"
"Size of uninitialized data=0x%08X\n"
"Address of entry point=0x%08X\n"
"Base of code=0x%08X\n"
"Image base=0x%016I64X\n"
"Section alignment=0x%08X\n"
"File alignment=0x%08X\n"
"Major operating system version=0x%04X\n"
"Minor operating system version=0x%04X\n"
"Major image version=0x%04X\n"
"Minor image version=0x%04X\n"
"Major subsystem version=0x%04X\n"
"Minor subsystem version=0x%04X\n"
"Win32 version value=0x%08X\n"
"Size of image=0x%08X\n"
"Size of headers=0x%08X\n"
"Check sum=0x%08X\n"
"Subsystem=0x%04X\n",
pOPT64->MajorLinkerVersion,
pOPT64->MinorLinkerVersion,
pOPT64->SizeOfCode,
pOPT64->SizeOfInitializedData,
pOPT64->SizeOfUninitializedData,
pOPT64->AddressOfEntryPoint,
pOPT64->BaseOfCode,
pOPT64->ImageBase,
pOPT64->SectionAlignment,
pOPT64->FileAlignment,
pOPT64->MajorOperatingSystemVersion,
pOPT64->MinorOperatingSystemVersion,
pOPT64->MajorImageVersion,
pOPT64->MinorImageVersion,
pOPT64->MajorSubsystemVersion,
pOPT64->MinorSubsystemVersion,
pOPT64->Win32VersionValue,
pOPT64->SizeOfImage,
pOPT64->SizeOfHeaders,
pOPT64->CheckSum,
pOPT64->Subsystem);
switch(pOPT64->Subsystem)
{
default:
case IMAGE_SUBSYSTEM_UNKNOWN:
fputs("\tUnknown subsystem.\n",stdout);
break;
case IMAGE_SUBSYSTEM_NATIVE:
fputs("\tImage doesn't require a subsystem.\n",stdout);
break;
case IMAGE_SUBSYSTEM_WINDOWS_GUI:
fputs("\tImage runs in the Windows GUI subsystem.\n",stdout);
break;
case IMAGE_SUBSYSTEM_WINDOWS_CUI:
fputs("\tImage runs in the Windows character subsystem.\n",stdout);
break;
case IMAGE_SUBSYSTEM_OS2_CUI:
fputs("\timage runs in the OS/2 character subsystem.\n",stdout);
break;
case IMAGE_SUBSYSTEM_POSIX_CUI:
fputs("\timage runs in the Posix character subsystem.\n",stdout);
break;
case IMAGE_SUBSYSTEM_NATIVE_WINDOWS:
fputs("\timage is a native Win9x driver.\n",stdout);
break;
case IMAGE_SUBSYSTEM_WINDOWS_CE_GUI:
fputs("\tImage runs in the Windows CE subsystem.\n",stdout);
break;
}
printf("Dll characteristics:0x%04X\n",pOPT64->DllCharacteristics);
if(pOPT64->DllCharacteristics&1)
fputs("\tDLL_PROCESS_ATTACH\n",stdout);
if(pOPT64->DllCharacteristics&2)
fputs("\tDLL_THREAD_ATTACH\n",stdout);
if(pOPT64->DllCharacteristics&4)
fputs("\tDLL_THREAD_DETACH\n",stdout);
if(pOPT64->DllCharacteristics&8)
fputs("\tDLL_PROCESS_DETACH\n",stdout);
if(pOPT64->DllCharacteristics&IMAGE_DLLCHARACTERISTICS_WDM_DRIVER)
fputs("\tWDM_Driver\n",stdout);
printf(
"Size of stack reserve=0x%016I64X\n"
"Size of stack commit=0x%016I64X\n"
"Size of heap reserve=0x%016I64X\n"
"Size of heap commit=0x%016I64X\n"
"Loader flags=0x%08X\n"
"Number of RVA and sizes=0x%08X\n",
pOPT64->SizeOfStackReserve,
pOPT64->SizeOfStackCommit,
pOPT64->SizeOfHeapReserve,
pOPT64->SizeOfHeapCommit,
pOPT64->LoaderFlags,
pOPT64->NumberOfRvaAndSizes);
for(uDirEntry=0;uDirEntry<pOPT64->NumberOfRvaAndSizes;uDirEntry++)
{
printf(
"%s:\n"
"Virtual address:0x%08X\tSize:0x%08X\n",
uDirEntry<sizeof(pDirTableDesc)/sizeof(char*)?pDirTableDesc:"Unknown",
pOPT64->DataDirectory.VirtualAddress,
pOPT64->DataDirectory.Size);
}
}
void ReadROMOPT(FILE*fp,IMAGE_ROM_OPTIONAL_HEADER*pROMOPT)
{
printf(
"Major linker version=0x%02X\n"
"Minor linker version=0x%02X\n"
"Size of code=0x%08X\n"
"Size of initializedData=0x%08X\n"
"Size of uninitializedData=0x%08X\n"
"Address of entry point=0x%08X\n"
"Base of code=0x%08X\n"
"Base of data=0x%08X\n"
"Base of bss=0x%08X\n"
"Gpr mask=0x%08X\n"
"Cpr mask:\n"
"\t0x%08X\n"
"\t0x%08X\n"
"\t0x%08X\n"
"\t0x%08X\n"
"Gp value0x%08X\n",
"MajorLinkerVersion=0x%02X\n",
pROMOPT->MinorLinkerVersion,
pROMOPT->SizeOfCode,
pROMOPT->SizeOfInitializedData,
pROMOPT->SizeOfUninitializedData,
pROMOPT->AddressOfEntryPoint,
pROMOPT->BaseOfCode,
pROMOPT->BaseOfData,
pROMOPT->BaseOfBss,
pROMOPT->GprMask,
pROMOPT->CprMask,
pROMOPT->CprMask,
pROMOPT->CprMask,
pROMOPT->CprMask,
pROMOPT->GpValue);
}
void ReadSegH(FILE*fp)
{
IMAGE_SECTION_HEADER SecH;
char szBuf={0};
WORD wSeg=g_PEH.NumberOfSections;
while(wSeg--)
{
fread(&SecH,1,sizeof(SecH),fp);
memcpy(szBuf,SecH.Name,IMAGE_SIZEOF_SHORT_NAME);
printf(
"--------------------------------Section headers--------------------------------\n"
"Name:%s\n"
"Physical address\\Virtual size:0x%08X\n"
"Virtual address:0x%08X\n"
"Size of raw data:0x%08X\n"
"Pointer to raw data:0x%08X\n"
"Pointer to relocations:0x%08X\n"
"Pointer to linenumbers:0x%08X\n"
"Number of relocations:0x%04X\n"
"Number of linenumbers:0x%04X\n"
"Characteristics:0x%08X\n",
szBuf,
SecH.Misc.PhysicalAddress,
SecH.VirtualAddress,
SecH.SizeOfRawData,
SecH.PointerToRawData,
SecH.PointerToRelocations,
SecH.PointerToLinenumbers,
SecH.NumberOfRelocations,
SecH.NumberOfLinenumbers,
SecH.Characteristics);
if(SecH.Characteristics&IMAGE_SCN_TYPE_NO_PAD)
fputs("IMAGE_SCN_TYPE_NO_PAD\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_CNT_CODE)
fputs("IMAGE_SCN_CNT_CODE\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_CNT_INITIALIZED_DATA)
fputs("IMAGE_SCN_CNT_INITIALIZED_DATA\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_CNT_UNINITIALIZED_DATA)
fputs("IMAGE_SCN_CNT_UNINITIALIZED_DATA\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_LNK_OTHER)
fputs("IMAGE_SCN_LNK_OTHER\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_LNK_INFO)
fputs("IMAGE_SCN_LNK_INFO\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_LNK_REMOVE)
fputs("IMAGE_SCN_LNK_REMOVE\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_LNK_COMDAT)
fputs("IMAGE_SCN_LNK_COMDAT\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_NO_DEFER_SPEC_EXC)
fputs("IMAGE_SCN_NO_DEFER_SPEC_EXC\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_GPREL)
fputs("IMAGE_SCN_GPREL\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_MEM_FARDATA)
fputs("IMAGE_SCN_MEM_FARDATA\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_MEM_PURGEABLE)
fputs("IMAGE_SCN_MEM_PURGEABLE\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_MEM_16BIT)
fputs("IMAGE_SCN_MEM_16BIT\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_MEM_LOCKED)
fputs("IMAGE_SCN_MEM_LOCKED\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_MEM_PRELOAD)
fputs("IMAGE_SCN_MEM_PRELOAD\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_ALIGN_1BYTES)
fputs("IMAGE_SCN_ALIGN_1BYTES\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_ALIGN_2BYTES)
fputs("IMAGE_SCN_ALIGN_2BYTES\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_ALIGN_4BYTES)
fputs("IMAGE_SCN_ALIGN_4BYTES\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_ALIGN_8BYTES)
fputs("IMAGE_SCN_ALIGN_8BYTES\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_ALIGN_16BYTES)
fputs("IMAGE_SCN_ALIGN_16BYTES\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_ALIGN_32BYTES)
fputs("IMAGE_SCN_ALIGN_32BYTES\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_ALIGN_64BYTES)
fputs("IMAGE_SCN_ALIGN_64BYTES\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_ALIGN_128BYTES)
fputs("IMAGE_SCN_ALIGN_128BYTES\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_ALIGN_256BYTES)
fputs("IMAGE_SCN_ALIGN_256BYTES\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_ALIGN_512BYTES)
fputs("IMAGE_SCN_ALIGN_512BYTES\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_ALIGN_1024BYTES)
fputs("IMAGE_SCN_ALIGN_1024BYTES\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_ALIGN_2048BYTES)
fputs("IMAGE_SCN_ALIGN_2048BYTES\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_ALIGN_4096BYTES)
fputs("IMAGE_SCN_ALIGN_4096BYTES\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_ALIGN_8192BYTES)
fputs("IMAGE_SCN_ALIGN_8192BYTES\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_LNK_NRELOC_OVFL)
fputs("IMAGE_SCN_LNK_NRELOC_OVFL\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_MEM_DISCARDABLE)
fputs("IMAGE_SCN_MEM_DISCARDABLE\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_MEM_NOT_CACHED)
fputs("IMAGE_SCN_MEM_NOT_CACHED\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_MEM_NOT_PAGED)
fputs("IMAGE_SCN_MEM_NOT_PAGED\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_MEM_SHARED)
fputs("IMAGE_SCN_MEM_SHARED\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_MEM_EXECUTE)
fputs("IMAGE_SCN_MEM_EXECUTE\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_MEM_READ)
fputs("IMAGE_SCN_MEM_READ\n",stdout);
if(SecH.Characteristics&IMAGE_SCN_MEM_WRITE)
fputs("IMAGE_SCN_MEM_WRITE\n",stdout);
}
}
int main(int argc,char**argv)
{
FILE*fp;
if(argc<2)
{
Usage();
return 1;
}
fp=fopen(argv,"rb");
if(!fp)
{
printf("Unable to open %s.\n",argv);
return 1;
}
//PE文件第一个文件头:DOS EXE头
ReadDOSH(fp);
//PE文件第二个头:PE头
if(g_DOSH.e_lfanew)//如果有新EXE头(PE、LE、NE等)
{
DWORD dwMagicNumber;
fseek(fp,g_DOSH.e_lfanew,SEEK_SET);//转到新EXE头
fread(&dwMagicNumber,1,sizeof(dwMagicNumber),fp);//读取标记
if(dwMagicNumber==IMAGE_NT_SIGNATURE)//如果是PE头
{
//PE头
ReadPEH(fp);
//PE可选标头
if(g_PEH.SizeOfOptionalHeader)//如果有可选标头
{
IMAGE_OPTIONAL_HEADER32 *pOPT32=NULL;
IMAGE_OPTIONAL_HEADER64 *pOPT64=NULL;
IMAGE_ROM_OPTIONAL_HEADER *pROMOPT=NULL;
void *pBuffer=malloc(g_PEH.SizeOfOptionalHeader);
if(pBuffer)
{
fputs("Optional header:\n",stdout);
fread(pBuffer,1,g_PEH.SizeOfOptionalHeader,fp);//读取
switch(*(WORD*)pBuffer)//读取魔法数字
{
case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
fputs("-----------------------------32 bit optional header----------------------------\n",stdout);
ReadOPT32(fp,(IMAGE_OPTIONAL_HEADER32*)pBuffer);
break;
case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
fputs("-----------------------------64 bit optional header----------------------------\n",stdout);
ReadOPT64(fp,(IMAGE_OPTIONAL_HEADER64*)pBuffer);
break;
case IMAGE_ROM_OPTIONAL_HDR_MAGIC:
fputs("-----------------------------Rom optional header-------------------------------\n",stdout);
ReadROMOPT(fp,(IMAGE_ROM_OPTIONAL_HEADER*)pBuffer);
break;
default:
fputs("Unknown optional header.\n",stdout);
break;
}
free(pBuffer);
ReadSegH(fp);//读取区段
}
else
fputs("No enough memory for reading the optional header.\n",stderr);
}
}
else
fputs("PrintPE is only for PE files.\n",stderr);
}
fclose(fp);
return 0;
}可以用它来查看EXE、DLL的文件头的细节。也可以通过修改它的源码来实现自己的加壳工具。
EXE下载地址:
这是源码:
PE文件的组成:
1、DOS的16位EXE头(Stub)
IMAGE_DOS_HEADER
在WINNT.H有定义。
2、PE头。
IMAGE_FILE_HEADER
在WINNT.H有定义。
3、可选头。定义了程序的入口点等信息
根据情况有以下三种类型:
IMAGE_OPTIONAL_HEADER32
IMAGE_OPTIONAL_HEADER64
IMAGE_ROM_OPTIONAL_HEADER
在WINNT.H有定义。
4、区段头。定义了程序的分段的信息。
IMAGE_SECTION_HEADER
在WINNT.H有定义。
常见区段:
.text:代码段
.data:数据段
.rdata:只读数据段
.bss:未初始化数据段
.reloc:重定向表信息
5、镜像。
所谓镜像就是运行的指令、附带的数据等。
6、资源。
图标、位图、字串表等玩意儿。 让PrintPE分析自己的PE头:
D:\C\PrintPE\Release>PrintPE.exe PrintPE.exe
--------------------------------DOS .EXE header--------------------------------
Magic number:0x5A4D
Bytes on last page of file:0x0090
Pages in file:0x0003
Relocations:0x0000
Size of header in paragraphs:0x0004
Minimum extra paragraphs needed:0x0000
Maximum extra paragraphs needed:0xFFFF
Initial (relative) SS value:0x0000
Initial SP value:0x00B8
Checksum:0x0000
Initial IP value:0x0000
Initial (relative) CS value:0x0000
File address of relocation table:0x0040
Overlay number:0x0000
OEM identifier (for e_oeminfo):0x0000
OEM information; e_oemid specific:0x0000
File address of new exe header:0x000000C8
----------------------------------PE Header------------------------------------
Machine:Intel 386.
Number of sections:0x0003
Time date stamp:0x53551E51
Pointer to symbol table:0x00000000
Number of symbols:0x00000000
Size of optional header:0x00E0
Characteristics:0x010F
Relocation info stripped from file.
File is executable(i.e. no unresolved externel references).
Line numbers stripped from file.
Local symbols stripped from file.
32 bit word machine.
Optional header:
-----------------------------32 bit optional header----------------------------
Major linker version:0x10B
Minor linker version:0x06
Size of code:0x00000000
Size of initialized data:0x00007000
Size of uninitialized data:0x00007000
Address of entry point:0x00000000
Base of code:0x00002605
Base of data:0x00001000
Image base:0x00008000
Section alignment:0x00400000
File alignment:0x00001000
Major operating system version:0x1000
Minor operating system version:0x0004
Major image version:0x0000
Minor image version:0x0000
Major subsystem version:0x0000
Minor subsystem version:0x0004
Win32 version value:0x00000000
Size of image:0x00000000
Size of headers:0x0000F000
Check sum:0x00001000
Subsystem:0x0000
Image runs in the Windows character subsystem.
Dll characteristics:0x0000
Size of stack reserve:0x00100000
Size of stack commit:0x00001000
Size of heap reserve:0x00100000
Size of heap commit:0x00001000
Loader flags:0x00000000
Number of RVA and sizes:0x00000010
Data directories:
Export Directory:
Virtual address:0x00000000 Size:0x00000000
Import Directory:
Virtual address:0x000084CC Size:0x00000028
Resource Directory:
Virtual address:0x00000000 Size:0x00000000
Exception Directory:
Virtual address:0x00000000 Size:0x00000000
Security Directory:
Virtual address:0x00000000 Size:0x00000000
Base Relocation Table:
Virtual address:0x00000000 Size:0x00000000
Debug Directory:
Virtual address:0x00000000 Size:0x00000000
Architecture Specific Data:
Virtual address:0x00000000 Size:0x00000000
RVA of GP:
Virtual address:0x00000000 Size:0x00000000
TLS Directory:
Virtual address:0x00000000 Size:0x00000000
Load Configuration Directory:
Virtual address:0x00000000 Size:0x00000000
Bound Import Directory in headers:
Virtual address:0x00000000 Size:0x00000000
Import Address Table:
Virtual address:0x00008000 Size:0x000000BC
Delay Load Import Descriptors:
Virtual address:0x00000000 Size:0x00000000
COM Runtime descriptor:
Virtual address:0x00000000 Size:0x00000000
Unknown:
Virtual address:0x00000000 Size:0x00000000
--------------------------------Section headers--------------------------------
Name:.text
Physical address\Virtual size:0x00006932
Virtual address:0x00001000
Size of raw data:0x00007000
Pointer to raw data:0x00001000
Pointer to relocations:0x00000000
Pointer to linenumbers:0x00000000
Number of relocations:0x0000
Number of linenumbers:0x0000
Characteristics:0x60000020
IMAGE_SCN_CNT_CODE
IMAGE_SCN_MEM_EXECUTE
IMAGE_SCN_MEM_READ
--------------------------------Section headers--------------------------------
Name:.rdata
Physical address\Virtual size:0x000008D6
Virtual address:0x00008000
Size of raw data:0x00001000
Pointer to raw data:0x00008000
Pointer to relocations:0x00000000
Pointer to linenumbers:0x00000000
Number of relocations:0x0000
Number of linenumbers:0x0000
Characteristics:0x40000040
IMAGE_SCN_CNT_INITIALIZED_DATA
IMAGE_SCN_MEM_READ
--------------------------------Section headers--------------------------------
Name:.data
Physical address\Virtual size:0x000056E4
Virtual address:0x00009000
Size of raw data:0x00005000
Pointer to raw data:0x00009000
Pointer to relocations:0x00000000
Pointer to linenumbers:0x00000000
Number of relocations:0x0000
Number of linenumbers:0x0000
Characteristics:0xC0000040
IMAGE_SCN_CNT_INITIALIZED_DATA
IMAGE_SCN_MEM_READ
IMAGE_SCN_MEM_WRITE 顶站长,orz
页:
[1]