C++通过读取二进制流的方式来解析PE(静态文件读取法)

步骤解读

  1. 先选择文件
  2. 读取文件二进制流
  3. 从二进制流读取DOS头(DOS_HEADER),长度64字节
  4. 读取DOS壳(DOS_STUB),DOS头开始,长度至到dosHeader->e_lfanew偏移量
  5. 读取PE标识(Signature),e_lfanew偏移量开始,长度4字节
  6. 读取PE文件头(FILE_HEADER),PE标识开始,长度20字节
  7. 读取PE可选头(OPTIONAL_HEADER),PE文件头开始,长度peHeader->sizeOfOptionalHeader

直接上代码

代码中只解析了重要信息

#include<iostream>
#include<windows.h>using namespace std;BOOL selectFile(char* filePath) {OPENFILENAMEA ofn;char filename[MAX_PATH];ZeroMemory(&ofn, sizeof(ofn));ofn.lStructSize = sizeof(ofn);ofn.hwndOwner = NULL;ofn.lpstrFilter = "ALL Files\0*.*\0";ofn.lpstrFile = filename;ofn.nMaxFile = sizeof(filename);ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;ofn.lpstrFile[0] = '\0';if (GetOpenFileNameA(&ofn) == TRUE) {//MessageBoxA(NULL, filename, "提示", MB_OK);strcpy_s(filePath,MAX_PATH,filename);return TRUE;}return FALSE;
}int main() {char filePath[MAX_PATH];if (selectFile(filePath)) {//打开文件HANDLE hfile = CreateFileA(filePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);//根据文件句柄获取文件大小DWORD fileSize = GetFileSize(hfile,NULL);//文件流缓冲区char* fileBuffer = new char[fileSize];//实际接收字节数DWORD realRead = 0;//读取文件if (ReadFile(hfile, fileBuffer, fileSize, &realRead, NULL)) {WORD e_magic = *(WORD*)fileBuffer;	//MZ标识DWORD e_lfanew = *(DWORD*)(fileBuffer + 60);	//NT头偏移量printf("e_magic:%04X\n", e_magic);printf("e_lfanew:%08X\n", e_lfanew);printf("\n");DWORD Signatrue = *(DWORD*)(fileBuffer + e_lfanew);	//PE标识printf("Siganture:%08X\n", Signatrue);printf("\n");WORD Machine = *(WORD*)(fileBuffer + e_lfanew + 0x04);	//运行平台WORD NumberOfSections = *(WORD*)(fileBuffer + e_lfanew + 0x06);	//区段数量DWORD TimeDateStamp = *(DWORD*)(fileBuffer + e_lfanew + 0x08);	//区段数量WORD SizeOfOptionHeader = *(WORD*)(fileBuffer + e_lfanew + 0x14);	//可选头大小WORD Characteristics = *(WORD*)(fileBuffer + e_lfanew + 0x16);	//特征printf("Machine:%04X\n", Machine);printf("NumberOfSections:%04X\n", NumberOfSections);printf("TimeDateStamp:%04X\n", TimeDateStamp);printf("SizeOfOptionHeader:%04X\n", SizeOfOptionHeader);printf("Characteristics.EXECUTABLE_IMAGE:%d\n", Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE);	//是否是可执行文件printf("Characteristics.IMAGE_FILE_LINE_NUMS_STRIPPED:%d\n", Characteristics & IMAGE_FILE_LINE_NUMS_STRIPPED);	//文件中不包含行号信息。printf("Characteristics.IMAGE_FILE_LOCAL_SYMS_STRIPPED:%d\n", Characteristics & IMAGE_FILE_LOCAL_SYMS_STRIPPED);	//文件中不包含局部符号。printf("Characteristics.IMAGE_FILE_32BIT_MACHINE:%d\n", Characteristics & IMAGE_FILE_32BIT_MACHINE);	//目标平台是32位。printf("Characteristics.IMAGE_FILE_DEBUG_STRIPPED:%d\n", Characteristics & IMAGE_FILE_DEBUG_STRIPPED);	//调试信息被移除。printf("Characteristics.IMAGE_FILE_SYSTEM:%d\n", Characteristics & IMAGE_FILE_SYSTEM);	//文件是系统文件。printf("Characteristics.IMAGE_FILE_DLL:%d\n", Characteristics & IMAGE_FILE_DLL);	//文件是dll文件。printf("\n");WORD Magic = *(WORD*)(fileBuffer  + e_lfanew + 0x18);	//0x10B是32位,0x20B是64位DWORD AddressOfEntryPoint = *(DWORD*)(fileBuffer + e_lfanew + 0x28);	//OEP程序入口偏移量DWORD ImageBase = *(DWORD*)(fileBuffer + e_lfanew + 0x34);	//程序入口,固定值+偏移量DWORD SectionAlignment = *(DWORD*)(fileBuffer + e_lfanew + 0x38);	//内存对齐大小DWORD FileAlignment = *(DWORD*)(fileBuffer + e_lfanew + 0x3C);	//文件对齐大小DWORD SizeOfIamge = *(DWORD*)(fileBuffer + e_lfanew + 0x50);	//文件在内存中的大小,按SectionAlignment对齐后的大小DWORD SizeOfHeaders = *(DWORD*)(fileBuffer + e_lfanew + 0x54);	//DOS,NT,PE,可选PE+区段 各种头加一块,按照FileAlignment对齐后的大小DWORD NumberOfRvaAndSizes = *(DWORD*)(fileBuffer + e_lfanew + 0x74);	//数据目录表的个数printf("Magic:%04X\n", Magic);printf("AddressOfEntryPoint:%08X\n", AddressOfEntryPoint);printf("ImageBase:%08X\n", ImageBase);printf("SectionAlignment:%08X\n", SectionAlignment);printf("FileAlignment:%08X\n", FileAlignment);printf("SizeOfIamge:%08X\n", SizeOfIamge);printf("SizeOfHeaders:%08X\n", SizeOfHeaders);printf("NumberOfRvaAndSizes:%08X\n", NumberOfRvaAndSizes);CloseHandle(hfile);}else {int errcode = GetLastError();cout << "文件读取失败:"<< errcode << endl;}}else {cout << "文件选择失败。" << endl;}
}

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

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

相关文章

520节日特别篇:构建浪漫互动网站实战技巧

520节日特别篇&#xff1a;构建浪漫互动网站实战技巧 一、非零分积分资源概览二、基础概念与作用说明HTML5 Canvas & SVGCSS3 动画与过渡JavaScript 动态交互 三、实战代码示例&#xff1a;打造浪漫爱心雨HTML 结构CSS 样式JavaScript 逻辑 四、实际开发应用思路1. 个性化祝…

怎么画思维导图?方法介绍

怎么画思维导图&#xff1f;在数字化时代&#xff0c;思维导图已成为我们工作、学习和生活中的得力助手。它不仅能帮助我们更好地组织和表达思想&#xff0c;还能提升我们的思维能力和创造力。那么&#xff0c;哪些软件可以画思维导图呢&#xff1f;本文将为你揭秘几款功能强大…

Linux 应用入门(一)

1. 交叉编译 概念&#xff1a;在当前编译平台下&#xff0c;编译出来的程序能运行在体系结构不同的另一种目标平台上&#xff0c;但是编译平台本身却不能运行该程序。 为什么需要交叉编译&#xff1f; 速度&#xff1a;目标平台得运行速度比主机往往慢得多&#xff0c;因为许多…

Docker+nginx部署SpringBoot+vue前后端分离项目(保姆及入门指南)

前后分离项目部署 项目回顾工具上线准备1、win1.1、前端1.2、后端 2、linux环境2.1、安装docker2.2、安装docker compose2.3、编写Dockerfile文件2.4、编写docker-compose.yml文件2.5、修改application-pro.yml2.6、准备好nginx的挂载目录和配置2.7、部署后端服务 项目回顾 书…

数据挖掘实战-基于内容协同过滤算法的电影推荐系统

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

【从C++到Java一周速成】章节9:构造器

章节9&#xff1a;构造器 对于一个类来说&#xff0c;一般有三种常见的成员&#xff1a;属性、方法、构造器。 这三种成员都可以定义零个或多个。 构造方法也叫构造器&#xff0c;是一个创建对象时被自动调用的特殊方法&#xff0c;用于对象的初始化。 Java通过new关键字来调用…

OpenHarmony集成OCR三方库实现文字提取

1. 简介 Tesseract(Apache 2.0 License)是一个可以进行图像OCR识别的C库&#xff0c;可以跨平台运行 。本样例基于Tesseract库进行适配&#xff0c;使其可以运行在OpenAtom OpenHarmony&#xff08;以下简称“OpenHarmony”&#xff09;上&#xff0c;并新增N-API接口供上层应…

.Net Core学习笔记 框架特性(注入、配置)

注&#xff1a;直接学习的.Net Core 6&#xff0c;此版本有没有startup.cs相关的内容 项目Program.cs文件中 是定义项目加载 启动的地方 //通过builder对项目进行配置、服务的加载 var builder WebApplication.CreateBuilder(args); builder.Services.AddControllers();//将…

Ubuntu服务器运行Subspace节点和Farm

提供Subspace 节点部署&性能优化&机房托管&运维监控等服务。myto88 磁盘格式化 将插入的磁盘格式化。 sudo mkfs.ext4 -m 0 -T largefile4 /dev/sd*磁盘挂载 此处为语雀内容卡片&#xff0c;点击链接查看&#xff1a;https://www.yuque.com/u25096009/lvoxa…

企商在线荣登甲子光年“2024中国AI算力层创新企业”榜单

5月15日&#xff0c;「AI创生时代——2024甲子引力X科技产业新风向」大会在北京顺利举办&#xff0c;大会发布2024【星辰100】创新企业榜。企商在线凭借全栈式一体化AI算力能力&#xff0c;与超聚变、寒武纪等企业共同入选“2024中国AI算力层创新企业”榜单。 本次大会由中国科…

AJAX(JQuery版本)

目录 前言 一.load方法 1.1load()简介 1.2load()方法示例 1.3load()方法回调函数的参数 二.$.get()方法 2.1$.get()方法介绍 2.2详细说明 2.3一些例子 2.3.1请求test.php网页并传送两个参数 2.3.2显示test返回值 三.$.post()方法 3.1$.post()方法介绍 3.2详细说明 …

什么是云计算安全?如何保障云计算安全

云计算彻底改变了数据存储的世界&#xff0c;它使企业可以远程存储数据并随时随地从任何位置访问数据。存和取变得简单&#xff0c;也使得云上数据极易造成泄露或者被篡改&#xff0c;所以云计算安全就显得非常重要了。那么什么是云计算安全&#xff1f; 其实&#xff0c;云计…

WPS PPT学习笔记 1 排版4原则等基本技巧整理

排版原则 PPT的排版需要满足4原则&#xff1a;密性、对齐、重复和对比4个基本原则。 亲密性 彼此相关的元素应该靠近&#xff0c;成为一个视觉单位&#xff0c;减少混乱&#xff0c;形成清晰的结构。 两端对齐&#xff0c;1.5倍行距 在本例中&#xff0c;19年放左边&#x…

是谁的项目还在烂大街?一个基于 SpringBoot 的高性能短链系统

看了几百份简历&#xff0c;真的超过 90% 的小伙伴的项目是商城、RPC、秒杀、论坛、外卖、点评等等烂大街的项目&#xff0c;人人都知道这些项目烂大街了&#xff0c;但大部分同学还是得硬着头皮做&#xff0c;没办法&#xff0c;网络上能找到的、教程比较完善的就这些项目了&a…

基于机器学习预测未来的二氧化碳排放量(随机森林和XGBoost)

基于机器学习预测未来的二氧化碳排放量&#xff08;随机森林和XGBoost&#xff09; 简介&#xff1a; CO2排放是当今全球关注的环境问题之一。本文将使用Python对OWID提供的CO2排放数据集进行分析&#xff0c;并尝试构建机器学习模型来预测未来的CO2排放趋势。我们将探索数据…

kafka Kerberos集群环境部署验证

背景 公司需要对kafka环境进行安全验证,目前考虑到的方案有Kerberos和SSL和SASL_SSL,最终考虑到安全和功能的丰富度,我们最终选择了SASL_SSL方案。处于知识积累的角度,记录一下kafka keberos安装部署的步骤。 机器规划 目前测试环境公搭建了三台kafka主机服务,现在将详细…

ViLT学习

多模态里程碑式的文章&#xff0c;总结了四种多模态方法&#xff0c;根据文字和图像特征特征抽取方式不通。 文章的贡献主要是速度提高了&#xff0c;使用了数据增强&#xff0c;文本的mask 学习自b站朱老师的论文讲解

电赛控制类PID算法实现

一、什么是PID PID&#xff08;Proportional-Integral-Derivative&#xff09;是一种经典的控制算法&#xff0c;广泛应用在自动化控制系统中。它是通过对被控对象的测量值和设定值进行比较&#xff0c;并根据误差的大小来调整输出信号&#xff0c;实现对被控对象的稳定控制。 …

【C++】map和set的封装

目录 前言一、红黑树的设计1.1 红黑树存储节点的设计1.2 红黑树的迭代器1.3 map的设计1.4 set的设计1.5关于map与set的const_iterator设计 前言 我们知道map和set的底层都是用红黑树实现的&#xff0c;但是set和map的结构不一样&#xff0c;set只有一个参数K&#xff0c;而map…