ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

CTF Wiki 脱壳入门:Windows PE 保护壳(Packer)的定义、分类与加载过程详解

CTF Wiki 脱壳入门:Windows PE 保护壳(Packer)的定义、分类与加载过程详解 文档网络安全教程【免费下载链接】ctf-wikiCome and join us, we need you!项目地址https://gitcode.com/gh_mirrors/ct/ctf-wiki点击查看免费下载导读本文是 CTF Wiki「Windows 逆向 · 脱壳技術」系列的开篇基础篇围绕 packer-introduction.md 展开系统讲解 Windows PE 文件中「壳」Packer的本质定义、压缩壳与加密壳两大类别的特性差异以及外壳程序在运行时必经的四个加载阶段保存现场、获取 API、解密区块、交还控制权。读完本文你将建立完整的壳模型认知并能以此为坐标系理解 單步跟蹤法、ESP 定律法、一步到達 OEP 法、內存鏡像法 等后续脱壳手法为何奏效——因为所有脱壳技巧本质上都是在逆向「壳的加载过程」。认识壳一段先行取得控制权的保护程序壳Shell / Packer是指寄生在某些计算机软件中、专门负责保护软件不被非法修改或反编译的程序。它的运行特点是先于原程序取得控制权壳代码随 PE 文件一起被加载器装载在进入原始程序入口点OEPOriginal Entry Point之前外壳先获得 CPU 控制权外壳完成其保护任务解压、解密、反调试等后再把控制权交还给原始程序继续执行。壳在程序启动时先行取得控制权完成保护任务后再交还给原始代码正是由于这段程序与自然界中「壳」的功能高度相似包裹并保护内层主体人们沿用了这一命名规则将其称为「壳」。在 CTF 逆向与恶意样本分析场景中壳无处不在一道 Windows 逆向题可能被加壳以增大分析难度恶意程序也常加壳以规避静态查杀因此「认识壳」是进入脱壳实战前的第一课。壳的分类压缩壳与加密壳通常将壳划分为两大类压缩壳与加密壳。二者在设计目标上有着根本区别理解这一区别直接决定了分析时采用的手段。压缩壳压缩壳的历史可追溯到 DOS 时代当时受限于计算能力解压开销过大并未得到广泛运用随着硬件性能提升压缩壳逐渐普及。它的核心价值包括缩减 PE 文件体积通过压缩算法减小文件占用的磁盘空间便于网络传输与保存隐藏内部细节压缩过程会隐藏 PE 文件内部的代码与资源结构使静态分析难以直接定位真实逻辑两类典型用途一类仅用于对普通 PE 文件做单纯压缩尽量保持原程序结构可还原另一类会对源文件进行较大变形严重破坏 PE 文件头使文件结构面目全非常被用于压缩恶意程序以干扰分析与查杀。常见的压缩壳有UPX、ASPack、PECompat。其中 UPX 是开源且应用最广泛的压缩壳其加壳结构规整、特征明显典型入口为pushad后接解压循环因此也成为 CTF 脱壳入门最常用的练习对象手動修復 IAT 等文章即以 UPX 加壳的 DLL 为例展开。加密壳加密壳又称保护壳其核心目的不再是压缩而是运用多种防止代码逆向分析的技术保护 PE 免受代码级逆向由于不再以缩小体积为目标加密壳保护的 PE 程序通常比原文件大得多大量应用于对安全性要求高、对破解敏感的应用程序商业软件授权保护等同时恶意程序也常利用加密壳避免或降低杀毒软件的检测查杀。常见的加密壳有ASProtector、Armadillo、EXECryptor、Themida、VMProtect。其中 VMProtect、Themida 等还引入了虚拟化VM保护技术将部分指令翻译为自定义虚拟机字节码逆向难度显著提升这已超出纯脱壳范畴涉及 虛擬機逆向 的相关知识。压缩壳与加密壳的对比对比维度压缩壳加密壳保护壳首要目标压缩体积、便于传输保存防止代码逆向分析对体积的影响显著缩小通常比原文件更大对 PE 结构的影响轻则单纯压缩重则破坏文件头广泛运用变形、加密、反调试手段典型代表UPX、ASPack、PECompatASProtector、Armadillo、EXECryptor、Themida、VMProtect常见使用场景普通程序压缩、恶意程序压缩商业授权保护、恶意程序免杀壳的加载过程外壳从启动到交权的四阶段无论压缩壳还是加密壳其运行时行为都遵循一条几乎固定的流程。这条流程也是所有脱壳方法的理论根基——脱壳的本质就是观察并截获外壳在某个阶段留下的特征。外壳启动后的加载过程可以拆解为以下四个阶段。第一阶段保存入口参数现场保护加壳程序在初始化时必须先完整保存原始程序的现场环境才能放心地运行自己的解压/解密逻辑加壳程序初始化时保存各寄存器的值外壳执行完毕解压/解密工作完成后恢复各寄存器值最后再跳到原程序入口执行。保存与恢复现场通常借助指令对实现pushad/popad用于批量保存/恢复通用寄存器EAX、ECX、EDX、EBX、ESP、EBP、ESI、EDIpushfd/popfd用于保存/恢复标志寄存器 EFLAGS。这一阶段正是后续多种脱壳手法的观测点在 單步跟蹤法 的示例中Notepad.exe 的壳入口第一句就是pushad把所有寄存器压入栈中随后调用解压函数而在0040D3AF处出现popad表示解压完毕、开始恢复现场ESP 定律法 则直接利用这一特征执行完入口的pushad后ESP 寄存器值发生改变OllyDbg 中显示为红色分析者对此 ESP 值设硬件断点运行后在popad之后断下即可快速逼近 OEP一步到達 OEP 法 更进一步直接在代码中搜索popad特征指令CtrlF查找、CtrlL找下一个匹配定位到解压完毕即将跳转 OEP 的位置。第二阶段获取所需函数 API外壳需要调用 Windows API 来完成解压、解密、申请内存等操作但它不能像正常程序那样依赖完整的输入表因为加壳时输入表被替换。其典型的 API 获取策略如下一般壳的输入表IAT中只保留极少数必要 APIGetProcAddress、GetModuleHandle、LoadLibrary若还需其他 API 函数则通过LoadLibraryA(W)或LoadLibraryExA(W)将对应 DLL 文件映射到调用进程的地址空间中如果所需 DLL 已被映射进进程地址空间则可调用GetModuleHandleA(W)获得该 DLL 的模块句柄一旦 DLL 模块被加载并获得句柄就可以调用GetProcAddress按名称获取所需导入函数的实际地址。这一阶段在动态分析中表现明显在 單步跟蹤法 的示例中步进到解压代码内部后可以看到程序依次调用GetModuleHandleA、GetProcAddress等 API——这正是外壳按名称解析自身所需函数的现场。换句话说当你在调试器中看到大量GetProcAddress调用序列时基本可以确认正处于壳的「获取 API」阶段。第三阶段解密各区块数据出于保护源程序代码与数据的目的加壳时一般会加密源程序文件的各个区块Section。在程序运行时外壳负责将这些区块数据解密使原程序得以正常运行外壳通常按区块加密、按区块解密逐段还原解密后的数据被放回合适的内存位置即 PE 加载后各区块对应的虚拟地址区域。区块访问顺序与内容特征也构成了脱壳的重要线索。例如 內存鏡像法 正是利用了「程序自解压/自解密时会先访问资源段.rsrc获取所需资源完成后转回代码段.text」这一规律分析者通过AltM打开内存镜像先对.rsrc段下一次性内存断点示例中地址为00407000大小00005000运行后程序断在解压过程中再对.text代码段示例中00401000处下断点运行后程序恰好停在 OEP004010CC。对 PE 区块结构不熟悉的读者可先参考 PE 文件基本结构 中关于节区Section的说明。第四阶段跳转回原程序入口点解压/解密完成后外壳需要把控制权完整地交还给原始程序这一阶段通常包含三个动作恢复并填写原 PE 文件的输入表IAT并处理好重定位项主要是针对 DLL 文件由于加壳时外壳构造了属于自己的输入表因此此时必须对原程序引入的每一个 DLL 的所有函数重新获取地址并逐一填写到 IAT 表中原程序才能在运行时正确解析导入函数上述工作全部完成后将控制权移交给原程序跳转到 OEP 并继续执行。跳转回 OEP 的典型手法在 單步跟蹤法 的示例代码中清晰可见0040D3AF 61 popad 0040D3B0 75 08 jnz short NotePad.0040D3BA 0040D3B2 B8 01000000 mov eax,0x1 0040D3B7 C2 0C00 retn 0xC 0040D3BA 68 CC104000 push NotePad.004010CC 0040D3BF C3 retn这里popad恢复了入口处保存的寄存器状态随后jnz跳到0040D3BA的push NotePad.004010CC再配合retn将 EIP 修改为004010CC——即原程序的入口点 OEP。这种「pushretn」改写 EIP 的模式在压缩壳中非常常见可作为识别「即将到达 OEP」的标志。值得注意的是跳回 OEP 时的 IAT 填写质量直接决定脱壳后程序能否正常运行。由于push/ret之后、真正进入 OEP 之前壳已完成 IAT 的重新解析分析者在到达 OEP 后通常需要dump 内存镜像并修复 IAT这正是脱壳系列中 修復 IAT 与 手動修復 IAT 两篇文章的用武之地。以加载过程为坐标系理解脱壳手法将上述四个阶段与同目录下的脱壳方法一一对照会发现整个「脫殼技術」系列其实是对「壳的加载过程」不同观测角度的投影壳的加载阶段特征观测点对应脱壳手法保存入口参数入口pushad/pushfd结束处popad/popfdESP 定律法、一步到達 OEP 法获取所需 API频繁调用GetProcAddress、GetModuleHandle等單步跟蹤法 中识别壳的解压逻辑解密各区块.rsrc资源段与.text代码段的访问顺序內存鏡像法跳转回 OEP大跨度jmp、pushretn改写 EIP、popad后跳转單步跟蹤法、一步到達 OEP 法OEP 之后的收尾IAT 表完整性、DLL 重定位修復 IAT、手動修復 IAT在 mkdocs.yml 的导航配置中本文档packer-introduction.md正位于「Windows 逆向 → 脫殼技術」章节的首位其后依次是 trace单步跟踪、espESP 定律、direct-oep一步到达 OEP、memory内存镜像、last-exception最后一次异常法、sfx、fix-iat修复 IAT、manually-fix-iat手动修复 IAT与 unpack-dllDLL 脱壳可见本文是整条脱壳知识链的起点。遇到非常规壳如带反调试、异常处理或特殊入口的壳时还可结合 反調試技術 等相关章节继续深入。小结本文从 CTF Wiki 脱壳系列的开篇文档出发建立了关于壳的完整基础认知壳是先行取得控制权、保护软件不被修改与反编译的程序它分为以压缩体积为目的的压缩壳UPX、ASPack、PECompat和以防逆向为目的的加密壳ASProtector、Armadillo、EXECryptor、Themida、VMProtect其运行过程固定为「保存现场 → 获取 API → 解密区块 → 跳转 OEP」四阶段。掌握这一加载模型后你便可以在实战中把 ESP 定律法 的pushad断点、內存鏡像法 的区块断点、單步跟蹤法 的popad/pushretn观察等技巧统一映射到「壳现在执行到哪个阶段」这个问题上从而有的放矢地完成每一次脱壳。赞分享文档网络安全教程【免费下载链接】ctf-wikiCome and join us, we need you!项目地址https://gitcode.com/gh_mirrors/ct/ctf-wiki点击查看免费下载相关推荐基于 qwen-code/channel-base 构建 Qwen Code 通道适配器基类、访问控制与会话路由全解析基于 qwen code/channel base 构建 Qwen Code 通道适配器基类、访问控制与会话路由全解析 qwen code/channel文档网络安全教程CocoIndex Rust 示例深度解析用 Whisper 把音频文件夹增量转写成 Postgres 索引表CocoIndex Rust 示例深度解析用 Whisper 把音频文件夹增量转写成 Postgres 索引表 本篇技术指南围绕 CocoIndex 仓库中的文档网络安全教程上一篇Xamarin.Forms企业级应用开发终极指南10个架构设计与团队协作最佳实践下一篇DiscordGo 插件系统开发构建可扩展的机器人架构终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表