【滴水三期】32/64位——PE文件节表打印与解析

news2024/9/21 23:43:52

【作业内容】

1、手动查,画个PE文件图。

2、编写程序打印节表中的信息。

3、根据节表中的信息,到文件中找到所有的节,观察节的开始位置与大小是否与节表中的描述一致

【PE file_buffer文件图】

【IMAGE_SECTION_HEADER解析】

<winNT.h> 头文件定义如下

typedef struct _IMAGE_SECTION_HEADER {
    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME]; //保存节的名字的数组。
    union {
            DWORD   PhysicalAddress;	//该节在文件中的实际大小
            DWORD   VirtualSize;		//该节在内存中占用的大小,节在内存中的大小会因为对齐或填充而增加
    } Misc;
    DWORD   VirtualAddress;		         //该节在进程的虚拟空间中的起始地址,内存偏移。加载器使用这个地址将节的内容映射到内存中相应的虚拟地址上。
    DWORD   SizeOfRawData;		        //该节在PE文件中对齐后的原始数据大小,由于 SizeOfRawData 字段是四舍五入的,而 VirtualSize 字段不是四舍五入的,因此 SizeOfRawData 字段也可能大于 VirtualSize。
    DWORD   PointerToRawData;		    //该节在PE文件的实际位置,即相对于文件开始的偏移量。加载器会根据这个偏移量从文件中读取节的内容,并将其加载到内存中。
    DWORD   PointerToRelocations;		//该节的重定位表在文件中的起始位置,如果节中有重定位项,该字段指出重定位表的文件偏移量。数据节可能需要重定位以修正基于位置的引用;没有重定位的映像,该值设为零。(在obj文件中使用,对exe无意义)。
    DWORD   PointerToLinenumbers;		//如果节包含源代码行号信息;;已被弃用,改值应为0
    WORD    NumberOfRelocations;		//该节有多少重定位条目;对于可执行文件,该值设为零。(在obj文件中使用,对exe无意义)。
    WORD    NumberOfLinenumbers;		//该行有多少行号条目;已被弃用,该值应为0
    DWORD   Characteristics;			//指定节的属性标志
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
【SECTION_CHARACTERISTICS】节表中Characteristics字段解析

<winNT.h> 头文件定义如下

1. **`IMAGE_SCN_TYPE_NO_PAD`** (`0x00000008`):指示该节不应该在文件中进行填充。 
2. **`IMAGE_SCN_CNT_CODE`** (`0x00000020`):表示该节包含可执行代码。 
3. **`IMAGE_SCN_CNT_INITIALIZED_DATA`** (`0x00000040`):表示该节包含已初始化的数据。 
4. **`IMAGE_SCN_CNT_UNINITIALIZED_DATA`** (`0x00000080`):表示该节包含未初始化的数据(通常是`.bss`节)。 

5. **`IMAGE_SCN_LNK_OTHER`** (`0x00000100`):保留,用于非标准链接器特定的节。 
6. **`IMAGE_SCN_LNK_INFO`** (`0x00000200`):表示该节包含链接器信息,如重定位表和行号表。
7. **`IMAGE_SCN_LNK_REMOVE`** (`0x00000800`):指示链接器应该从最终输出中删除此节。 
8. **`IMAGE_SCN_LNK_COMDAT`** (`0x00001000`):表示该节包含COMDAT数据,即在链接时可能与其他节合并的数据。
 
9. **`IMAGE_SCN_NO_DEFER_SPEC_EXC`** (`0x00004000`):表示该节中的代码不应延迟特定异常处理。 

10. **`IMAGE_SCN_GPREL`** (`0x00008000`):表示该节中的数据相对于全局页基址(即PE文件的基地址)是相对的。 

11. **`IMAGE_SCN_MEM_PURGEABLE`** (`0x00020000`):表示该节在内存中是可丢弃的,即可以由系统在需要时清除。 
12. **`IMAGE_SCN_MEM_16BIT`** (`0x00020000`):表示该节包含16位代码或数据。 
13. **`IMAGE_SCN_MEM_LOCKED`** (`0x00040000`):表示该节在内存中是锁定的,即不能被页面调度器交换出去。 
14. **`IMAGE_SCN_MEM_PRELOAD`** (`0x00080000`):表示该节应该在进程启动时预加载到内存中。 
15. **`IMAGE_SCN_ALIGN_1BYTES`** (`0x00100000`) 至 **`IMAGE_SCN_ALIGN_8192BYTES`** (`0x04000000`):这一系列标志位用于指定节在内存中的对齐方式。 

16. **`IMAGE_SCN_LNK_NRELOC_OVFL`** (`0x01000000`):表示该节的重定位溢出,即重定位表中包含了太多重定位条目。 

17. **`IMAGE_SCN_MEM_DISCARDABLE`** (`0x02000000`):表示该节中的数据在内存中是可以被丢弃的,即可以由系统在需要时清除。 
18. **`IMAGE_SCN_MEM_NOT_CACHED`** (`0x04000000`):表示该节在内存中不应该被缓存。 
19. **`IMAGE_SCN_MEM_NOT_PAGED`** (`0x08000000`):表示该节在内存中不应该被分页。
20. **`IMAGE_SCN_MEM_SHARED`** (`0x10000000`):表示该节在内存中是可以被共享的。 
21. **`IMAGE_SCN_MEM_EXECUTE`** (`0x20000000`):表示该节在内存中是可以执行的。 
22. **`IMAGE_SCN_MEM_READ`** (`0x40000000`):表示该节在内存中是可以读取的。 
23. **`IMAGE_SCN_MEM_WRITE`** (`0x80000000`):表示该节在内存中是可以写的。 


#define IMAGE_SCN_MEM_FARDATA (0x00008000):用于指示一个节是远数据(far data)节,遗留产物,现代程序用不上。
#define IMAGE_SCN_ALIGN_MASK(0x00F00000):定义了一个掩码,用于从`Characteristics`字段中提取对齐属性.它被设计为与`Characteristics`字段进行位与操作(&),以提取出对齐属性。这个掩码的二进制表示中,只有对齐属性位被设置为1,其他位被设置为0。

【PE文件节表打印】

#include <windows.h>
#include <winnt.h>
#include <stdio.h>


const char* filename= "C:\\Users\\Administrator\\Desktop\\SunloginClient\\远控项目(1)\\service\\Release\\client.exe";
char* file_buffer;

//读文件,返回存储文件内容的缓冲区
int Read_File(){
	FILE* pfile = NULL;
	if ((fopen_s(&pfile, filename, "rb"))) {
		printf("file open error with %d .\n",errno);
		fclose(pfile);
		return 0;
	}

	//判断文件大小
	fseek(pfile,0,SEEK_END);
	int file_size=ftell(pfile);
	rewind(pfile);
	file_buffer = (char*)calloc((file_size+1), 1);
	
	//读取文件
	if (!((fread_s(file_buffer, file_size, 1, file_size, pfile)) == file_size))
	{
		printf("fread faild with %d.\n",errno);
		file_buffer = NULL;
		free(file_buffer);
		fclose(pfile);
		return 0;
	}

	return 0;
}
int Section_Operator() {
	/*
	1、判断DOS 头前word个字节是否为5A4D
	2、读取e_lfanew
	3、跳到NT头位置,
	*/
	

	PIMAGE_DOS_HEADER dos_header;
	dos_header = (PIMAGE_DOS_HEADER)file_buffer;
	if (!(dos_header->e_magic== IMAGE_DOS_SIGNATURE))
	{
		printf("Not PE file!\n"); 
		return 0;
	}
	DWORD Pe_sig = dos_header->e_lfanew;
	//file_temp_buffer==MACHINE
	char* file_temp_buffer= (char*)calloc(sizeof(file_buffer), 1);
	

	//1、获得 WORD NumberOfSections 判断节的数量
	//2、获得 WORD SizeofOptionsHeader  此头没有本节课作业相关的数据,先不读取,直接跳过此头。

	//有个DOWRD signature字节,直接跳过,到FILE_HEADER 部分
	file_temp_buffer = file_buffer + Pe_sig+4 ; 

	PIMAGE_FILE_HEADER file_header;
	file_header = (PIMAGE_FILE_HEADER)file_temp_buffer;

	//1、获得 WORD NumberOfSections 判断节的数量
	int section_number=file_header->NumberOfSections;

	//2、获得 WORD SizeofOptionsHeader  此头没有本节课作业相关的数据,先不读取,直接跳过此头。
	int option_header_size = file_header->SizeOfOptionalHeader;

	file_temp_buffer = file_temp_buffer + option_header_size+sizeof(IMAGE_FILE_HEADER);
	

	PIMAGE_NT_HEADERS;
	PIMAGE_SECTION_HEADER section_header;
	section_header = (PIMAGE_SECTION_HEADER)file_temp_buffer;
	while (section_number--)
	{

		printf("====================== %s节表信息 =======================\n", section_header->Name);
		printf("节在内存中的大小:%08X\n",section_header->Misc.VirtualSize);
		printf("节的内存偏移:%08X\n",section_header->VirtualAddress);
		printf("节在文件中对齐后的大小:%08X\n",section_header->SizeOfRawData);
		printf("节在PE文件的偏移:%08X\n",section_header->PointerToRawData);
		printf("该值应为0:%08X\n",section_header->PointerToRelocations);
		printf("该值应为0:%08X\n",section_header->PointerToLinenumbers);
		printf("该值应为0:%08X\n",section_header->NumberOfRelocations);
		printf("该值应为0:%04X\n",section_header->NumberOfLinenumbers);
		printf("节的权限:%08X\n",section_header->Characteristics);
		//section_header 是PIMAGE_SECTION_HEADER类型,(section_header++) 等于 指针向下顺移一个节的位置。
		//printf("====================== %s节表信息 =======================\n",section_header->Name);
		section_header++;
	}

	file_buffer = NULL;
	file_temp_buffer = NULL;
	free(file_buffer);
	free(file_temp_buffer);
}




int main() {
	Read_File();
	Section_Operator();
	return 0;
}

注:如有不正确或可完善的地方请私聊,直接评论也可以。本人在编辑的时候可能会受到自身逻辑限制,无法想到一些重要的情况,欢迎各位一起学习的小伙伴多多批评指正。

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

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

相关文章

web浏览器播放rtsp视频流,海康监控API

概述 这里记录一下如何让前端播放rtsp协议的视频流 ​ 项目中调用海康API&#xff0c;生成的视频流(hls、ws、rtmp等)通过PotPlayer播放器都无法播放&#xff0c;说明视频流有问题&#xff0c;唯独rtsp视频流可以播放。 但是浏览器本身是无法播放rtsp视频的&#xff0c;即使…

Qt3D给圆环等立体图形添加纹理图片

添加纹理图片&#xff0c;首先需要自己找一个纹理图&#xff0c;当然了&#xff0c;随便什么图片都行。 创建3D图形的主要步骤查看另一篇文章。 这里主要代码如下&#xff1a; 使用QTextureLoader加载图片&#xff0c;图片路径需为qrc:/的路径。 auto *planeTransform1 ne…

PyMongo

什么是PyMongo PyMongo 是一个 Python 库&#xff0c;用于与 MongoDB 数据库进行交互。MongoDB 是一个基于文档的 NoSQL 数据库&#xff0c;提供高性能、可扩展性和灵活的架构。PyMongo 提供了一套工具&#xff0c;使得在 Python 程序中操作 MongoDB 变得简单和高效。 安装PyMo…

【C++程序设计】——利用数组处理批量数据(二)

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-削好皮的Pineapple! &#x1f468;‍&#x1f4bb; hello 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 削好皮的Pineapple! 原创 &#x1f468;‍&#x1f4…

17085 工作分配问题(优先做)

这个问题可以通过回溯法来解决。我们可以遍历所有可能的工作分配方案&#xff0c;然后找出总劳务费用最小的方案。 以下是C代码实现&#xff1a; #include <iostream> #include <vector> #include <algorithm> using namespace std;const int INF 1e9; co…

羌活基因组--文献精读-36

The chromosome-scale assembly of the Notopterygium incisum genome provides insight into the structural diversity of coumarins 羌活&#xff08;Notopterygium incisum&#xff09;基因组的染色体级别组装为香豆素的结构多样性提供了新的见解 摘要 香豆素是由苯丙素途…

内网安全:多种横向移动方式

1.MMC20.Application远程执行命令 2.ShellWindows远程执行命令 3.ShellBrowserWindow远程执行命令 4.WinRM远程执行命令横向移动 5.使用系统漏洞ms17010横向移动 DCOM&#xff1a; DCOM&#xff08;分布式组件对象模型&#xff09;是微软的一系列概念和程序接口。它支持不同…

Java中操作文件

认识⽂件 我们先来认识狭义上的⽂件(file)。针对硬盘这种持久化存储的I/O设备&#xff0c;当我们想要进⾏数据保存时&#xff0c; 往往不是保存成⼀个整体&#xff0c;⽽是独⽴成⼀个个的单位进⾏保存&#xff0c;这个独⽴的单位就被抽象成⽂件的概 念&#xff0c;就类似办公桌…

【Linux】深入理解线程

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和算法 ✈️专栏&#xff1a;Linux &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵&#xff0c;希望大佬指点一二 如果文章对…

基于ssm的图书管理系统/图书借阅管理系统

获取源码联系方式请查看文章结尾&#x1f345; 摘 要 网络技术的快速发展给各行各业带来了很大的突破&#xff0c;也给各行各业提供了一种新的管理模块&#xff0c;对于图书管理将是又一个传统管理到智能化信息管理的改革&#xff0c;对于传统的图书借阅的管理&#xff0c;所包…

最长上升子序列LIS(一般+优化)

1. 题目 题目链接&#xff1a; B3637 最长上升子序列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 输入样例&#xff1a; 6 1 2 4 1 3 4 输出样例&#xff1a; 4 说明/提示&#xff1a; 分别取出 1、2、3、4 即可。 2. 具体实现 2.1 一般做法 dp[i]表示第i个位置的…

医院管理系统读取身份证源码- CyberWinApp-SAAS 本地化及未来之窗行业应用跨平台架构

一、身份证读取 提高效率&#xff1a;快速获取身份信息&#xff0c;避免手动输入的繁琐和耗时&#xff0c;极大地提升业务办理速度。 准确性高&#xff1a;减少人工输入错误&#xff0c;确保身份信息的精准无误。 便捷操作&#xff1a;简化流程&#xff0c;使工作人员操作更轻…

51单片机个人学习笔记14(直流电机驱动及PWM)

前言 本篇文章属于STC89C52单片机&#xff08;以下简称单片机&#xff09;的学习笔记&#xff0c;来源于B站教学视频。下面是这位up主的视频链接。本文为个人学习笔记&#xff0c;只能做参考&#xff0c;细节方面建议观看视频&#xff0c;肯定受益匪浅。 [1-1] 课程简介_哔哩…

Elemnt UI筛选时间功能

html&#xff1a; <el-form-item label"数据筛选: " ><el-date-picker v-model"choose_time" type"datetimerange" size"small" change"chooseTime" style"width:100%;" value-format"yyyy-MM-dd …

逻辑推理之lora微调

逻辑推理微调 比赛介绍准备内容lora微调lora微调介绍lora优势代码内容 start_vllm相关介绍调用 运行主函数提交结果总结相应连接 比赛介绍 本比赛旨在测试参与者的逻辑推理和问题解决能力。参与者将面对一系列复杂的逻辑谜题&#xff0c;涵盖多个领域的推理挑战。 比赛的连接:…

内网穿透--ICMP隧道转发实验

实验背景 通过公司带有防火墙功能的路由器接入互联网&#xff0c;然后由于私网IP的缘故&#xff0c;公网无法直接访问内部web服务器主机。通过内网其它主机做代理&#xff0c;穿透访问内网web服务器主机边界路由器或防火墙做静态NAT映射访问内网服务器inux主机&#xff0c;且策…

C++分析AVL树

目录 AVL树介绍 AVL树平衡因子更新分析 AVL树插入时旋转与平衡因子更新 左单旋 右单旋 左右单旋 右左单旋 AVL旋转可行性 AVL树节点删除&#xff08;待补充&#xff09; AVL树分析 AVL树介绍 二叉搜索树在某些极端情况下可能会退化&#xff0c;为了解决这个问题&…

Redis学习[6] ——Redis缓存设计

八、Redis缓存设计 8.1 为什么Redis用作缓存&#xff1f; 一般来说&#xff0c;数据库的数据都是落在磁盘上的&#xff0c;会导致读写速度很慢。如果用户的请求量非常大&#xff0c;数据库很容易崩溃。由于Redis的数据保存在内存中&#xff0c;读写速度很快&#xff0c;所以R…

SQL注入 报错注入+附加拓展知识,一篇文章带你轻松入门

第5关--------------------------------------------> 前端直接不会显示账号密码的打印&#xff1b;但是在接收前端的数据的那部分后端那里&#xff0c;会看前端传递过来的值是否正确&#xff0c;如果不正确&#xff0c;后端接收值那里就会当MySQL语句执行错误&#xff0c;…

RK3568笔记五十一:W25Q64测试(spi 标准接口 )

若该文为原创文章&#xff0c;转载请注明原文出处。 前面有测试过W25Q64&#xff0c;但那是自己编写的驱动&#xff0c;现在使用内核自带的驱动&#xff0c;只需要通过SPI标准接口&#xff0c;编写应用程序即可以读写W25Q64. 一、硬件原理图 SPI 引脚 功能 MOSI GPIO3_C1 …