提取 PE 文件的各种信息

  

      前段时间项目需要实现对 Windows PE 文件版本信息的提取,如文件说明、文件版本、产品名称、版权、原始文件名等信息。获取这些信息在 Windows 下当然有一系列的 API 函数供调用,简单方便。

        我们先看一下PE文件结构,PE文件由DOS首部,PE文件头,块表,块和调试信息组成,有关PE文件的数据结构信息在winnt.h中定义。

文章不过多赘述,直接上代码简单明了。

实现代码:

#include "stdafx.h"
#include <Windows.h>extern void DirectoryString(DWORD dwIndex);int _tmain(int argc, _TCHAR* argv[])
{//获取文件句柄HANDLE hFile = CreateFile(_T("D:\\Wmplayer.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){printf("非 PE 文件\n");system("pause");return 0;}PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(pFileBuf + pDosHeader->e_lfanew);if (pNtHeader->Signature != IMAGE_NT_SIGNATURE){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("start https://www.chwm.vip/?PEinfo");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;}
}

获取某指定区段的信息实现代码:

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; }

效果演示:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/230490.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode 25. K 个一组翻转链表

K 个一组翻转链表 给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。 k 是一个正整数&#xff0c;它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍&#xff0c;那么请将最后剩余的节点保持原有顺序。 你不能只是单纯的改…

不同语言告别2023,迎接2024

一、序言 1.一名合格的程序员&#xff0c;始于Hello World&#xff0c;终于Hello World&#xff0c;用不同语言表达2023最后一天。 2.在这一年里&#xff0c;博主新接触了VUE、Python、人工智能、JAVA的框架SprinBoot、微服务等&#xff0c;然后一路来感谢大家的支持&#xf…

nifi详细介绍--一款开箱即用、功能强大可靠,可用于处理和分发数据的大数据组件

目录 目录 一、引言 二、NiFi 的历史背景介绍 三、NiFi 是什么&#xff1f; 核心特性 应用领域 四、NIFI 入门 五 、NiFi 工作流程 六、实际应用场景 七、优势总结 一、引言 NiFi&#xff08;Apache NiFi&#xff09;&#xff0c;全名为“Niagara Files”&#xff0…

Unity DOTS中的baking(二)Baker的触发

Unity DOTS中的baking&#xff08;二&#xff09;Baker的触发 我们知道&#xff0c;当传入Baker的authoring component的值发生变化时&#xff0c;就会触发baking。不过在有些情况下&#xff0c;component所引用的对象没有变化&#xff0c;而是对象自身内部的一些属性发生了变化…

编写.NET的Dockerfile文件构建镜像

创建一个WebApi项目&#xff0c;并且创建一个Dockerfile空文件&#xff0c;添加以下代码&#xff0c;7.0代表的你项目使用的SDK的版本&#xff0c;构建的时候也需要选择好指定的镜像tag FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base WORKDIR /app EXPOSE 80 EXPOSE 443F…

深度学习基础知识神经网络

神经网络 1. 感知机 感知机&#xff08;Perceptron&#xff09;是 Frank Rosenblatt 在1957年提出的概念&#xff0c;其结构与MP模型类似&#xff0c;一般被视为最简单的人工神经网络&#xff0c;也作为二元线性分类器被广泛使用。通常情况下指单层的人工神经网络&#xff0c…

超实用的小红书达人投放策略分析,纯干货

为什么我投放了小红书达人却没有什么效果&#xff1f; 品牌到底应该怎么投放小红书达人&#xff1f; 品牌小红书达人投放怎么去把控和规划&#xff1f; 小红书达人作为品牌方和用户之间的桥梁&#xff0c;直接影响消费决策。达人粉丝数量大&#xff0c;粘性高&#xff0c;很…

一加 Buds 3正式发布:普及旗舰音质 一加用户首选

1月4日&#xff0c;一加新品发布会正式推出旗下新款耳机一加 Buds 3。延续一加经典美学&#xff0c;秉承音质完美主义追求&#xff0c;一加 Buds 3全面普及一加旗舰耳机体验&#xff0c;其搭载旗舰同款“超清晰同轴双单元”&#xff0c;配备49dB 4000Hz超宽频主动降噪&#xff…

Oracle笔记-查看表已使用空间最大空间

目前以Oracle18c为例&#xff0c;主要是查这个表USER_SEGMENTS。 在 Oracle 18c 数据库中&#xff0c;USER_SEGMENTS 是一个系统表&#xff0c;用于存储当前用户&#xff08;当前会话&#xff09;拥有的所有段的信息。段是 Oracle 中分配存储空间的逻辑单位&#xff0c;用于存…

linux centos 添加临时ip

### 1.添加ip ip addr add IP/mask dev 网络设备 例&#xff1a;ip addr add 172.104.210.247/24 dev ens5f1 ### 2.启动网卡 ip link set up 网络设备 例&#xff1a;ip link set up ens3f0 ### 3.设置默认路由 ip route add default via GATEWAY 例&#xff1a;ip route add …

vu3-14

第一个需求是在用户登录成功之后&#xff0c;在主页显示用户的真实姓名和性别&#xff0c;这些信息要调用后端API获取数据库里面的信息&#xff0c;第二个需求是点击菜单1&#xff0c;在表单中修改用户信息之后&#xff0c;更新到后端数据库&#xff0c;然后在主页同步更新用户…

增删改查语句实现了解不同的函数与特殊字符unionunion all区别

一、crud&#xff08;增删改查&#xff09; 1.1、查询 概念&#xff1a; 查询数据是指从数据库中根据需求&#xff0c;使用不同的查询方式来获取不同的数据&#xff0c;是使用频率最高、最重要的操作 注&#xff1a;在MySQL中&#xff0c;当执行一条SQL语句后&#xff0c;系…

Docker中的核心概念

1.镜像 Image 一个镜像就代表一个软件。mysql镜像、redis镜像、mq镜像 2.容器 Container 一个镜像运行一次就会生成一个容器&#xff0c;容器就是一个运行的软件服务。 3.远程仓库 Repository 远程仓库用来存储所有软件的镜像&#xff0c;Docker Hub 4.本地仓库 用来存储…

Mybatis源码基本原理--XML版

文章目录 mybatis是什么架构设计首先建立起Mapper的代理工程和代理映射器的注册和使用XML文件解析数据源解析、创建和使用SQL执行器&#xff08;Executor&#xff09;的定义与实现SQL解析参数处理器&#xff1a;策略模式实现封装处理结果注解 mybatis 是什么 MyBatis 是一款优…

acwing 1358. 约数个数和(莫比乌斯函数)

设 d(x)&#xfffd;(&#xfffd;) 为 x&#xfffd; 的约数个数&#xff0c;给定 N,M&#xfffd;,&#xfffd;&#xff0c;求 ∑i1N∑j1Md(ij)∑&#xfffd;1&#xfffd;∑&#xfffd;1&#xfffd;&#xfffd;(&#xfffd;&#xfffd;) 输入格式 输入多组测试数据…

Java 读取超大excel文件

注意&#xff1a;此参考解决方案只是针对xlsx格式的excel文件&#xff01; Maven <dependency><groupId>com.monitorjbl</groupId><artifactId>xlsx-streamer</artifactId><version>2.2.0</version> </dependency>读取方式1…

SpringBoot的测试

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开心好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…

基于Segformer实现PCB缺陷检测(步骤 + 代码)

导 读 本文主要介绍基于Segformer实现PCB缺陷检测 &#xff0c;并给出步骤和代码。 背景介绍 PCB缺陷检测是电子制造的一个重要方面。利用Segformer等先进模型不仅可以提高准确性&#xff0c;还可以大大减少检测时间。传统方法涉及手动检查&#xff0c;无法扩展且容易出错…

目标检测-Two Stage-Mask RCNN

文章目录 前言一、Mask RCNN的网络结构和流程二、Mask RCNN的创新点总结 前言 前文目标检测-Two Stage-Faster RCNN提到了Faster RCNN主要缺点是&#xff1a; ROI Pooling有两次量化操作&#xff0c;会引入误差影响精度 Mask RCNN针对这一缺点做了改进&#xff0c;此外Mask …

C/C++动态内存分配 malloc、new、vector(简单讲述)

路虽远&#xff0c;行则将至 事虽难&#xff0c;做则必成 今天来主要讲C中动态内存分配 其中会穿插一些C的内容以及两者的比较 如果对C语言中的动态内存分配还不够理解的同学 可以看看我之前的博客:C语言动态分配 在讲解C的动态内存分配之前 我们先讲一下C内存模型 &#xff1…