【滴水逆向三期41作业】C语言提取文件PE头部信息

这是一个C++程序,用于读取PE(PortableExecutable)文件的头部信息并显示在控制台。用户可以选择输出DOS头、标准PE头、可选PE头或节表信息。代码首先打开文件,计算文件大小,然后将内容读入内存缓冲区进行处理。
摘要由CSDN通过智能技术生成

这里给出的提取文件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;
}

代码中还有许多可优化的地方,希望大家指出,我会非常虚心地听取大家的建议,希望我们能共同进步!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shad0w-2023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值