概述
首先感谢 cyxvc 老哥,他的代码可读性超高,精简有用以理解,我找这方面的资料好久了,这篇文章对我帮助很大。
参考代码:
#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 头 信 息 ==================nn");
printf("入 口 点:t%08Xt", pOptionalHeader->AddressOfEntryPoint);
printf("子 系 统:t%04Xn", pOptionalHeader->Subsystem);
printf("镜像基址:t%08Xt", pOptionalHeader->ImageBase);
printf("区段数目:t%04Xn", pFileHeader->NumberOfSections);
printf("镜像大小:t%08Xt", pOptionalHeader->SizeOfImage);
printf("日期时间标志:t%08Xn", pFileHeader->TimeDateStamp);
printf("代码基址:t%08Xt", pOptionalHeader->BaseOfCode);
printf("部首大小:t%08Xn", pOptionalHeader->SizeOfHeaders);
printf("数据基址:t%08Xt", pOptionalHeader->BaseOfData);
printf("特 征 值:t%04Xn", pFileHeader->Characteristics);
printf("块 对 齐:t%08Xt", pOptionalHeader->SectionAlignment);
printf("校 验 和:t%08Xn", pOptionalHeader->CheckSum);
printf("文件块对齐:t%08Xt", pOptionalHeader->FileAlignment);
printf("可选头部大小:t%04Xn", pFileHeader->SizeOfOptionalHeader);
printf("标 志 字:t%04Xtt", pOptionalHeader->Magic);
printf("RVA数及大小:t%08Xnn", pOptionalHeader->NumberOfRvaAndSizes);
printf("======================= 目 录 表 =======================n");
//获取目录表头指针
PIMAGE_DATA_DIRECTORY pDataDirectory = pOptionalHeader->DataDirectory;
printf("tt RAVtt 大小n");
for (DWORD i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++)
{
DirectoryString(i);
printf("%08Xt%08Xn",
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 %08Xn",
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("输出表:tt");
break;
case 1:printf("输入表:tt");
break;
case 2:printf("资源:tt");
break;
case 3:printf("异常:tt");
break;
case 4:printf("安全:tt");
break;
case 5:printf("重定位:tt");
break;
case 6:printf("调试:tt");
break;
case 7:printf("版权:tt");
break;
case 8:printf("全局指针:t");
break;
case 9:printf("TLS表:tt");
break;
case 10:printf("载入配置:t");
break;
case 11:printf("输入范围:t");
break;
case 12:printf("IAT:tt");
break;
case 13:printf("延迟输入:t");
break;
case 14:printf("COM:tt");
break;
case 15:printf("保留:tt");
break;
}
}
效果图:
另外附上我的代码。???? 获取某指定区段的信息:
HANDLE hFile = CreateFile(_T("C:\Windows\SysNative\ntoskrnl.exe"), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
cout << "CreateFile failed:" << GetLastError() << endl;
return false;
}
DWORD dwFileSize = GetFileSize(hFile, NULL);
CHAR* pFileBuf = new CHAR[dwFileSize];
DWORD ReadSize = 0;
if (!ReadFile(hFile, pFileBuf, dwFileSize, &ReadSize, NULL)) {
cout << "ReadFile failed:" << GetLastError() << endl;
return false;
}
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuf;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(pFileBuf + pDosHeader->e_lfanew);
PIMAGE_FILE_HEADER pFileHeader = &(pNtHeader->FileHeader);
PIMAGE_OPTIONAL_HEADER pOptionalHeader = &(pNtHeader->OptionalHeader);
PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(pNtHeader);
DWORD dwSectionNum = pFileHeader->NumberOfSections;
int page_vaddr = 0, page_roff = 0;
for (DWORD i = 0; i < dwSectionNum; i++, pSectionHeader++) {
string s_name;
for (DWORD j = 0; j < IMAGE_SIZEOF_SHORT_NAME; j++) {
if (pSectionHeader->Name[j]) {
s_name += pSectionHeader->Name[j];
}
}
if (s_name == "PAGE") {
page_vaddr = pSectionHeader->VirtualAddress;
page_roff = pSectionHeader->PointerToRawData;
break;
}
}
if (page_vaddr == 0 || page_roff == 0) { cout << "没有找到 PAGE 区段" << endl; return false; }
最后
以上就是舒心汉堡为你收集整理的C++ 获取 PE 文件的各种信息的全部内容,希望文章能够帮你解决C++ 获取 PE 文件的各种信息所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复