这里给出的提取文件PE头部信息到控制台的代码:
// PETool自编版.cpp : Defines the entry point for the console application. // #include <stdio.h> #include <stdlib.h> #include <windows.h> #include <malloc.h> #include "Function.h" int main(int argc, char* argv[]){ FILE *fp1,*fp2; int File_length,choose1,choose2; DWORD i=1,j=0; char *File_Buffer; char Filename[20]; printf("***************************欢迎使用PETool自编版***************************\n"); //用户输入 //printf("请输入想要查看的文件(exe文件):"); //打开文件 fp1=File_open(Filename); //计算文件大小 File_length=File_size(fp1); //申请内存 File_Buffer=File_malloc(File_length); //向内存缓冲区写入数据 if(File_read(File_Buffer,1,File_length,fp1)){ printf("向内存缓冲区写入数据成功!\n"); }else{ printf("写入数据失败!\n"); } //用户选择 printf("***********************1.在控制台输出PE头信息。***************************\n"); //printf("***********************2.将PE头信息保存到txt文件中(暂时不可用)。********\n"); printf("请输入您需要的项目:"); scanf("%d",&choose1); printf("**************************1.输出所有PE头部信息。**************************\n"); printf("**************************2.输出DOS头信息。 ***************************\n"); printf("**************************3.输出标准PE头部信息。**************************\n"); printf("**************************4.输出可选PE头部信息。**************************\n"); printf("**************************5.节表信息。 **************************\n"); printf("请选择您要输出的项目:"); scanf("%d",&choose2); //实例化结构体 IMAGE_DOS_HEADER pDosHeader; IMAGE_NT_HEADERS pNTHeader; IMAGE_SECTION_HEADER pSectionHeader; switch (choose1){ case 1:{ switch(choose2){ case 2:{ //输出DOS头部 pDosHeader=*(IMAGE_DOS_HEADER*)File_Buffer; printf("********************************DOS头部********************************\n"); printf("e_magic(MZ标志): 0x%x\n",pDosHeader.e_magic); printf("e_lfanew(PE偏移): 0x%x\n\n",pDosHeader.e_lfanew); break; } case 1:{ //输出DOS头部 pDosHeader=*(IMAGE_DOS_HEADER*)File_Buffer; printf("********************************DOS头部********************************\n"); printf("e_magic(MZ标志): 0x%x\n",pDosHeader.e_magic); printf("e_lfanew(PE偏移): 0x%x\n\n",pDosHeader.e_lfanew); } case 3:{ //输出标准PE头部 if(*((PDWORD)((DWORD)File_Buffer+pDosHeader.e_lfanew)) == IMAGE_NT_SIGNATURE){ printf("经检测是有效的PE标志(有效的PE文件)。\n\n"); }else{ printf("不是有效的PE标志!\n"); free(File_Buffer); } pNTHeader=*(IMAGE_NT_HEADERS*)(File_Buffer+pDosHeader.e_lfanew); printf("****************************标准PE头部信息*****************************\n"); printf("Machine(运行平台): 0x%x\n",pNTHeader.FileHeader.Machine); printf("NumberOfSections(区块的数量): 0x%x\n",pNTHeader.FileHeader.NumberOfSections); printf("TimeDataStap(时间戳): 0x%x\n",pNTHeader.FileHeader.TimeDateStamp); printf("SizeOfOptionalHeader(可选PE头的大小): 0x%x\n",pNTHeader.FileHeader.SizeOfOptionalHeader); printf("Characteristics(特征/特性): 0x%x\n\n",pNTHeader.FileHeader.Characteristics); if(choose2==3)break; } case 4:{ printf("****************************可选PE头部信息*****************************\n"); printf("Magic() 0x%d",pNTHeader.OptionalHeader.Magic); printf("AddressOfEntryPoint(程序入口RVA) 0x%d\n",pNTHeader.OptionalHeader.AddressOfEntryPoint); printf("ImageBase(内存镜像基址) 0x%d\n",pNTHeader.OptionalHeader.ImageBase); printf("SectionAlignment(内存对齐大小) 0x%d\n",pNTHeader.OptionalHeader.SectionAlignment); printf("FileAlignment(文件对齐大小) 0x%d\n",pNTHeader.OptionalHeader.FileAlignment); printf("SizeOfImage(映像装入内存后的大小) 0x%d\n",pNTHeader.OptionalHeader.SizeOfImage); printf("SizeOfHeaders(所有头按照文件对齐后的大小和) 0x%d\n\n",pNTHeader.OptionalHeader.SizeOfHeaders); if(choose2==4)break; } case 5:{ printf("*****************************节表信息**********************************\n"); //i=(DWORD)i; pDosHeader=*(IMAGE_DOS_HEADER*)File_Buffer; pNTHeader=*(IMAGE_NT_HEADERS*)(File_Buffer+pDosHeader.e_lfanew); pSectionHeader=*(IMAGE_SECTION_HEADER*)((DWORD)File_Buffer+pDosHeader.e_lfanew+20+pNTHeader.FileHeader.SizeOfOptionalHeader); for(i=1;i<=pNTHeader.FileHeader.NumberOfSections;i++){ printf("*****************************第%d个节表信息*****************************\n",i); printf("name(名称): %c",pSectionHeader.Name); for(j = 1;j<IMAGE_SIZEOF_SHORT_NAME+1;j++) { printf("%c",pSectionHeader.Name[j]); } printf("\nMisc(区块的数据没有对齐前的实际大小): %x\n",pSectionHeader.Misc.VirtualSize); printf("VirtualAddress(该块装在到内存的RVA): %x\n",pSectionHeader.VirtualAddress); printf("SizeOfRvaData(该块在磁盘文件中所占大小): %x\n",pSectionHeader.SizeOfRawData); printf("PointToRvaDta(该块在磁盘文件中的偏移): %x\n",pSectionHeader.PointerToRawData); printf("Characteristics(块属性): %x\n\n",pSectionHeader.Characteristics); pSectionHeader=*(((IMAGE_SECTION_HEADER*)((DWORD)File_Buffer+pDosHeader.e_lfanew+(DWORD)20+pNTHeader.FileHeader.SizeOfOptionalHeader))+i); } if(choose2=5)break; } } } } return 0; }
代码中还有许多可优化的地方,希望大家指出,我会非常虚心地听取大家的建议,希望我们能共同进步!