这里给出的提取文件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;
}
代码中还有许多可优化的地方,希望大家指出,我会非常虚心地听取大家的建议,希望我们能共同进步!