pe结构打印

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include<Windows.h>


int main() {
	//要读取的exe   读取
	FILE* fp = NULL;
	
	//要写入的位置
	FILE* new_fp = NULL;
	long file_size;
	char* file_buffer;//文件
	char* image_buffer;//内存映像
	char* new_buffer;
	fp = fopen("C:\\Users\\asus\\Desktop\\PETool.exe", "rb");
	fseek(fp, 0, SEEK_END);//指向文件末尾
	file_size = ftell(fp);//当前指针位置 相对于 文件首地址 的 偏移字节数
	fseek(fp, 0, SEEK_SET);//指向文件开始
	printf("文件大小:%d字节\n", file_size);

	//申请内存空间存放PE文件
	file_buffer = (char*)malloc(file_size);
	memset(file_buffer, 0, file_size);
	fread(file_buffer,file_size,1,fp);
	PIMAGE_DOS_HEADER pDos_Header = (PIMAGE_DOS_HEADER)file_buffer;

	//DOS头
	printf("DOS头\n");
	printf("Dos头起始位置:0x%x\n", pDos_Header);
	printf("打印pDos_Header->\ne_magic:%x\t\t\tMZ标记用于判断是否为可执行文件 \n", pDos_Header->e_magic);// "MZ标记" 用于判断是否为可执行文件.	
	printf("e_lfanew:%x\t\t\tPE头相对于文件的偏移,用于定位PE文件\n", pDos_Header->e_lfanew);// PE头相对于文件的偏移,用于定位PE文件
	//NT头
	printf("\n打印NT头\n\n");
	PIMAGE_NT_HEADERS pNT_Header = (PIMAGE_NT_HEADERS)(file_buffer + pDos_Header->e_lfanew);
	printf("pNT_Header:%x\t\t\t打印NT头起始位置\n",pNT_Header);
	printf("Signature:%.8x\t\t\t\n",pNT_Header->Signature);
	printf("FileHeader:%.8x\t\t\t\n",pNT_Header->FileHeader);
	printf("OptionalHeader: % .8x\t\t\t\n",pNT_Header->OptionalHeader);
	printf("\n打印标准PE头\n\n");
	printf("Machine: % .8x\t\t\t程序运行的CPU型号:0x0 任何处理器/0x14C 386及后续处理器\n", pNT_Header->FileHeader.Machine);
	printf("NumberOfSections: % .8x\t\t文件中存在的节的总数,如果要新增节或者合并节 就要修改这个值\n", pNT_Header->FileHeader.NumberOfSections);
	printf("TimeDateStamp: % .8x\t\t\t时间戳:文件的创建时间(操作系统的创建时间无关),编译器填写的\n", pNT_Header->FileHeader.TimeDateStamp);
	printf("SizeOfOptionalHeader: % .8x\t\t可选PE头的大小,32位PE文件默认E0h 64位PE文件默认为F0h小可以自定义\n", pNT_Header->FileHeader.SizeOfOptionalHeader);
	printf("Characteristics: % .8x\t\t每个位有不同的含义,可执行文件值为10F 即0 1 2 3 8位置1\n", pNT_Header->FileHeader.Characteristics);
	printf("\n打印扩展PE头\n\n");
	printf("Magic: % .8x\t\t\t\t说明文件类型:10B 32位下的PE文件     20B 64位下的PE文件\n", pNT_Header->OptionalHeader.Magic);
	//printf("MajorLinkerVersion: % .8x\t\t\t \n", pNT_Header->OptionalHeader.MajorLinkerVersion);
	//printf("MinorLinkerVersion: % .8x\t\t\t\n", pNT_Header->OptionalHeader.MinorLinkerVersion);
	printf("SizeOfCode: % .8x\t\t\t所有代码节的和,必须是FileAlignment的整数倍 编译器填的  没用\n", pNT_Header->OptionalHeader.SizeOfCode);
	printf("SizeOfInitializedData: % .8x\t\t已初始化数据大小的和,必须是FileAlignment的整数倍 编译器填的  没用\n", pNT_Header->OptionalHeader.SizeOfInitializedData);
	printf("SizeOfUninitializedData: % .8x\t未初始化数据大小的和,必须是FileAlignment的整数倍 编译器填的  没用\n", pNT_Header->OptionalHeader.SizeOfUninitializedData);
	printf("AddressOfEntryPoint: % .8x\t\t程序的入口\n", pNT_Header->OptionalHeader.AddressOfEntryPoint);
	printf("BaseOfCode: % .8x\t\t\t代码开始的基址,编译器填的   没用\n", pNT_Header->OptionalHeader.BaseOfCode);
	printf("BaseOfData: % .8x\t\t\t数据开始的基址,编译器填的   没用\n", pNT_Header->OptionalHeader.BaseOfData);
	printf("ImageBase: % .8x\t\t\t内存镜像基址\n", pNT_Header->OptionalHeader.ImageBase);
	printf("SectionAlignment: % .8x\t\t内存对齐\n", pNT_Header->OptionalHeader.SectionAlignment);
	printf("FileAlignment: % .8x\t\t\t文件对齐\n", pNT_Header->OptionalHeader.FileAlignment);
	printf("SizeOfImage: % .8x\t\t\t内存中整个PE文件的映射的尺寸,可以比实际的值大,但必须是SectionAlignment的整数倍\t\n", pNT_Header->OptionalHeader.SizeOfImage);
	printf("SizeOfHeaders: % .8x\t\t\t所有头+节表按照文件对齐后的大小,否则加载会出错\n", pNT_Header->OptionalHeader.SizeOfHeaders);
	printf("CheckSum: % .8x\t\t\t校验和,一些系统文件有要求.用来判断文件是否被修改.\n", pNT_Header->OptionalHeader.CheckSum);
	//printf("Subsystem: % .8x\t\t\t\n", pNT_Header->OptionalHeader.Subsystem);
	//printf("DllCharacteristics: % .8x\t\t\t\n", pNT_Header->OptionalHeader.DllCharacteristics);
	printf("SizeOfStackReserve: % .8x\t\t初始化时保留的堆栈大小\n", pNT_Header->OptionalHeader.SizeOfStackReserve);
	printf("SizeofStackCommit: % .8x\t\t初始化时实际提交的大小\n", pNT_Header->OptionalHeader.SizeOfStackCommit);
	printf("SizeOfHeapReserve: % .8x\t\t初始化时保留的堆大小\n", pNT_Header->OptionalHeader.SizeOfHeapReserve);
	printf("SizeOfHeapCommit: % .8x\t\t初始化时十几提交的大小\n", pNT_Header->OptionalHeader.SizeOfHeapCommit); 
	//printf("LoaderFlags: % .8x\t\t\t\n", pNT_Header->OptionalHeader.LoaderFlags);
	printf("NumberOfRvaAndSizes: % .8x\t\t目录项数目\n", pNT_Header->OptionalHeader.NumberOfRvaAndSizes);
	//打印节表  区段
	PIMAGE_SECTION_HEADER pSction_Header = IMAGE_FIRST_SECTION(pNT_Header);
	printf("\t**************************\t\n");
	for (size_t i = 0; i < pNT_Header->FileHeader.NumberOfSections; i++)
	{
		printf("打印节表%d\n",i+1);
		printf("name:%s\t\t\t区段、节名字\n",pSction_Header[i].Name);
		printf("PhysicalAddress:%.8X\t\t\t\n", pSction_Header[i].Misc.PhysicalAddress);
		printf("VirtualSize:%.8X\t\t\t\n", pSction_Header[i].Misc.VirtualSize);
		printf("Misc:%.8X\t\t\t双字 是该节在没有对齐前的真实尺寸,该值可以不准确\n", pSction_Header[i].Misc);
		printf("VirtualAddress:%.8X\t\t节区在内存中的偏移地址。加上ImageBase才是在内存中的真正地址.\n", pSction_Header[i].VirtualAddress);
		printf("SizeOfRawData:%.8X\t\t节在文件中对齐后的尺寸.\n", pSction_Header[i].SizeOfRawData);
		printf("PointerToRawData:%.8X\t节区在文件中的偏移.\n", pSction_Header[i].PointerToRawData);
		/*
		6、PointerToRelocations 在obj文件中使用 对exe无意义																				
		7、PointerToLinenumbers 行号表的位置 调试的时候使用																				
		8、NumberOfRelocations 在obj文件中使用  对exe无意义																			
		9、NumberOfLinenumbers 行号表中行号的数量 调试的时候使用
		*/
		printf("Characteristics:%.8X\t节的属性\n\n", pSction_Header[i].Characteristics);
		




	}





	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值