DOS版PE工具制作

// PE.cpp : 定义控制台应用程序的入口点。
//DOS版PE工具制作

#include "stdafx.h"
#include <windows.h>
#include <winnt.h>


int filelength(FILE *fp);
int _tmain(int argc, _TCHAR* argv[])
{
	FILE *Fp;
	int FpSize = 0;
	short e_lfanew = 0;
	fopen_s(&Fp, "C:\Users\Administrator\Desktop\MSG.exe", "rb");
	FpSize = filelength(Fp);//获取文件大小
	char * TempBuffer = (char *)malloc(FpSize);//申请存放文件的内存空间
	if (TempBuffer == NULL)
	{
		fclose(Fp);
		free(TempBuffer);
		return 0;
	}
	fread_s(TempBuffer, FpSize + 1, 1, FpSize, Fp);//将文件读入内存中
	TempBuffer = (char *)(TempBuffer + *(int *)(TempBuffer + 0x3c));//获取PE标志地址
	PIMAGE_FILE_HEADER MyFileHeader;
	printf("----------------------------------------------
");
	printf("PE标记:%08x
", *(int *)TempBuffer);
	printf("----------------------------------------------
");
	TempBuffer = TempBuffer + 0x4;//指针指向标准PE头首地址
	MyFileHeader = (PIMAGE_FILE_HEADER)TempBuffer;
	printf("IMAGE_FILE_HEADER结构:
");
	printf("----------------------------------------------
");
	printf("Machine                      : %04X
", MyFileHeader->Machine);//运行平台 
	printf("NumberOfSections             : %04X
", MyFileHeader->NumberOfSections);//区块数目
	printf("TimeDateStamp                : %08X
", MyFileHeader->TimeDateStamp);//文件日期时间戳 
	printf("PointerToSymbolTable         : %08X
", MyFileHeader->PointerToSymbolTable);//指向符号表 
	printf("NumberOfSymbols              : %08X
", MyFileHeader->NumberOfSymbols);//符号表中的符号数量 
	printf("SizeOfOptionalHeader         : %04X
", MyFileHeader->SizeOfOptionalHeader);//映像可选头结构的大小 
	printf("Characteristics              : %04X
", MyFileHeader->Characteristics);//文件特征值 
	printf("----------------------------------------------
");
	TempBuffer = TempBuffer + 0x14;//指针指向可选PE头首地址
	PIMAGE_OPTIONAL_HEADER  MyOptionalHeader;
	MyOptionalHeader = (PIMAGE_OPTIONAL_HEADER)TempBuffer;
	printf("IMAGE_OPTIONAL_HEADER结构:
");
	printf("----------------------------------------------
");
	printf("Magic                        : %04X
", MyOptionalHeader->Magic);//幻数,32位pe文件总为010bh 
	printf("MajorLinkerVersion           : %02X
", MyOptionalHeader->MajorLinkerVersion);//连接器主版本号 
	printf("MinorLinkerVersion           : %02X
", MyOptionalHeader->MinorLinkerVersion);//连接器副版本号 
	printf("SizeOfCode                   : %08X
", MyOptionalHeader->SizeOfCode);//代码段总大小 
	printf("SizeOfInitializedData        : %08X
", MyOptionalHeader->SizeOfInitializedData);//已初始化数据段总大小 
	printf("SizeOfUninitializedData      : %08X
", MyOptionalHeader->SizeOfUninitializedData);//未初始化数据段总大小 
	printf("AddressOfEntryPoint          : %08X
", MyOptionalHeader->AddressOfEntryPoint);//程序执行入口地址(RVA) 
	printf("BaseOfCode                   : %08X
", MyOptionalHeader->BaseOfCode);//代码段起始地址(RVA) 
	printf("BaseOfData                   : %08X
", MyOptionalHeader->BaseOfData);//数据段起始地址(RVA) 
	printf("ImageBase                    : %08X
", MyOptionalHeader->ImageBase);//程序默认的装入起始地址 
	printf("SectionAlignment             : %08X
", MyOptionalHeader->SectionAlignment);//内存中区块的对齐单位  
	printf("FileAlignment                : %08X
", MyOptionalHeader->FileAlignment);//文件中区块的对齐单位
	printf("MajorOperatingSystemVersion  : %04X
", MyOptionalHeader->MajorOperatingSystemVersion);//所需操作系统主版本号 
	printf("MinorOperatingSystemVersion  : %04X
", MyOptionalHeader->MinorOperatingSystemVersion);//所需操作系统副版本号
	printf("MajorImageVersion            : %04X
", MyOptionalHeader->MajorImageVersion);//自定义主版本号
	printf("MinorImageVersion            : %04X
", MyOptionalHeader->MinorImageVersion);//自定义副版本号 
	printf("MajorSubsystemVersion        : %04X
", MyOptionalHeader->MajorSubsystemVersion);//所需子系统主版本号 
	printf("MinorSubsystemVersion        : %04X
", MyOptionalHeader->MinorSubsystemVersion);//所需子系统副版本号
	printf("Win32VersionValue            : %08X
", MyOptionalHeader->Win32VersionValue);//总是0 
	printf("SizeOfImage                  : %08X
", MyOptionalHeader->SizeOfImage);//pe文件在内存中的映像总大小
	printf("SizeOfHeaders                : %08X
", MyOptionalHeader->SizeOfHeaders);//从pe文件开始到节表(包含节表)的总大小
	printf("CheckSum                     : %08X
", MyOptionalHeader->CheckSum);//pe文件CRC校验和  
	printf("Subsystem                    : %04X
", MyOptionalHeader->Subsystem);//用户界面使用的子系统类型  
	printf("DllCharacteristics           : %04X
", MyOptionalHeader->DllCharacteristics);//为0 
	printf("SizeOfStackReserve           : %08X
", MyOptionalHeader->SizeOfStackReserve);//为线程的栈初始保留的虚拟内存的默认值  
	printf("SizeOfStackCommit            : %08X
", MyOptionalHeader->SizeOfStackCommit);//为线程的栈初始提交的虚拟内存的大小 
	printf("SizeOfHeapReserve            : %08X
", MyOptionalHeader->SizeOfHeapReserve);//为进程的堆保留的虚拟内存的大小  
	printf("SizeOfHeapCommit             : %08X
", MyOptionalHeader->SizeOfHeapCommit);//为进程的堆初始提交的虚拟内存的大小 
	printf("LoaderFlags                  : %08X
", MyOptionalHeader->LoaderFlags);//为0 
	printf("NumberOfRvaAndSizes          : %08X
", MyOptionalHeader->NumberOfRvaAndSizes);//数据目录结构数组的项数,总为 00000010h  
	TempBuffer = TempBuffer + MyFileHeader->SizeOfOptionalHeader;//指针指向区块首地址
	printf("----------------------------------------------
");
	printf("节表信息:
");
	printf("----------------------------------------------
");
	PIMAGE_SECTION_HEADER MySectionHeader;
	MySectionHeader = (PIMAGE_SECTION_HEADER)TempBuffer;
	for (int i = 0; i < MyFileHeader->NumberOfSections; i++)
	{
		printf("Name                     : %s
", MySectionHeader->Name);//区块名字 
		printf("Misc                     : %08X
", MySectionHeader->Misc);//在没有对齐前的真实大小
		printf("VirtualAddress           : %08X
", MySectionHeader->VirtualAddress);//节区在内存中的偏移地址
		printf("SizeOfRawData            : %08X
", MySectionHeader->SizeOfRawData);//节在文件中对齐后的大小
		printf("PointerToRawData         : %08X
", MySectionHeader->PointerToRawData);//节区在文件中的偏移
		printf("PointerToRelocations     : %08X
", MySectionHeader->PointerToRelocations);//在OBJ文件中使用 无意义
		printf("PointerToLinenumbers     : %08X
", MySectionHeader->PointerToLinenumbers);//行号表的位置 调试的时候用
		printf("NumberOfRelocations      : %04X
", MySectionHeader->NumberOfRelocations);//在OBJ文件中使用 对EXE无意义
		printf("NumberOfLinenumbers      : %04X
", MySectionHeader->NumberOfLinenumbers);//行号表中行号的数量 调试的时候用
		printf("Characteristics          : %08X
", MySectionHeader->Characteristics);//节的属性
		printf("----------------------------------------------
");
		MySectionHeader++;
	}
	
	fclose(Fp);
	getchar();
	free(TempBuffer);
	return 0;
}
//获取文件大小

int filelength(FILE *fp)
{
	int num;
	fseek(fp, 0, SEEK_END);
	num = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	return num;

}
原文地址:https://www.cnblogs.com/wumac/p/5259621.html