遍历PE文件头、扩展头、数据目录表、区段表信息

原创 2015年11月18日 16:15:57
#include "stdafx.h"
#include <Windows.h>

extern void DirectoryString(DWORD dwIndex);

int _tmain(int argc, _TCHAR* argv[])
{
	//获取文件句柄
	HANDLE hFile = CreateFile(
		_T("D:\\PE.exe"),
		GENERIC_READ,
		0,
		NULL,
		OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	//获取文件大小
	DWORD dwFileSize = GetFileSize(hFile, NULL);
	CHAR *pFileBuf = new CHAR[dwFileSize];
	//将文件读取到内存
	DWORD ReadSize = 0;
	ReadFile(hFile, pFileBuf, dwFileSize, &ReadSize, NULL);

	//判断是否为PE文件
	PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuf;
	if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
	{
		//不是PE
		printf("不是PE文件\n");
		system("pause");
		return 0;
	}

	PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(pFileBuf + pDosHeader->e_lfanew);
	if (pNtHeader->Signature != IMAGE_NT_SIGNATURE)
	{
		//不是PE文件
		printf("不是PE文件\n");
		system("pause");
		return 0;
	}

	//获取基本PE头信息
	//获取信息所用到的两个结构体指针	(这两个结构体都属于NT头)
	PIMAGE_FILE_HEADER		pFileHeader		= &(pNtHeader->FileHeader);
	PIMAGE_OPTIONAL_HEADER	pOptionalHeader	= &(pNtHeader->OptionalHeader);
	//输出PE头信息
	printf("================== 基 本 P E 头 信 息 ==================\n\n");
	printf("入 口 点:\t%08X\t", pOptionalHeader->AddressOfEntryPoint);
	printf("子 系 统:\t%04X\n", pOptionalHeader->Subsystem);
	printf("镜像基址:\t%08X\t", pOptionalHeader->ImageBase);
	printf("区段数目:\t%04X\n", pFileHeader->NumberOfSections);
	printf("镜像大小:\t%08X\t", pOptionalHeader->SizeOfImage);
	printf("日期时间标志:\t%08X\n", pFileHeader->TimeDateStamp);
	printf("代码基址:\t%08X\t", pOptionalHeader->BaseOfCode);
	printf("部首大小:\t%08X\n", pOptionalHeader->SizeOfHeaders);
	printf("数据基址:\t%08X\t", pOptionalHeader->BaseOfData);
	printf("特 征 值:\t%04X\n", pFileHeader->Characteristics);
	printf("块 对 齐:\t%08X\t", pOptionalHeader->SectionAlignment);
	printf("校 验 和:\t%08X\n", pOptionalHeader->CheckSum);
	printf("文件块对齐:\t%08X\t", pOptionalHeader->FileAlignment);
	printf("可选头部大小:\t%04X\n", pFileHeader->SizeOfOptionalHeader);
	printf("标 志 字:\t%04X\t\t", pOptionalHeader->Magic);
	printf("RVA数及大小:\t%08X\n\n", pOptionalHeader->NumberOfRvaAndSizes);

	printf("======================= 目 录 表 =======================\n");
	//获取目录表头指针
	PIMAGE_DATA_DIRECTORY pDataDirectory = pOptionalHeader->DataDirectory;
	printf("\t\t  RAV\t\t  大小\n");
	for (DWORD i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++)
	{
		DirectoryString(i);
		printf("%08X\t%08X\n",
			pDataDirectory[i].VirtualAddress, pDataDirectory[i].Size);
	}

	printf("======================= 区 段 表 =======================\n");
	//获取区段表头指针
	PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(pNtHeader);
	printf("名称      VOffset   VSize     ROffset   RSize     标志\n");
	//获取区段个数
	DWORD dwSectionNum = pFileHeader->NumberOfSections;
	//根据区段个数遍历区段信息
	for (DWORD i = 0; i < dwSectionNum; i++, pSectionHeader++)
	{
		for (DWORD j = 0; j < IMAGE_SIZEOF_SHORT_NAME; j++)
		{
			printf("%c", pSectionHeader->Name[j]);
		}
		printf("  %08X  %08X  %08X  %08X  %08X\n",
			pSectionHeader->VirtualAddress,
			pSectionHeader->Misc.VirtualSize,
			pSectionHeader->PointerToRawData,
			pSectionHeader->SizeOfRawData,
			pSectionHeader->Characteristics);
	}
	printf("\n");

	system("pause");
	return 0;
}

void DirectoryString(DWORD dwIndex)
{
	switch (dwIndex)
	{
	case 0:printf("输出表:\t\t");
		break;
	case 1:printf("输入表:\t\t");
		break;
	case 2:printf("资源:\t\t");
		break;
	case 3:printf("异常:\t\t");
		break;
	case 4:printf("安全:\t\t");
		break;
	case 5:printf("重定位:\t\t");
		break;
	case 6:printf("调试:\t\t");
		break;
	case 7:printf("版权:\t\t");
		break;
	case 8:printf("全局指针:\t");
		break;
	case 9:printf("TLS表:\t\t");
		break;
	case 10:printf("载入配置:\t");
		break;
	case 11:printf("输入范围:\t");
		break;
	case 12:printf("IAT:\t\t");
		break;
	case 13:printf("延迟输入:\t");
		break;
	case 14:printf("COM:\t\t");
		break;
	case 15:printf("保留:\t\t");
		break;
	}
}


遍历效果演示:


版权声明:本文为博主原创文章,未经博主允许不得转载。

PE文件结构详解(二)可执行文件头

在PE文件结构详解(一)基本概念里,解释了一下PE文件的一些基本概念,从这篇开始,将正式讲解PE文件的详细结构。 了解一个文件的详细结构,最应该首先了解的就是这个文件的文件头的含义,因为几乎所有的文件...
  • evileagle
  • evileagle
  • 2013年09月23日 23:28
  • 27794

【C++源码】PE文件结构中导出表的解析

【C++源码】PE文件结构中导出表的解析 控制台版本
  • ProgrammeringLearner
  • ProgrammeringLearner
  • 2016年08月31日 19:39
  • 1318

【EXE PE】了解pe段--PE结构详解

来源:看雪论坛http://bbs.pediy.com/showthread.php?t=145912 1 基本概念 下表描述了贯穿于本文中的一些概念: 名称 描述 地址 是“虚拟地址...
  • zfpigpig
  • zfpigpig
  • 2013年09月06日 11:19
  • 4027

遍历文件目录及bmp位图信息头的读取

#include #include #include #include #pragma warning(disable:4996) //-----------------------------...
  • yinyuping
  • yinyuping
  • 2011年12月23日 00:08
  • 509

PE文件学习(二)数据目录表之导出表与导入表

数据目录表是PE中比较重要的一个组成部分,其结构如下: IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]#de...
  • SanSiro1
  • SanSiro1
  • 2015年08月25日 17:35
  • 1862

PE总结7---PE文件结构NT头之数据目录表 IMAGE_DATA_DIRECTORY

IMAGE_DATA_DIRCTORY结构如下: typedef struct _IMAGE_DATA_DIRECTORY { DWORD VirtualAddress; //相对虚拟地址 DW...
  • oBuYiSeng
  • oBuYiSeng
  • 2015年12月09日 09:01
  • 2326

PE格式解析-区段表及导入表结构详解

PE格式区段表与导入表的结构详解
  • qq_30145355
  • qq_30145355
  • 2017年12月21日 02:29
  • 58

关于PE文件新区段的创建

对于为已有的EXE文件加壳,一般我们会创建一个新的区段,在该区段中写入的是外壳代码。   新加一个区段,通常会有三个步骤   1.首先修改PE文件头部信息,NT头部的区段数目,修改OPTIONAL...
  • dasgk
  • dasgk
  • 2013年08月25日 09:56
  • 900

QT遍历目录获取文件信息

QFileInfo获取文件信息:文件名称,路径,大小,创建时间,修改时间,权限等使用路径:UNIX: /home/dipper/file1Windows: C://dipper//file1构造函数:...
  • songjinshi
  • songjinshi
  • 2011年03月22日 15:28
  • 14539

proc文件系统_每进程信息形成原理、目录遍历方式、位图查找

我们知道在linux中,proc系统中对于每个进程都有一个进程相关的目录,里面描述了该进程各个方面详细的信息,本文探讨3个问题: 1: /proc目录下每进程子目录的形成[动态遍历当前进程列表形成]...
  • zhoujian19880205
  • zhoujian19880205
  • 2012年04月04日 16:13
  • 1375
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:遍历PE文件头、扩展头、数据目录表、区段表信息
举报原因:
原因补充:

(最多只允许输入30个字)