DOS头与NT头手动解析以及编写读取PE文件的函数

PE头部分的解析可以由工具直接解析,但是新手初次接触PE文件时,可以尝试手动解析进行练习,加深印象。

查看PE头

可以使用PEview打开文件来查看PE文件的头部分,这里以使用PEview打开visio2003为例

在该界面可以看到文件中全部文件指针的数据,我们对照DOS头和NT头的结构,可以将该结构体的每一个成员与对应的数据对应起来。

需要注意的是,PEview是16进制编辑器,因此从左至右依次读取结构体成员对应的数据,但是读取的单个数据是以两个字节为一组,从右至左排列。

举个例子,根据PE头的结构,PE文件头部分的第一部分是DOS头,其第一个成员为e_magic,一共四个字节,则对应上图中的数据可知,e_magic的数据即为5A4D,同理,e_cdlp为0090,e_cp为0003......

将DOS头和NT头全部读取得:

DOS头:

pFileDataDescrption
WORD e_magic5A4DMagic number
WORD e_cblp0090Bytes on last page of file
WORD e_cp0003Pages in file
WORD e_crlc0000Relocations
WORD e_cparhdr0004Size of header in paragraphs
WORD e_minalloc0000Minimum extra paragraphs needed
WORD e_maxallocFFFFMaximum extra paragraphs needed
WORD e_ss0000Initial SS value
WORD e_sp00B8Initial SP value
WORD e_csum0000Checksum
WORD e_ip0000Initial IP value
WORD e_cs0000Initial CS value
WORD e_lfarlc0040File address of relocation table
WORD e_ovno0000Overlay number
WORD e_res[4]0000Reserved words
WORD e_oemid0000OEM identifier
WORD e_oeminfo0000OEM information
WORD e_res2[10]0000Reserved words
LONG e_lfanew000000F8File address of new exe header

标准PE头:

pFileData
WORD Machine014C
WORD NumberOfSections0005
DWORD TimeDateStamp472B98E3
DWORD PointerToSymbolTable00000000
DWORD NumberOfSymbols00000000
WORD SizeOfOptionalHeader00E0
WORD Characteristics010E

可选PE头:

pFileData
WORD Magic010B
BYTE MajorLinkerVersion07
BYTE MinorLinkerVersion0A
DWORD SizeOfCode00000600
DWORD SizeOfInitializedData0002B400
DWORD SizeOfUninitializedData00000000
DWORD AddressOfEntryPoint00001114
DWORD BaseOfCode00001000
DWORD BaseOfData00002000
DWORD ImageBase00400000
DWORD SectionAlignment00001000
DWORD FileAlignment00002000
WORD MajorOperatingSystemVersion0004
WORD MinorOperatingSystemVersion0000
WORD MajorImageVersion0000
WORD MinorImageVersion0000
WORD MajorSubsystemVersion0004
WORD MinorSubsystemVersion0000
DWORD Win32VersionValue00000000
DWORD SizeOfImage00030000
DWORD SizeOfHeaders00000400
DWORD CheckSum0003098D
WORD Subsystem0002
WORD DllCharacteristics0000
DWORD SizeOfStackReserve00100000
DWORD SizeOfStackCommit00001000
DWORD SizeOfHeapReserve00100000
DWORD SizeOfHeapCommit00001000
DWORD LoaderFlags00000000
DWORD NumberOfRvaAndSizes00000010

编写读取PE文件的函数

void* ReadPEfile(char* Filename)
{
//定义一个无类型的指针pfilebuffer
	void* pfilebuffer;
	FILE* pfile=NULL;
//以可读可写的方式打开文件
	pfile=fopen(Filename,"rb");
	if(pfile=NULL)
	{
		printf("Failed to open PEfile %s .",Filename);
		return 0;
	}
//读取文件大小(fseek将文件指针移到文件末尾,ftell返回文件首位之间的长度,再调用fseek将文件指针移动到文件开头)
	fseek(pfile,0,SEEK_END);
	Filesize=ftell(pfile);//预先定义Filesize为全局变量
	fseek(pfile,0,SEEK_SET);
//malloc函数申请内存空间
	pfilebuffer=malloc(Filesize);
	if(!pfilebuffer)
	{
		printf("Failed to apply for space .");
		fclose(pfile);
		return 0;
	}
//以一个字节为步长,从pfile所在的位置开始,将Filesize个数据读到pfilebuffer中
	int n=fread(pfilebuffer,Filesize,1,pfile);
	if(!n)
	{
		printf("Failed to read data");
		free(pfilebuffer);
		fclose(pfile);
	}
	fclose(pfile);
	return pfilebuffer;
};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值