逆向笔记——打印PE的信息

平台:winxp,
编译:VC++6.0
工具:PETool

PE结构图

PE结构也可以通过PETool查看,比较直观

//备注:这里用的是结构体来打印的,也可使用指针打印
void PrintPEInfo( FILE* fileAddr )
{
	printf("fileAddr:%x
",fileAddr);

	IMAGE_DOS_HEADER myDosHeader;
	IMAGE_NT_HEADERS32 myNTHeaders32;
	IMAGE_FILE_HEADER myFileHeader;
	IMAGE_OPTIONAL_HEADER32 myOptionalHeader32;

	//2、将指针指向DOS头
	fread(&myDosHeader,sizeof(IMAGE_DOS_HEADER),1,fileAddr);
		//2.1 打印 可执行文件标志 magic
	printf("e_magic:%x
",myDosHeader.e_magic);
		//2.2 打印 PE头文件地址
	printf("e_lfanew:%x
",myDosHeader.e_lfanew);

	//3、将指针指向NT头
	fseek(fileAddr,myDosHeader.e_lfanew,SEEK_SET);
	fread(&myNTHeaders32,sizeof(IMAGE_NT_HEADERS32),1,fileAddr);
		//3.1 打印PE文件标志
	printf("Signature:%x
",myNTHeaders32.Signature);	

	//4、将指针指向PE头
	fseek(fileAddr,myDosHeader.e_lfanew+sizeof(DWORD),SEEK_SET);
	fread(&myFileHeader,sizeof(IMAGE_FILE_HEADER),1,fileAddr);
		//4.1 运行平台
	printf("Machine:%x
",myFileHeader.Machine);
		//4.2 节的数量
	printf("NumberOfSections:%x
",myFileHeader.NumberOfSections);	
		//4.3 文件创建时的时间戳
	printf("TimeDateStamp:%x
",myFileHeader.TimeDateStamp);	
		//4.4 文件属性
	printf("Characteristics:%x
",myFileHeader.Characteristics);

	//5、将指针指向PE可选头
	fseek(fileAddr,myDosHeader.e_lfanew+0x18,SEEK_SET);
	fread(&myOptionalHeader32,sizeof(IMAGE_OPTIONAL_HEADER32),1,fileAddr);
		//5.1 标志字(幻数) 用来说明文件是ROM映像,还是普通可执行文件
	printf("Magic:%x
",myOptionalHeader32.Magic);		
		//5.2 代码段(所有代码段)对齐后的大小
	printf("SizeOfCode:%x
",myOptionalHeader32.SizeOfCode);
		//5.3 已初始化数据块大小
	printf("SizeOfInitializedData:%x
",myOptionalHeader32.SizeOfInitializedData);
		//5.4 未初始化数据块大小
	printf("SizeOfUninitializedData:%x
",myOptionalHeader32.SizeOfUninitializedData);
		//5.5 RVA OEP(相对入口地址)
	//addressOfEntryPoint = myOptionalHeader32.AddressOfEntryPoint;
	printf("AddressOfEntryPoint:%x
",myOptionalHeader32.AddressOfEntryPoint);
		//5.6 代码段的起始地址
	printf("BaseOfCode:%x
",myOptionalHeader32.BaseOfCode);
		//5.7 数据段的起始地址
	printf("BaseOfData:%x
",myOptionalHeader32.BaseOfData);
		//5.8 程序默认装入的地址(基址),相对地址需要加上这个基址才是真正的地址
	printf("ImageBase:%x
",myOptionalHeader32.ImageBase);
		//5.9 内存中节的对齐值
	printf("SectionAlignment:%x
",myOptionalHeader32.SectionAlignment);
		//5.A 文件中节的对齐值
	printf("FileAlignment:%x
",myOptionalHeader32.FileAlignment);
		//5.B 映像(文件装入内存中)大小
//	sizeOfImage = myOptionalHeader32.SizeOfImage;
	printf("SizeOfImage:%x
",myOptionalHeader32.SizeOfImage);
		//5.C 首部及块表(首部+块表)的大小
	printf("SizeOfHeaders:%x
",myOptionalHeader32.SizeOfHeaders);
	//6、将指针指向节
	IMAGE_SECTION_HEADER *pmySectionHeader = (IMAGE_SECTION_HEADER *)calloc(myFileHeader.NumberOfSections,sizeof(IMAGE_SECTION_HEADER));
    fseek(fileAddr,(myDosHeader.e_lfanew+sizeof(IMAGE_NT_HEADERS)),SEEK_SET);
    fread(pmySectionHeader,sizeof(IMAGE_SECTION_HEADER),myFileHeader.NumberOfSections,fileAddr);
	for(int i=0; i<myFileHeader.NumberOfSections; i++, pmySectionHeader++)
	{
		//6.1 节的名字
		printf("Name:%s
",pmySectionHeader->Name);
		//6.2 未齐前 内存中的大小
		printf("VirtualSize:%x
",pmySectionHeader->Misc.VirtualSize);
		//6.3 文件中的偏移
		printf("PointerToRawData:%x
",pmySectionHeader->PointerToRawData);
		//6.4 对齐后 文件中的大小
		printf("SizeOfRawData:%x
",pmySectionHeader->SizeOfRawData);
		//6.5 内存中的偏移
		printf("VirtualAddress:%x
",pmySectionHeader->VirtualAddress);
		//6.6 节属性
		printf("Characteristics:%x
",pmySectionHeader->Characteristics);

	}
	//7、关闭文件
	fclose(fileAddr);
}
原文地址:https://www.cnblogs.com/Erma/p/12593659.html