PE文件剖析实验
成绩 |
目录
《实验1:PE文件剖析实验》报告 1
1. 实验目的 3
2. 实验过程 3
2.1实验准备 3
2.2实验内容 3
3. 实现结果 17
4. 感想收获 20
5. 参考资料 21
实验目的
理解PE文件的具体格式,为后续计算机病毒学习打下基础
实验过程
2.1实验准备
工具StudyPE+ x64、WinHex
2.2实验内容
1.选择图中EXE文件,对其展开分析
2.把图中EXE文件拖入Win Hex中
3.观察信息并结合所学知识,找出文件的PE标志,入口地址、基址,节表个数及列出节表、输出表、输入表等信息。
上图是一张PE结构图
- DOS部分结构代码,其存放在CPP的winnt.h头文件
DOS MZ头文件是一个名为IMAGE_DOS_HEADER的64字节的结构体
DOS Sub DOS块是填充信息大小不确定,内容不重要
- PE文件头
已知DOS最后有LONG类型的后四位为PE头文件的指针(偏移地址)由于内存高位开始 00 01 00 00在内存中为 00 00 01 00;在此处找到PE头标识。
基地址函数 ImageBASE 获取可以用HMODULE GetModuleHandle(LPCTSR IpModuleName)传入的为指针类型
PE标志,4D5A对应的MZ为DOS可执行文件标记,5045对应的PE为PE头文件的标志。
至此也确定了DOS块大小。
PE文件头部分实际上是一个实际上是一个IMAGE_NT_HEADERS结构体,包含4个字节的Signature. 20字节的 IMAGE_FILE_HEADER结构体, 224字节的IMAGE_OPTIONAL_HEADER32结构体
4个字节的Signature. 20字节的 IMAGE_FILE_HEADER结构体, 224字节的IMAGE_OPTIONAL_HEADER32结构体三部分
- Signature
- IMAGE_FILE_HEADER结构体
(1)Machine:可执行文件的目标CPU类型。
(2)NumberOfSection: 区块的数目。(注:区块表是紧跟在 IMAGE_NT_HEADERS 后边的)
- TimeDataStamp: 表明文件是何时被创建的。这个值是自1970年1月1日以来用格林威治时间(GMT)计算的秒数,这个值是比文件系统(FILESYSTEM)的日期时间更加精确的指示器。
(4)PointerToSymbolTable: COFF 符号表的文件偏移位置,现在基本没用了。
(5)NumberOfSymbols: 如果有COFF 符号表,它代表其中的符号数目,COFF符号是一个大小固定的结构,如果想找到COFF 符号表的结束位置,则需要这个变量。
(6)SizeOfOptionalHeader: 紧跟着IMAGE_FILE_HEADER 后边的数据结构(IMAGE_OPTIONAL_HEADER)的大小。(32位PE文件,值是00E0h;64位PE32+文件,值是00F0h )。
(7)Characteristics: 文件属性,有选择的通过几个值可以运算得到。( 这些标志的有效值是定义于 winnt.h 内的 IMAGE_FILE_** 的值,具体含义见下表。普通的EXE文件这个字段的值一般是 0100h,DLL文件这个字段的值一般是 210Eh。)多种属性可以通过 “或运算” 使得同时拥有。
(1)Machine:14ch为intal i386。
(2)NumberOfSection: 区块的数目为8
(3)TimeDataStamp: 表明文件是何时被创建的。这个值是自1970年1月1日以来用格林威治时间(GMT)计算的秒数
(4)SizeOfOptionalHeader: 32位PE文件,值是00E0h;
(5)Characteristics: 文件属性,有选择的通过几个值可以运算得到。
- IMAGE_OPTIONAL_HEADER32
+18h WORD Magic; // 标志字, ROM 映像(0107h),普通可执行文件(010Bh)
+1Ah BYTE MajorLinkerVersion; // 链接程序的主版本号
+1Bh BYTE MinorLinkerVersion; // 链接程序的次版本号
+1Ch DWORD SizeOfCode; // 所有含代码的节的总大小
+20h DWORD SizeOfInitializedData; // 所有含已初始化数据的节的总大小
+24h DWORD SizeOfUninitializedData; // 所有含未初始化数据的节的大小
+28h DWORD AddressOfEntryPoint; // 程序执行入口RVA
+2Ch DWORD BaseOfCode; // 代码的区块的起始RVA
+30h DWORD BaseOfData; // 数据的区块的起始RVA
// NT additional fields. 以下是属于NT结构增加的领域。
+34h DWORD ImageBase; // 程序的首选装载地址
+38h DWORD SectionAlignment; // 内存中的区块的对齐大小
+3Ch DWORD FileAlignment; // 文件中的区块的对齐大小
+40h WORD MajorOperatingSystemVersion; // 要求操作系统最低版本号的主版本号
+42h WORD MinorOperatingSystemVersion; // 要求操作系统最低版本号的副版本号
+44h WORD MajorImageVersion; // 可运行于操作系统的主版本号
+46h WORD MinorImageVersion; // 可运行于操作系统的次版本号
+48h WORD MajorSubsystemVersion; // 要求最低子系统版本的主版本号
+4Ah WORD MinorSubsystemVersion; // 要求最低子系统版本的次版本号
+4Ch DWORD Win32VersionValue; // 莫须有字段,不被病毒利用的话一般为0
+50h DWORD SizeOfImage; // 映像装入内存后的总尺寸
+54h DWORD SizeOfHeaders; // 所有头 + 区块表的尺寸大小
+58h DWORD CheckSum; // 映像的校检和
+5Ch WORD Subsystem; // 可执行文件期望的子系统
+5Eh WORD DllCharacteristics; // DllMain( )函数何时被调用,默认为 0
+60h DWORD SizeOfStackReserve; // 初始化时的栈大小
+64h DWORD SizeOfStackCommit; // 初始化时实际提交的栈大小
+68h DWORD SizeOfHeapReserve; // 初始化时保留的堆大小
+6Ch DWORD SizeOfHeapCommit; // 初始化时实际提交的堆大小
+70h DWORD LoaderFlags; // 与调试有关,默认为 0
+74h DWORD NumberOfRvaAndSizes; // 下边数据目录的项数,这个字段自Windows NT 发布以来 // 一直是16
+78h IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
// 数据目录表
IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
重点分析,相对PE地址偏离
+18h WORD Magic; 普通可执行文件(010Bh)
+1Ch DWORD SizeOfCode; // 所有含代码的节的总大小5800
+28h DWORD AddressOfEntryPoint; // 程序执行入口RVA00006664
+2Ch DWORD BaseOfCode; // 代码的区块的起始RVA00001000
+30h DWORD BaseOfData; // 数据的区块的起始RVA0000700
+34h DWORD ImageBase; // 程序的首选装载地址默认基址00400000
+38h DWORD SectionAlignment; // 内存中的区块的对齐大小1000h=4kb
+3Ch DWORD FileAlignment; // 文件中的区块的对齐大小200h
+50h DWORD SizeOfImage; // 映像装入内存后的总尺寸0000E000
+54h DWORD SizeOfHeaders; // 所有头 + 区块表的尺寸大小00000400
+58h DWORD CheckSum; // 映像的校检和000109C0
- 节表和数据块
.text段。一般是代码段。
.data段。一般是数据段。
.bss段。未初始化数据段。比如static变量,有时在函数内才初始化。
.rdata段。只读数据段。比如字符串。
.idata和.edata段。数据和.数据段。导入表、导出表信息。
.rsrc段。资源段。
.reloc段。重定位信息段。
实现结果
把图中EXE文件拖入StudyPE+ x64中
对照之前所得结论,各个部分一致。
感想收获
在这次实验中,我主要通过观察和分析Windows可执行文件(PE文件)来理解其结构和关键数据项。这包括找到PE标志、入口地址、基址、节表个数,并列出节表、输出表和输入表等信息。以下是我的实验心得和学习总结。
- PE标志的定位
体会:了解PE文件的结构和基本知识是分析文件的基础。PE标志是识别文件类型的关键,只有确认了文件类型才能进行后续的详细分析。黑客可能通过一些不常用的属性实现病毒或木马的隐藏;
- 入口地址和基址
体会:入口地址对于调试和逆向工程非常重要,它指示了程序的执行起点。基址则影响了程序的内存布局,理解这部分有助于我们更好地分析程序的运行行为。
- 节表
体会:节表的分析有助于理解程序的模块化结构,不同的节有不同的用途,如.text节通常包含可执行代码,.data节包含初始化数据。这对于逆向工程和漏洞分析非常有用。
通过这次实验,我对PE文件的结构和关键数据项有了更深的理解。这些知识不仅加深了我对操作系统和文件系统的理解,也为我在软件分析、调试和逆向工程方面提供了重要的基础。PE文件的分析不仅是理论知识的验证,更是实践能力的提升,让我能够更好地应用所学知识解决实际问题。
在未来的学习和工作中,我会继续深入研究PE文件的其他细节,并尝试应用这些知识进行更复杂的分析任务。此次实验不仅让我掌握了具体的技能,也培养了我细致观察和系统分析的能力,这将对我未来的学习和职业发展产生深远影响。
参考资料
PE结构详解1-系统篇-第一讲-解密系列_哔哩哔哩_bilibili
PE文件结构全局大揭秘,【PE文件结构全局概览解析】:轻松学习不迷路(软件安全/游戏安全必备基础知识)_哔哩哔哩_bilibili
PE文件结构详解 --(完整版)_pe结构图下载-CSDN博客
PE学习——PE文件整体结构解析,写得很精致,可以对照案例实践 - bonelee - 博客园 (cnblogs.com)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构