- UID
- 1
- 精华
- 积分
- 76361
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
这个和旧的PrintPE相比,多了很多内容,包括IAT、EAT(输入、输出表)以及资源表的读取。原先的只是简单地打印了PE头。这个有了更多功能。
旧帖:
【C】C语言写的打印PE文件头信息的程序
转载请明出处:
http://www.0xaa55.com/thread-530-1-1.html
用法和旧帖说的一样。运行如下命令:
PrintPE 某PE文件.后缀
就可以看到效果了。
但是因为这个版本功能比较全,打印的东西比较多,因此建议大家还是把结果重定向到一个文件比较好。
PrintPE 某PE文件.后缀>输出.txt
这样就能看到PE文件的所有信息了。包括输入表(这个PE引用了哪些DLL)、输出表(这个PE提供了哪些符号输出)、资源表等。功能比旧版强多了。
感谢@美俪女神 (Tesla.Angela)提供的技术资料。
其实我编写这个程序的时候,用的是无脑输出法,也就是,WINNT.H给的结构体有几个成员,我就输出多少信息。
不过为了让文件更直观,有些部分的信息我把它省略掉了。
源码:- //-----------------------------------------------------------------------------
- //PrintPE:
- //打印一个PE文件所有信息的程序。
- //功能就是无脑把PE文件头的所有内容全部打印出来。
- //代码不保证可读性。
- //作者:0xAA55
- //QQ:838816058
- //论坛:http://www.0xaa55.com/
- //本人所有技术资料都在“技术宅的结界”。欢迎大家参与交流。
- //-----------------------------------------------------------------------------
- #include<stdio.h>
- #include<windows.h>
- //-----------------------------------------------------------------------------
- //全局变量
- //-----------------------------------------------------------------------------
- IMAGE_DOS_HEADER g_DOSH;
- IMAGE_FILE_HEADER g_PEH;
- void *g_pOPTBuffer=NULL;//可选头缓冲区
- IMAGE_SECTION_HEADER *g_pSecH=NULL;
- //-----------------------------------------------------------------------------
- //打印“用法”
- //-----------------------------------------------------------------------------
- void Usage()
- {
- fputs(
- "USAGE:\n"
- "PrintPE PEFILE\n",stderr);
- }
- //-----------------------------------------------------------------------------
- //读取PE文件最开始的头:DOS头
- //-----------------------------------------------------------------------------
- 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;//DOS重定向表
- fread(pdwRelocTable,1,sizeof(DWORD)*wRelocs,fp);//一次性读取
- while(wRelocs--)
- {
- printf("0x%04X:0x%04X\n",(*pPtr>>16)&0xFFFF,*pPtr&0xFFFF);//打印远指针
- pPtr++;
- }
- free(pdwRelocTable);
- }
- else//没分配到内存
- {
- DWORD dwReloc;
- while(wRelocs--)
- {
- fread(&dwReloc,1,sizeof(dwReloc),fp);//读一个打印一个
- printf("0x%04X:0x%04X\n",(dwReloc>>16)&0xFFFF,dwReloc&0xFFFF);//打印远指针
- }
- }
- }
- }
- //-----------------------------------------------------------------------------
- //读取PE头
- //-----------------------------------------------------------------------------
- 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);
- }
- //-----------------------------------------------------------------------------
- //目录表的描述字符串
- //-----------------------------------------------------------------------------
- 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"
- };
- //-----------------------------------------------------------------------------
- //读取32位可选头
- //-----------------------------------------------------------------------------
- void ReadOPT32(FILE*fp)
- {
- UINT uDirEntry;
- IMAGE_OPTIONAL_HEADER32*pOPT32=(IMAGE_OPTIONAL_HEADER32*)g_pOPTBuffer;
- 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->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;
- }
- //打印DLL特性
- 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[uDirEntry]:"Unknown",
- pOPT32->DataDirectory[uDirEntry].VirtualAddress,
- pOPT32->DataDirectory[uDirEntry].Size);
- }
- }
- //-----------------------------------------------------------------------------
- //读取64位可选头
- //-----------------------------------------------------------------------------
- void ReadOPT64(FILE*fp)
- {
- UINT uDirEntry;
- IMAGE_OPTIONAL_HEADER64*pOPT64=(IMAGE_OPTIONAL_HEADER64*)g_pOPTBuffer;
- 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;
- }
- //打印DLL特性
- 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[uDirEntry]:"Unknown",
- pOPT64->DataDirectory[uDirEntry].VirtualAddress,
- pOPT64->DataDirectory[uDirEntry].Size);
- }
- }
- //-----------------------------------------------------------------------------
- //读取ROM的可选头
- //-----------------------------------------------------------------------------
- void ReadROMOPT(FILE*fp)
- {
- IMAGE_ROM_OPTIONAL_HEADER*pROMOPT=(IMAGE_ROM_OPTIONAL_HEADER*)g_pOPTBuffer;
- 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[0],
- pROMOPT->CprMask[1],
- pROMOPT->CprMask[2],
- pROMOPT->CprMask[3],
- pROMOPT->GpValue);
- }
- //-----------------------------------------------------------------------------
- //读取段落头(会分配内存给段落头)
- //-----------------------------------------------------------------------------
- void ReadSegH(FILE*fp)
- {
- char szBuf[IMAGE_SIZEOF_SHORT_NAME+1]={0};
- WORD wSeg=g_PEH.NumberOfSections;
- g_pSecH=(IMAGE_SECTION_HEADER*)malloc(g_PEH.NumberOfSections*sizeof(IMAGE_SECTION_HEADER));
- if(g_pSecH)
- {
- IMAGE_SECTION_HEADER*pSecH=g_pSecH;
- while(wSeg--)//读取所有段落头
- {
- fread(pSecH,1,sizeof(IMAGE_SECTION_HEADER),fp);
- memcpy(szBuf,pSecH->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,
- pSecH->Misc.PhysicalAddress,
- pSecH->VirtualAddress,
- pSecH->SizeOfRawData,
- pSecH->PointerToRawData,
- pSecH->PointerToRelocations,
- pSecH->PointerToLinenumbers,
- pSecH->NumberOfRelocations,
- pSecH->NumberOfLinenumbers,
- pSecH->Characteristics);
- //打印段落特性
- if(pSecH->Characteristics&IMAGE_SCN_TYPE_NO_PAD)
- fputs("IMAGE_SCN_TYPE_NO_PAD\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_CNT_CODE)
- fputs("IMAGE_SCN_CNT_CODE\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_CNT_INITIALIZED_DATA)
- fputs("IMAGE_SCN_CNT_INITIALIZED_DATA\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_CNT_UNINITIALIZED_DATA)
- fputs("IMAGE_SCN_CNT_UNINITIALIZED_DATA\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_LNK_OTHER)
- fputs("IMAGE_SCN_LNK_OTHER\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_LNK_INFO)
- fputs("IMAGE_SCN_LNK_INFO\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_LNK_REMOVE)
- fputs("IMAGE_SCN_LNK_REMOVE\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_LNK_COMDAT)
- fputs("IMAGE_SCN_LNK_COMDAT\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_NO_DEFER_SPEC_EXC)
- fputs("IMAGE_SCN_NO_DEFER_SPEC_EXC\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_GPREL)
- fputs("IMAGE_SCN_GPREL\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_MEM_FARDATA)
- fputs("IMAGE_SCN_MEM_FARDATA\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_MEM_PURGEABLE)
- fputs("IMAGE_SCN_MEM_PURGEABLE\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_MEM_16BIT)
- fputs("IMAGE_SCN_MEM_16BIT\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_MEM_LOCKED)
- fputs("IMAGE_SCN_MEM_LOCKED\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_MEM_PRELOAD)
- fputs("IMAGE_SCN_MEM_PRELOAD\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_ALIGN_1BYTES)
- fputs("IMAGE_SCN_ALIGN_1BYTES\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_ALIGN_2BYTES)
- fputs("IMAGE_SCN_ALIGN_2BYTES\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_ALIGN_4BYTES)
- fputs("IMAGE_SCN_ALIGN_4BYTES\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_ALIGN_8BYTES)
- fputs("IMAGE_SCN_ALIGN_8BYTES\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_ALIGN_16BYTES)
- fputs("IMAGE_SCN_ALIGN_16BYTES\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_ALIGN_32BYTES)
- fputs("IMAGE_SCN_ALIGN_32BYTES\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_ALIGN_64BYTES)
- fputs("IMAGE_SCN_ALIGN_64BYTES\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_ALIGN_128BYTES)
- fputs("IMAGE_SCN_ALIGN_128BYTES\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_ALIGN_256BYTES)
- fputs("IMAGE_SCN_ALIGN_256BYTES\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_ALIGN_512BYTES)
- fputs("IMAGE_SCN_ALIGN_512BYTES\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_ALIGN_1024BYTES)
- fputs("IMAGE_SCN_ALIGN_1024BYTES\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_ALIGN_2048BYTES)
- fputs("IMAGE_SCN_ALIGN_2048BYTES\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_ALIGN_4096BYTES)
- fputs("IMAGE_SCN_ALIGN_4096BYTES\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_ALIGN_8192BYTES)
- fputs("IMAGE_SCN_ALIGN_8192BYTES\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_LNK_NRELOC_OVFL)
- fputs("IMAGE_SCN_LNK_NRELOC_OVFL\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_MEM_DISCARDABLE)
- fputs("IMAGE_SCN_MEM_DISCARDABLE\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_MEM_NOT_CACHED)
- fputs("IMAGE_SCN_MEM_NOT_CACHED\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_MEM_NOT_PAGED)
- fputs("IMAGE_SCN_MEM_NOT_PAGED\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_MEM_SHARED)
- fputs("IMAGE_SCN_MEM_SHARED\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_MEM_EXECUTE)
- fputs("IMAGE_SCN_MEM_EXECUTE\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_MEM_READ)
- fputs("IMAGE_SCN_MEM_READ\n",stdout);
- if(pSecH->Characteristics&IMAGE_SCN_MEM_WRITE)
- fputs("IMAGE_SCN_MEM_WRITE\n",stdout);
- pSecH++;
- }
- }
- }
- //-----------------------------------------------------------------------------
- //把RVA转换成文件内偏移的函数
- //需要给出所有的段落头,以及段落头数量
- //-----------------------------------------------------------------------------
- DWORD RvaToFileOffset(DWORD dwRVA,IMAGE_SECTION_HEADER*pSecHeaders,DWORD dwNbSections)
- {
- while(dwNbSections--)//遍历所有段
- {
- if(dwRVA>=pSecHeaders->VirtualAddress &&
- dwRVA<=pSecHeaders->VirtualAddress+pSecHeaders->SizeOfRawData)//在段内
- return dwRVA+pSecHeaders->PointerToRawData-pSecHeaders->VirtualAddress;//取得文件内偏移
- pSecHeaders++;//找下一个段
- }
- return dwRVA;//不在所有的段内,则返回原数值。
- }
- void ReadExport(FILE*fp,IMAGE_DATA_DIRECTORY*pDir);
- void ReadImport(FILE*fp,IMAGE_DATA_DIRECTORY*pDir);
- void ReadResource(FILE*fp,IMAGE_DATA_DIRECTORY*pDir);
- //-----------------------------------------------------------------------------
- //读取目录表
- //-----------------------------------------------------------------------------
- void ReadDirEntry(FILE*fp,DWORD dwNumRvaAndSizes,IMAGE_DATA_DIRECTORY*pDir)
- {
- if(dwNumRvaAndSizes>IMAGE_DIRECTORY_ENTRY_EXPORT)//如果有输出表
- ReadExport(fp,pDir++);//读取输出表
- if(dwNumRvaAndSizes>IMAGE_DIRECTORY_ENTRY_IMPORT)//如果有输入表
- ReadImport(fp,pDir++);//读取输入表
- if(dwNumRvaAndSizes>IMAGE_DIRECTORY_ENTRY_RESOURCE)//如果有资源表
- ReadResource(fp,pDir++);//读取资源表
- }
- //-----------------------------------------------------------------------------
- //读取输出表
- //-----------------------------------------------------------------------------
- void ReadExport(FILE*fp,IMAGE_DATA_DIRECTORY*pDir)
- {
- long lCurPos=ftell(fp);//记住当前文件指针
- IMAGE_EXPORT_DIRECTORY ExpDir;
- char szName[256];
- DWORD *pFuncAddr=NULL,
- *pNameAddr=NULL;
- WORD *pOrdinalAddr=NULL;
- long SizeOfFuncAddrs,
- SizeOfNameAddrs,
- SizeOfOrdinalAddrs;
- if(!pDir->VirtualAddress||!pDir->Size)
- return;
- fseek(fp,RvaToFileOffset(pDir->VirtualAddress,g_pSecH,g_PEH.NumberOfSections),SEEK_SET);
- fread(&ExpDir,1,sizeof(ExpDir),fp);//先读取IMAGE_EXPORT_DIRECTORY这个结构体
- printf(
- "-------------------------------Export directory--------------------------------\n"
- "Characteristics=0x%08X\n"
- "Time date stamp=0x%08X\n"
- "Major version=0x%04X\n"
- "Minor version=0x%04X\n"
- "Name=0x%08X\n"
- "Base=0x%08X\n"
- "Number of functions=0x%08X\n"
- "Number of names=0x%08X\n"
- "Address of functions=0x%08X\n"
- "Address of names=0x%08X\n"
- "Address of name ordinals=0x%08X\n",
- ExpDir.Characteristics,
- ExpDir.TimeDateStamp,
- ExpDir.MajorVersion,
- ExpDir.MinorVersion,
- ExpDir.Name,
- ExpDir.Base,
- ExpDir.NumberOfFunctions,
- ExpDir.NumberOfNames,
- ExpDir.AddressOfFunctions,
- ExpDir.AddressOfNames,
- ExpDir.AddressOfNameOrdinals);
- //打印名字
- fseek(fp,RvaToFileOffset(ExpDir.Name,g_pSecH,g_PEH.NumberOfSections),SEEK_SET);
- fgets(szName,sizeof(szName),fp);
- printf("Export name:%s\n",szName);
- pFuncAddr=malloc(SizeOfFuncAddrs=ExpDir.NumberOfFunctions*sizeof(DWORD));//函数地址表
- pNameAddr=malloc(SizeOfNameAddrs=ExpDir.NumberOfNames*sizeof(DWORD));//函数名表
- pOrdinalAddr=malloc(SizeOfOrdinalAddrs=ExpDir.NumberOfNames*sizeof(WORD));
- if(pFuncAddr&&pNameAddr&&pOrdinalAddr)//分配到了内存
- {
- DWORD i;
- fseek(fp,RvaToFileOffset(ExpDir.AddressOfFunctions,g_pSecH,g_PEH.NumberOfSections),SEEK_SET);
- fread(pFuncAddr,1,SizeOfFuncAddrs,fp);//读取函数地址表
- fseek(fp,RvaToFileOffset(ExpDir.AddressOfNames,g_pSecH,g_PEH.NumberOfSections),SEEK_SET);
- fread(pNameAddr,1,SizeOfNameAddrs,fp);//读取名称地址表
- fseek(fp,RvaToFileOffset(ExpDir.AddressOfNameOrdinals,g_pSecH,g_PEH.NumberOfSections),SEEK_SET);
- fread(pOrdinalAddr,1,SizeOfOrdinalAddrs,fp);//读取名称地址表
- fputs("Index\t\tAddress\t\tName\n",stdout);
- for(i=0;i<ExpDir.NumberOfNames;i++)//打印所有函数的序号、地址、名称
- {
- char szFunction[256];
- DWORD dwIndex=pOrdinalAddr[i ];
- fseek(fp,RvaToFileOffset(pNameAddr[i ],g_pSecH,g_PEH.NumberOfSections),SEEK_SET);
- fgets(szFunction,sizeof(szFunction),fp);//读取函数名
- printf("0x%04X\t0x%08X\t%s\n",dwIndex+1,pFuncAddr[dwIndex],szFunction);
- }
- while(i<ExpDir.NumberOfFunctions)//打印剩余没有名称的函数的序号、地址
- {
- printf("<??? >\t0x%08X\t<No name>\n",pFuncAddr[i ]);
- i++;
- }
- }
- else
- fputs("No enough memory.\n",stderr);
- free(pFuncAddr);
- free(pNameAddr);
- free(pOrdinalAddr);
- fseek(fp,lCurPos,SEEK_SET);//恢复文件指针
- }
- //-----------------------------------------------------------------------------
- //读取输入表
- //-----------------------------------------------------------------------------
- void ReadImport(FILE*fp,IMAGE_DATA_DIRECTORY*pDir)
- {
- long lCurPos=ftell(fp);//记住当前文件指针
- DWORD dwStartOffset=RvaToFileOffset(pDir->VirtualAddress,g_pSecH,g_PEH.NumberOfSections);//输入表的开始位置
- if(!pDir->VirtualAddress||!pDir->Size)
- return;
- for(;;)//有多个输入表需要顺序读取
- {
- IMAGE_IMPORT_DESCRIPTOR ImpDir;//输入表
- char szName[256];//名字
- DWORD dwThunkDataBegin;//输入表起始位置
- DWORD dwThunkAddressBegin;//输入表函数起始位置
- fseek(fp,dwStartOffset,SEEK_SET);
- fread(&ImpDir,1,sizeof(ImpDir),fp);//读取输入表
- if( !ImpDir.OriginalFirstThunk &&
- !ImpDir.TimeDateStamp &&
- !ImpDir.ForwarderChain &&
- !ImpDir.Name &&
- !ImpDir.FirstThunk)//如果没有表了
- break;//退出循环
- printf(
- "-------------------------------Import Descriptor-------------------------------\n"
- "RVA to original unbound IAT:0x%08X\n"
- "Date/time stamp of DLL bound to:0x%08X\n"
- "Forwarder chain:0x%08X\n"
- "Name:0x%08X\n"
- "First thunk:0x%08X\n",
- ImpDir.OriginalFirstThunk,
- ImpDir.TimeDateStamp,
- ImpDir.ForwarderChain,
- ImpDir.Name,
- ImpDir.FirstThunk);//打印表的信息
- //输出导入的DLL的名字
- fseek(fp,RvaToFileOffset(ImpDir.Name,g_pSecH,g_PEH.NumberOfSections),SEEK_SET);
- fgets(szName,sizeof(szName),fp);
- printf("Name:%s\n",szName);
- //读取IMAGE_THUNK_DATA
- dwThunkDataBegin=RvaToFileOffset(ImpDir.OriginalFirstThunk,g_pSecH,g_PEH.NumberOfSections);
- dwThunkAddressBegin=RvaToFileOffset(ImpDir.FirstThunk,g_pSecH,g_PEH.NumberOfSections);
- //32位和64位有不同的处理方式
- switch(*(WORD*)g_pOPTBuffer)
- {
- case IMAGE_NT_OPTIONAL_HDR32_MAGIC://读取32位的IMAGE_THUNK_DATA
- fputs("Ordinal\tAddress\t\tName\n",stdout);
- for(;;dwThunkDataBegin+=sizeof(IMAGE_THUNK_DATA32),dwThunkAddressBegin+=sizeof(IMAGE_THUNK_DATA32))
- {
- IMAGE_THUNK_DATA32 ThunkData;
- IMAGE_THUNK_DATA32 ThunkAddress;
- fseek(fp,dwThunkDataBegin,SEEK_SET);
- fread(&ThunkData,1,sizeof(ThunkData),fp);
- if(!ThunkData.u1.Ordinal)//如果没有表了
- break;//退出循环
- if(ThunkData.u1.Ordinal&IMAGE_ORDINAL_FLAG32)//如果是通过序号导入的
- {
- fseek(fp,dwThunkAddressBegin,SEEK_SET);//找到地址
- fread(&ThunkAddress,1,sizeof(ThunkAddress),fp);//读取地址
- printf("0x%04X\t0x%08X\t<No name>\n",IMAGE_ORDINAL32(ThunkData.u1.Ordinal),ThunkAddress.u1.Function);//显示序号
- }
- else//否则是通过名称导入的
- {
- WORD wHint;
- char szFunc[256];
- fseek(fp,RvaToFileOffset((DWORD)(ThunkData.u1.AddressOfData),g_pSecH,g_PEH.NumberOfSections),SEEK_SET);
- fread(&wHint,1,sizeof(wHint),fp);//读取序号
- fgets(szFunc,sizeof(szFunc),fp);//读取名字
- fseek(fp,dwThunkAddressBegin,SEEK_SET);//找到地址
- fread(&ThunkAddress,1,sizeof(ThunkAddress),fp);//读取地址
- printf("0x%04X\t0x%08X\t%s\n",wHint,ThunkAddress.u1.Function,szFunc);
- }
- }
- break;
- case IMAGE_NT_OPTIONAL_HDR64_MAGIC://读取64位的IMAGE_THUNK_DATA
- fputs("Ordinal\tAddress\t\tName\n",stdout);
- for(;;dwThunkDataBegin+=sizeof(IMAGE_THUNK_DATA64),dwThunkAddressBegin+=sizeof(IMAGE_THUNK_DATA64))
- {
- IMAGE_THUNK_DATA64 ThunkData;
- IMAGE_THUNK_DATA64 ThunkAddress;
- fseek(fp,dwThunkDataBegin,SEEK_SET);
- fread(&ThunkData,1,sizeof(ThunkData),fp);
- if(!ThunkData.u1.Ordinal)//如果没有表了
- break;//退出循环
- if(ThunkData.u1.Ordinal&IMAGE_ORDINAL_FLAG64)//如果是通过序号导入的
- {
- fseek(fp,dwThunkAddressBegin,SEEK_SET);//找到地址
- fread(&ThunkAddress,1,sizeof(ThunkAddress),fp);//读取地址
- printf("0x%04X\t0x%08X\t<No name>\n",IMAGE_ORDINAL64(ThunkData.u1.Ordinal),ThunkAddress.u1.Function);//显示序号
- }
- else//否则是通过名称导入的
- {
- WORD wHint;
- char szFunc[256];
- fseek(fp,RvaToFileOffset((DWORD)(ThunkData.u1.AddressOfData),g_pSecH,g_PEH.NumberOfSections),SEEK_SET);
- fread(&wHint,1,sizeof(wHint),fp);//读取序号
- fgets(szFunc,sizeof(szFunc),fp);//读取名字
- fseek(fp,dwThunkAddressBegin,SEEK_SET);//找到地址
- fread(&ThunkAddress,1,sizeof(ThunkAddress),fp);//读取地址
- printf("0x%04X\t0x%016I64X\t%s\n",wHint,(ULONGLONG)(ThunkAddress.u1.Function),szFunc);
- }
- }
- break;
- }
- dwStartOffset+=sizeof(IMAGE_IMPORT_DESCRIPTOR);//准备读取下一个输入表
- }
- fseek(fp,lCurPos,SEEK_SET);//恢复文件指针
- }
- void ReadResDirEntry(FILE*fp,DWORD dwResourceBegin,DWORD dwOffset,UINT uLevel);
- #define TREE_TAB 4 /*资源树的缩进量*/
- #define TREE_CHAR ' ' /*资源树的缩进字符*/
- //-----------------------------------------------------------------------------
- //读取整个资源表
- //-----------------------------------------------------------------------------
- void ReadResource(FILE*fp,IMAGE_DATA_DIRECTORY*pDir)
- {
- long lCurPos=ftell(fp);//记住当前文件指针
- if(!pDir->VirtualAddress||!pDir->Size)
- return;
- fputs("-----------------------------Resource Directory--------------------------------\n",stdout);
- //因为是树形结构所以需要递归读取
- ReadResDirEntry(fp,RvaToFileOffset(pDir->VirtualAddress,g_pSecH,g_PEH.NumberOfSections),0,0);
- fseek(fp,lCurPos,SEEK_SET);//恢复文件指针
- }
- //-----------------------------------------------------------------------------
- //读取资源树形结构
- //-----------------------------------------------------------------------------
- void ReadResDirEntry(FILE*fp,DWORD dwResourceBegin,DWORD dwOffset,UINT uLevel)
- {
- IMAGE_RESOURCE_DIRECTORY RcDir;
- DWORD dwEntries,dwNbEntries;
- long lBeginOfEntry;
- char*szLevelPrefix;
- unsigned uTabs=uLevel*TREE_TAB;
- fseek(fp,dwResourceBegin+dwOffset,SEEK_SET);
- fread(&RcDir,1,sizeof(RcDir),fp);//先读取IMAGE_RESOURCE_DIRECTORY这个结构体
- szLevelPrefix=(char*)malloc(uTabs+1);//分级的一个前缀
- if(!szLevelPrefix)//在这个尴尬的时候内存不足的话不好处理,所以直接退出
- {
- fputs("No enough memory.\n",stderr);
- return;
- }
- memset(szLevelPrefix,TREE_CHAR,uTabs);//前面填充空格
- szLevelPrefix[uTabs]=0;//结尾的\0
- printf(
- "%sCharacteristics:0x%08X\n"
- "%sTime date stamp:0x%08X\n"
- "%sMajor version:0x%04X\n"
- "%sMinor version:0x%04X\n"
- "%sNumber of named entries:0x%04X\n"
- "%sNumber of id entries:0x%04X\n",
- szLevelPrefix,RcDir.Characteristics,
- szLevelPrefix,RcDir.TimeDateStamp,
- szLevelPrefix,RcDir.MajorVersion,
- szLevelPrefix,RcDir.MinorVersion,
- szLevelPrefix,RcDir.NumberOfNamedEntries,
- szLevelPrefix,RcDir.NumberOfIdEntries);//打印结构体
- //紧接着这个结构体的是名字项和ID项
- lBeginOfEntry=ftell(fp);
- dwNbEntries=RcDir.NumberOfNamedEntries+RcDir.NumberOfIdEntries;//取得总项数
- //读取所有项
- for(dwEntries=0;dwEntries<dwNbEntries;dwEntries++)
- {
- IMAGE_RESOURCE_DIRECTORY_ENTRY RcDirEntry;
- fseek(fp,lBeginOfEntry+dwEntries*sizeof(RcDirEntry),SEEK_SET);//先读取项
- fread(&RcDirEntry,1,sizeof(RcDirEntry),fp);
- //先打印资源的名字或ID
- if(RcDirEntry.NameIsString)//如果是名字
- {
- WORD wLength;
- WCHAR*pszName;
- //读取名称长度
- fseek(fp,dwResourceBegin+RcDirEntry.NameOffset,SEEK_SET);
- fread(&wLength,1,sizeof(wLength),fp);
- //分配内存读取名称
- pszName=(WCHAR*)malloc((wLength+1)*sizeof(WCHAR));
- if(pszName)
- {
- pszName[wLength]=0;
- fread(pszName,1,wLength*sizeof(WCHAR),fp);
- printf("%sName:%S\n",szLevelPrefix,pszName);
- free(pszName);
- }
- else
- fputs("No enough memory.\n",stderr);
- }
- else//否则是ID
- printf("%sID:0x%08X\n",szLevelPrefix,RcDirEntry.Id);
- //然后打印资源的下一级内容
- if(RcDirEntry.DataIsDirectory)//如果下一级是一个子目录表
- ReadResDirEntry(fp,dwResourceBegin,RcDirEntry.OffsetToDirectory,uLevel+1);//递归查找
- else
- {
- //指向数据。
- IMAGE_RESOURCE_DATA_ENTRY DataEntry;
- //读取数据表
- fseek(fp,dwResourceBegin+RcDirEntry.OffsetToData,SEEK_SET);
- fread(&DataEntry,1,sizeof(DataEntry),fp);
- //打印数据信息
- printf(
- "%sOffsetToData:0x%08X\n"
- "%sSize:0x%08X\n"
- "%sCodePage:0x%08X\n",
- szLevelPrefix,DataEntry.OffsetToData,
- szLevelPrefix,DataEntry.Size,
- szLevelPrefix,DataEntry.CodePage);
- }
- }
- free(szLevelPrefix);
- }
- //-----------------------------------------------------------------------------
- //程序入口点
- //-----------------------------------------------------------------------------
- int main(int argc,char**argv)
- {
- FILE*fp;
- if(argc<2)
- {
- Usage();
- return 1;
- }
- fp=fopen(argv[1],"rb");
- if(!fp)
- {
- printf("Unable to open %s.\n",argv[1]);
- 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)//如果有可选标头
- {
- g_pOPTBuffer=malloc(g_PEH.SizeOfOptionalHeader);
- if(g_pOPTBuffer)
- {
- fputs("Optional header:\n",stdout);
- fread(g_pOPTBuffer,1,g_PEH.SizeOfOptionalHeader,fp);//读取
- switch(*(WORD*)g_pOPTBuffer)//读取魔法数字
- {
- case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
- fputs("-----------------------------32 bit optional header----------------------------\n",stdout);
- ReadOPT32(fp);
- break;
- case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
- fputs("-----------------------------64 bit optional header----------------------------\n",stdout);
- ReadOPT64(fp);
- break;
- case IMAGE_ROM_OPTIONAL_HDR_MAGIC:
- fputs("-----------------------------Rom optional header-------------------------------\n",stdout);
- ReadROMOPT(fp);
- break;
- default:
- fputs("Unknown optional header.\n",stdout);
- break;
- }
- ReadSegH(fp);//读取区段
- switch(*(WORD*)g_pOPTBuffer)//读取导入、导出表(需要在读取区段后读取。)
- {
- case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
- ReadDirEntry(fp,((IMAGE_OPTIONAL_HEADER32*)g_pOPTBuffer)->NumberOfRvaAndSizes,((IMAGE_OPTIONAL_HEADER32*)g_pOPTBuffer)->DataDirectory);
- break;
- case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
- ReadDirEntry(fp,((IMAGE_OPTIONAL_HEADER64*)g_pOPTBuffer)->NumberOfRvaAndSizes,((IMAGE_OPTIONAL_HEADER64*)g_pOPTBuffer)->DataDirectory);
- break;
- }
- free(g_pOPTBuffer);g_pOPTBuffer=NULL;
- free(g_pSecH);g_pSecH=NULL;
- }
- 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;
- }
复制代码
代码有点长。。。
下载地址: |
|