遍历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文件版本信息、资源Version)

修改PE文件版本信息(简单演示)
  • tiewen
  • tiewen
  • 2014年04月14日 17:46
  • 7240

使用WinDbg获取SSDT 系统服务描述表的函数服务号(索引)

今天研究了一下午SSDT的东东,最尴尬的是起初我不知道如何获取到SSDT的函数服务号,而这个玩意儿在不同版本的windows是不一样的,后面经过研究还是找到了正确的方法.这里简单的分享一下. ...
  • whatday
  • whatday
  • 2016年10月10日 23:10
  • 493

伪造IP发送数据(UDP)

#include #include #include #include #include #include "protoinfo.h" #pragma comment (lib,"ws2_3...

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

#include #include #include #include #pragma warning(disable:4996) //-----------------------------...

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

IMAGE_DATA_DIRCTORY结构如下: typedef struct _IMAGE_DATA_DIRECTORY { DWORD VirtualAddress; //相对虚拟地址 DW...

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

数据目录表是PE中比较重要的一个组成部分,其结构如下: IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]#de...

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

我们知道在linux中,proc系统中对于每个进程都有一个进程相关的目录,里面描述了该进程各个方面详细的信息,本文探讨3个问题: 1: /proc目录下每进程子目录的形成[动态遍历当前进程列表形成]...

有感于滥用多线程之遍历文件目录信息

今天这篇博文,完全是有感而发,不仅仅是经常看到有人求文件夹遍历的代码,主要是,看到有些人写了一些多线程读取的方法,贴到网上供人参考使用,然后真有不少人特意求这种多线程遍历文件目录的方法。看到这个现象,...

QT遍历目录获取文件信息

QFileInfo获取文件信息:文件名称,路径,大小,创建时间,修改时间,权限等使用路径:UNIX: /home/dipper/file1Windows: C://dipper//file1构造函数:...

C++打印PE文件头信息Demo

PE文件格式被组织为一个线性的数据流,它由一个MS-DOS头部开始,接着是一个是模式的程序残余以及一个PE文件标志,这之后紧接着PE文件头和可选头部。这些之后是所有的段头部,段头部之后跟随着所有的段实...
  • iamoyjj
  • iamoyjj
  • 2011年06月09日 22:21
  • 3073
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:遍历PE文件头、扩展头、数据目录表、区段表信息
举报原因:
原因补充:

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