# PE解析器 **Repository Path**: cutecuteyu/pe-parser ## Basic Information - **Project Name**: PE解析器 - **Description**: PE解析器 - **Primary Language**: Python - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-03-15 - **Last Updated**: 2026-03-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # MinGW DLL + Flask PE分析网页示例 ## 文件说明 - `pe_parser_dll.cpp`:DLL导出入口(仅参数校验与转发) - `pe_parser_core.cpp`:PE解析核心实现(头部、导入表、导出表、JSON输出) - `pe_parser_core.h`:PE解析核心函数声明 - `pe_parser_api.h`:DLL导出接口声明 - `messagebox_app.cpp`:用于测试的MessageBox EXE - `main.py`:Flask路由入口(轻量编排) - `services/pe_service.py`:Python服务层(DLL调用、JSON读取、摘要统计) - `main.cpp`:命令行调用DLL的C++示例主程序(可选) - `templates/index.html`:输入页面 - `templates/report.html`:分析报告页面 ## 第一步:构建DLL和测试EXE(MinGW) ```powershell g++ -std=c++17 -O2 -DBUILD_PE_PARSER_DLL -shared pe_parser_dll.cpp pe_parser_core.cpp -o peparser.dll "-Wl,--out-implib,libpeparser.a" -static-libgcc -static-libstdc++ g++ -std=c++17 -O2 -mwindows messagebox_app.cpp -o messagebox_app.exe ``` ## 第二步:使用uv初始化并安装依赖 ```powershell uv init --app --name pe-web-analyzer --vcs none --no-readme --no-description . uv add flask ``` ## 第三步:启动网页(必须使用uv run) ```powershell uv run python main.py ``` 启动后访问: - `http://127.0.0.1:5000` 在网页输入例如 `messagebox_app.exe`,提交后会: - 调用DLL生成 `messagebox_app_pe_headers.json` - 解析JSON并展示完整PE结构分析报告 - 报告包含 DOS/NT/Optional/Section 信息 - 报告包含导入表(导入DLL、导入函数明细)与导出表(导出函数明细) ## Windows下PE结构详解 ### 总览 - 典型PE文件由以下部分组成:DOS头与Stub、NT头(签名、文件头、可选头)、节表(Section Headers)、各节(.text/.rdata/.data/.rsrc/.reloc 等)以及数据目录(导入、导出、资源、重定位、调试、TLS、CLR 等)。 - 核心作用:描述可执行映像在内存中的布局、入口点、所需库、导出符号、安全/兼容性特性,并为加载器提供解析与装载所需的全部元数据。 ### 基础概念 - RVA/VA/FOA:RVA 为“相对虚拟地址”(相对 ImageBase 的偏移),VA 为“虚拟地址”(RVA + ImageBase),FOA 为“文件偏移”。磁盘文件上的数据需要通过节对齐与地址换算从 FOA 映射到 RVA/VA。 - 对齐:SectionAlignment(内存对齐)与 FileAlignment(文件对齐)决定了节在内存与文件中的边界;解析时须按各自对齐值换算范围。 - 32位/64位差异:PE32 的 OptionalHeader.Magic 为 0x10B,PE32+ 为 0x20B;PE32+ 移除 BaseOfData,指针/VA 字段为 64 位(如 ImageBase、数据目录相关字段)。 ### DOS头 IMAGE_DOS_HEADER - 关键字段: - e_magic:必须为 "MZ" 才视为有效 DOS 头。 - e_lfanew:指向 NT 头(IMAGE_NT_HEADERS)偏移。 - 作用:兼容早期 DOS;为新格式提供跳转位置(NT 头)。 ### NT头 IMAGE_NT_HEADERS - 签名:"PE\0\0" 表示后续为 COFF/PE 结构。 - 文件头 IMAGE_FILE_HEADER: - Machine:CPU 架构(x86、x64、ARM 等)。 - NumberOfSections:节的数量。 - Characteristics:文件特性(可执行、DLL、32位机器等标志)。 - 可选头 IMAGE_OPTIONAL_HEADER(PE32/PE32+): - Magic:区分 32/64 位。 - AddressOfEntryPoint(AEP):进程入口 RVA(DLL 则为 DllMain、EXE 为主入口)。 - ImageBase:映像首选装载基址(启用 ASLR 时可能被随机化)。 - SectionAlignment / FileAlignment:节在内存/文件中的对齐粒度。 - SizeOfImage:整个映像在内存中的大小(按 SectionAlignment 对齐)。 - Subsystem:所需子系统(Windows GUI、CUI、EFI 等)。 - DllCharacteristics:安全/兼容性标志(ASLR/DEP/CFG/高熵VA/终止控制流等)。 - DataDirectory[16]:16 项数据目录,分别指向导出、导入、资源、异常、证书、基址重定位、调试、架构、全局指针、TLS、加载配置、绑定导入、延迟导入、COM CLR 等。 ### 节表 IMAGE_SECTION_HEADER - 描述每个节在文件与内存中的位置与属性: - Name:节名(如 .text、.rdata、.data、.rsrc、.reloc)。 - VirtualAddress / VirtualSize:在内存中的 RVA 与大小。 - PointerToRawData / SizeOfRawData:在文件中的偏移与大小。 - Characteristics:属性位(可执行、可读、可写、对齐、是否包含代码/数据等)。 - 常见节: - .text:代码段(可执行、只读)。 - .rdata:只读数据(常量、导入名称等)。 - .data / .pdata:可写数据/异常处理表(x64)。 - .idata:导入表相关(可含 IAT/ILT)。 - .edata:导出表。 - .rsrc:资源(图标、版本信息、清单等)。 - .reloc:重定位信息。 - .tls:线程本地存储及回调。 ### 数据目录要点 - 导出表(IMAGE_EXPORT_DIRECTORY): - 描述该模块导出的函数/数据(名称、序号、RVA);构成 EAT(Export Address Table)。 - 可能存在“转发导出”(Forwarded Export),即导出转指向其他 DLL。 - 导入表(IMAGE_IMPORT_DESCRIPTOR): - 列出所依赖的 DLL 及其导入的函数(按名称或序号)。 - IAT(Import Address Table)在加载阶段被填充为实际函数地址,程序通过 IAT 间接调用。 - ILT/INT(导入名称表)保存原始导入引用;存在延迟导入(Delay-Load)。 - 基址重定位(IMAGE_BASE_RELOCATION): - 当映像未能装载到首选 ImageBase 时,需对涉及绝对地址的指针进行修正。 - 常见类型:x86 的 HIGHLOW,x64 的 DIR64;ASLR 下广泛使用。 - 资源(.rsrc): - 树状结构(目录/条目/数据);包括 ICON、VERSION、MANIFEST 等。 - Unicode 名称支持,层级索引需谨慎边界检查。 - 调试目录(IMAGE_DEBUG_DIRECTORY): - 包含调试信息指针,如 CodeView(RSDS)记录 PDB 路径/签名。 - TLS(线程本地存储): - 描述 TLS 段与回调函数(在入口前由加载器按线程调用)。 - 加载配置(IMAGE_LOAD_CONFIG_DIRECTORY): - 包含 SafeSEH、CFG(Control Flow Guard)、SEH 处理相关、Security Cookie 等安全特性。 - COM/CLR(.NET 程序): - COM Descriptor 指向 CLR 元数据与运行时(表示为托管程序集)。 ### Windows装载流程简述 1. 将各节按 SectionAlignment 映射到内存(只读/可写/可执行权限由 Characteristics 决定)。 2. 解析导入表,装载依赖 DLL,填充 IAT。 3. 若基址发生变化则应用重定位。 4. 处理 TLS(分配段并调用 TLS 回调)。 5. 调用入口点(EXE 的 AEP 或 DLL 的 DllMain)。 ### 校验与安全相关 - CheckSum:PE 校验和值(部分系统路径下文件可能要求有效值)。 - 签名(WIN_CERTIFICATE/Authenticode):用于代码签名与信任验证(位于文件末尾,不映射到内存)。 - 安全标志:DEP(/NXCOMPAT)、ASLR(/DYNAMICBASE)、CFG(/GUARD:CF)、高熵VA(/HIGHENTROPYVA)等。 ### 解析实现注意事项(常见坑) - 地址换算:RVA ↔ FOA 必须结合节表与对齐;不要直接等同。 - 边界校验:所有目录/表项需验证 RVA/大小在映像范围内且不越界、不过度重叠。 - 名称与序号:导入/导出既可按名称也可按序号;存在转发导出。 - 资源编码:资源名称可能为 Unicode;层级繁多需严格校验。 - x86/x64 差异:指针尺寸、异常表(.pdata)、重定位类型等不同。 ### 与本项目的对应 - `pe_parser_core.cpp` 负责读取 DOS/NT/Optional/Section 与各数据目录,生成结构化 JSON。 - `services/pe_service.py` 读取 JSON 汇总并在报告页展示:节布局、导入/导出明细、资源与重定位等关键信息。