简介:这是一款面向开发者、逆向工程学习者与软件分析人员的 EXE 可执行文件解压与资源提取工具,主要用于查看非安装类可执行程序的内部结构,提取其中嵌入的图片、文本、音频及其他二进制数据,也可辅助排查程序组成、复用素材与开展教学演示。压缩包共 167 个文件,约 5.14MB,包含 42 个 exe 主程序与配套组件、91 个 txt 说明及许可文档、7 个 dll 运行库,以及 ini 配置、ico 图标、doc 手册和 htm 页面等,docs 文档与 bin 运行目录分区明确,便于按模块查阅和部署。已有 3511 人学习下载。读者可从中了解 EXE 封装方式、定位可提取资源、参考配置与日志说明掌握工具用法,并借助许可和变更记录判断功能边界;对资源分析、软件结构研究或课堂演示而言,具备较实用的参考价值。使用时需遵守版权法规与软件许可条款。
1. EXE 可执行文件解压工具下载前,先把环境账算清楚
拿到一个来源不明的安装包,双击怕改注册表,右键又没有解压选项,大部分人这时候的第一个念头都是装一个 EXE 可执行文件解压 工具。我第一次也是这么干的,结果第一次就出错:工具装好了,对着一个两百多兆的 setup.exe 点下去,解出来三层空目录加一个同名 exe,真正想找的资源一个没出来。后来才想明白,EXE 文件解压 这件事的难点根本不在工具装没装,而在你能不能先认出这个 exe 是哪一类打包器,以及本机环境是否允许它顺利展开。这套环境适合三类人:需要提取安装包内静态资源的前端与客户端开发、做样本初步分析的逆向新手、以及要批量提取图形素材和配置文件的从业者。装不好的典型表现不是报错,而是安静地给你一堆残缺文件,那才是最费时间的。
2. 下载与落地:EXE 解压工具从压缩包到可用命令行
这一章做的事很具体:把下载下来的工具落进一个固定目录,让它从「双击才能用」变成「命令行随时能调」。很多人卡在这里,不是因为操作复杂,而是因为从一开始就没规划目录,工具解压到下载文件夹,输出文件也扔在下载文件夹,几十次解包之后自己都不知道哪份输出对应哪个样本。我一般会在动手前先把目录结构定死,后面所有步骤都围绕这套结构来。
2.1 先认打包器:NSIS、Inno Setup、InstallShield 的分辨方法
在装工具之前,先花两分钟判断 target.exe 的类型,能省掉后面一半的返工。最常见的几类是:自解压包(SFX)、NSIS 安装包、Inno Setup 安装包、InstallShield 安装包、MSI 封装,以及原生编译出来的 PE 可执行文件。最后一种特别注意,它不是压缩包,没有任何东西可解,用多贵的工具都解不出资源,只能反编译。
Linux 或 WSL 下判断最快,file加xxd看头部就够:
# 看文件类型与 PE 头部特征 file ./target.exe # 只读前 128 字节,看是否有压缩包魔数或打包器标记 xxd -l 128 ./target.exefile的输出会告诉你这是 PE32 还是 PE32+,以及是否带.NET标记。xxd看得更细:前两个字节是4D 5A(即 MZ)说明这是标准 Windows 可执行文件,但如果偏移几十字节之后能看到Nullsoft、Inno Setup、InstallShield这类 ASCII 字符串,基本就能确定打包器类型。
Windows 下更省事,直接用解压工具列目录,不展开:
# 列出 exe 内部条目,不写盘 7z l .\target.exe # 只看前 40 条,避免输出刷屏 7z l .\target.exe | Select-Object -First 40判断依据很简单:如果能列出大量.dll、.bmp、.ini、[NSIS].nsi这类条目,说明它是可解的封装格式;如果只列出一条data.cab加一个setup.exe,那大概率是 Inno Setup 做的二次封装,通用解压只能剥到第一层,真正的资源还在data.cab里。
我把常见类型和对应处理方式整理成一张表,实际排查时对着看会快很多:
| 打包器类型 | 头部或目录特征 | 推荐处理方式 |
|---|---|---|
| 自解压包 SFX | 有7zSFX或WinRAR SFX字样 | 直接用解压工具展开 |
| NSIS | 目录中出现[NSIS].nsi、$PLUGINSDIR | 解压工具可解,脚本段需另处理 |
| Inno Setup | 出现data.cab、embedded目录 | 优先用 innoextract |
| InstallShield | 出现data1.cab、setup.ins | 需要专用提取工具 |
| MSI 封装 | 头部为 OLE 复合文档结构 | 用msiexec /a管理安装 |
| 原生编译 PE | 只有.text、.rdata段 | 不可解,转反编译方向 |
这张表里最容易误判的是 Inno Setup,因为它第一层用普通解压工具也能打开,很多人以为成功了,其实只拿到了一个壳。
2.2 目录规划:工具本体、输出区、缓存区三分离
我在多台机器上重复踩过同一个坑:把所有东西都放在同一个目录,结果一次误操作把输出目录当缓存清了,前面两小时的解包记录全没了。后来固定成四段式结构,就不再出这种事:
D:\tools\exe-unpack\ ├─ bin\ # 工具本体,唯一需要进 PATH 的目录 ├─ out\ # 解包输出,按样本名分一级子目录 ├─ cache\ # 临时展开区,随时可以整目录删除 └─ logs\ # 每次解包的日志,排错时唯一可信的黑匣子bin只放可执行文件和它自己的依赖库,不做任何输出;out按「样本名_时间戳」建子目录,同一个样本解两次不会互相覆盖;cache专门给大包展开时用,指向一块空间充裕的盘;logs里每次运行落一个文本文件,命名带上时间戳。这四块分开之后,清理缓存不会误伤输出,迁移机器也只需要拷bin和配置文件。
如果本机系统盘紧张,cache可以直接指到另一块盘,比如E:\unpack-cache,后面配置文件里会用到这个路径。
2.3 首次解包与 PATH 配置
工具本体通常以压缩包形式分发,先建目录再展开:
# 一次建好四个目录,已存在时静默跳过 New-Item -ItemType Directory -Force -Path D:\tools\exe-unpack\bin, D:\tools\exe-unpack\out, D:\tools\exe-unpack\cache, D:\tools\exe-unpack\logs # 把工具本体展开到 bin,-Force 覆盖旧版本 Expand-Archive -Path .\exe-unpack.zip -DestinationPath D:\tools\exe-unpack\bin -Force-Force这个参数要留意:升级工具时它是覆盖利器,但如果你在bin里手放过自定义配置,也会一并被覆盖。我的习惯是把个人配置统一放bin外面,升级时只动bin。
接下来把它加进用户级 PATH,不要动系统级,避免影响到其他账户:
# 读取当前用户 PATH,追加 bin 目录后写回 $old = [Environment]::GetEnvironmentVariable("Path", "User") $new = $old + ";D:\tools\exe-unpack\bin" [Environment]::SetEnvironmentVariable("Path", $new, "User")写回之后必须新开一个终端窗口才生效,这是 PowerShell 会话缓存导致的现象,不是配置失败。验证方式:
# 确认解析到了预期路径 where.exe exe-unpack输出应该是D:\tools\exe-unpack\bin\exe-unpack.exe。如果解析到别的目录,说明 PATH 里存在同名工具,或者顺序不对,把新增项挪到前面即可。
第一次实跑建议拿一个小样本,把输出固定到out下:
# -o 指定输出目录,--log 落日志,样本路径放最后 exe-unpack -o ./out/demo-001 --log ./logs/demo-001.log ./samples/demo-setup.exe-o后面跟的目录如果不存在会自动创建;--log是排错时最值钱的一个参数,解包中途失败时,控制台往往只留一行模糊提示,完整原因都在日志里。第一次跑通之后,工具就算落位了,接下来才是真正花时间的地方:依赖和环境。
3. 依赖与运行环境:让工具链真正跑起来的三块基础
工具能启动,不等于能解开所有样本。EXE 解包这条链路上,真正拖后腿的往往是三个看起来跟解压无关的东西:文件系统限制、字符编码、以及安全软件的实时拦截。这一章按平台拆开讲,Windows 侧盯住三项必查,Linux 与 WSL 侧补齐命令行依赖,最后用一份配置文件把默认参数固定下来,避免每次敲一长串参数。
3.1 Windows 侧三个必查项:长路径、编码、安全软件
第一项是长路径。很多安装包内部目录层级极深,展开之后的完整路径轻松超过 260 字符,Windows 默认限制一碰就报「路径过长」,而且报错位置往往在中途,前面已经写了一半文件,输出目录变成半成品。开启长路径支持:
# 开启 NTFS 长路径支持,值为 1 表示启用 Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" ` -Name "LongPathsEnabled" -Value 1这个改动写进注册表后需要重启才完全生效,只是新开终端不够。改完之后可以用一段超长路径建目录测试,能建成功就说明生效了。
第二项是编码。中文目录名、日文资源文件名在解包时经常变成乱码,原因不是工具坏了,而是控制台代码页和文件系统编码不一致。临时切换:
# 切到 UTF-8 代码页,仅对当前会话有效 chcp 65001这只是治标。更稳的做法是在配置文件里把编码策略设为auto,让工具按文件头 BOM 判断,只有确实判断错的时候才手工指定utf-8或gbk。
第三项是安全软件。解包工具的行为特征——大量读写未知 exe、频繁创建临时文件——很容易被实时防护判定为可疑,表现是解到一半文件突然消失,或者工具本体被直接隔离。我的做法是给工具目录和输出目录加白名单:
# 把工具目录与输出目录加入 Defender 排除列表 Add-MpPreference -ExclusionPath "D:\tools\exe-unpack" Add-MpPreference -ExclusionPath "E:\unpack-out"加排除之前先确认工具来源可信,这一步不能省。加完之后再复现一次刚才失败的样本,如果还是中断,那就不是安全软件的问题,回去看日志。
3.2 Linux 与 WSL 侧:补齐 innoextract、binwalk、cabextract
如果主力环境是 Linux,或者习惯在 WSL 里做样本分析,光装一个工具本体是不够的,Inno Setup 和 InstallShield 这两类封装需要额外的提取器兜底。一次性装齐:
# 更新索引后安装 p7zip、innoextract、binwalk、cabextract sudo apt update sudo apt install -y p7zip-full innoextract binwalk cabextract file每个包的作用不一样,别混着用:p7zip-full提供7z命令,能处理 SFX、NSIS、MSI 和多层嵌套压缩;innoextract专攻 Inno Setup,能还原出安装脚本里的文件映射;binwalk用来扫描嵌套在文件尾部的附加数据,很多样本会把真正的载荷追加在 PE 节区之后;cabextract处理.cab分卷,前面那个「只解出 setup.exe 和 data.cab」的场景就靠它收尾。
装完之后验证一遍版本可用性:
# 逐个确认命令可执行,输出被丢弃也无所谓 for c in 7z innoextract binwalk cabextract; do command -v "$c" >/dev/null && echo "$c ok" || echo "$c missing" done四个都输出ok才算依赖齐了。缺哪个回去补哪个,不要指望工具本体自带这些能力。
3.3 配置文件:把默认参数固定下来
参数每次都敲在命令行上,早晚会漏。我一般会在bin同级建一个config.ini,把高频参数写死:
[general] output_dir = D:\tools\exe-unpack\out cache_dir = E:\unpack-cache overwrite = rename encoding = auto log_level = info [extract] keep_timestamps = true preserve_paths = true max_file_size_mb = 4096逐项解释一下取舍:overwrite = rename是最省心的策略,重复解同名样本时自动加后缀,不会覆盖上一次结果;encoding = auto依赖文件头判断,绝大多数情况够用,遇到确定乱码的再改成gbk;max_file_size_mb设成 4096 是因为超过 4G 的单个文件在 FAT32 上直接写不进去,提前卡住比中途失败好排查;keep_timestamps和preserve_paths建议都开,前者保留原始修改时间,方便判断资源版本,后者保持目录层级,避免同名文件互相踩。
配置文件的加载顺序也要清楚:命令行参数 > 配置文件 > 内置默认值。也就是说-o一旦在命令行出现,配置文件里的output_dir就被忽略。这条规则在排查「为什么配置不生效」时特别关键。
4. 配置参数取舍:输出目录、覆盖策略与资源落盘
配置这件事没有标准答案,只有场景匹配。同一个覆盖策略,做资源提取和做样本分析就是两种选法。这一章把三个最容易选错的参数掰开:覆盖策略、大文件与分卷处理、以及资源查看器的联动落盘。每个都给出我实际在用的取值和理由,你可以直接抄,也可以按自己的场景改。
4.1 覆盖策略:ask、rename、skip、overwrite 怎么选
四种策略的差别,只有在重复解同一个样本时才会暴露出来。我把它们放在一起对比:
| 策略 | 行为 | 适用场景 | 风险 |
|---|---|---|---|
| ask | 每次交互询问 | 手工处理少量样本 | 批量脚本会卡住 |
| rename | 自动加序号后缀 | 默认推荐,反复解同一包 | 输出目录会变多 |
| skip | 已存在则跳过 | 增量补充提取 | 旧结果有问题时不会更新 |
| overwrite | 直接覆盖 | 确认前一次结果作废 | 误覆盖不可恢复 |
我自己的习惯是默认rename,只有在明确知道上一次输出有问题、需要重来的时候,才临时用命令行覆盖:
# 临时覆盖,仅对本次生效,不改配置文件 exe-unpack -o ./out/demo-001 --overwrite ./samples/demo-setup.exeask看起来最安全,实际上在批量脚本里最危险。一旦脚本里有循环,第一个重复项就会把整个流程挂在那里等输入,而你可能已经去干别的了。
还有一种情况要特别注意:输出目录如果落在同步盘里,rename产生的多份结果会被同步客户端反复上传,占空间还拖慢速度。这种目录我一般直接排除同步。
4.2 大文件与分卷 EXE:缓存位置、磁盘格式与体积预估
大包展开失败,九成不是工具的问题,是空间和文件系统的问题。先做体积预估,别上来就解:
# 只列条目和大小,不写盘 exe-unpack --list --size ./samples/big-setup.exe输出里会给出条目数和展开后的总字节数。经验值是展开后体积约为原包的 1.5 到 2.5 倍,压缩率高的资源包倍数更大。按这个估算留空间,我一般会留出三倍余量。
几个硬性限制要记住:单个文件超过 4G 时,FAT32 分区直接写不进去,必须换 NTFS 或 exFAT;cache_dir和output_dir最好不要放在同一块盘上,展开过程中两边同时读写,机械盘会明显拖慢速度;如果cache指向的盘剩余空间小于预估体积,工具会在中途失败,日志里通常只写一句「写入失败」,很难联想到空间问题。
分卷的情况稍复杂。有些安装包会把内容切成data1.cab、data2.cab这样的多卷,必须全部放在同一目录下再解,缺一卷就会在中途报错。判断方法很简单,看文件名后缀是否连续编号,有编号就说明是分卷,先把同批文件凑齐。
4.3 与资源查看器联动:把元信息一并落盘
只解出文件还不够。做资源提取的时候,我经常需要知道每个文件在原始包里的路径、大小、修改时间,甚至图标和版本信息。这些元数据如果不在解包时一并导出,后面就得重新跑一遍。
# 解包同时导出元信息清单 exe-unpack -o ./out/demo-002 \ --dump-meta ./out/demo-002/_meta.json \ --dump-strings ./out/demo-002/_strings.txt \ ./samples/demo-setup.exe--dump-meta生成的是结构化清单,包含条目路径、原始大小、压缩后大小、时间戳,后续用脚本做比对很方便;--dump-strings导出可打印字符串,排查「这个包到底调了哪些外部程序」时很有用。两个文件都以下划线开头命名,和真实资源区分开,避免混在一起。
元信息清单还有一个隐藏用途:当你怀疑某次解包不完整时,拿清单里的条目数和实际落盘文件数对一下,差多少一目了然。这比凭感觉判断靠谱得多。
5. 常见问题排查:五类解包失败的现场记录
下面这五条,是我在不同机器、不同样本上反复遇到的。每一条都按「现象、原因、解决」写,照着对症状基本能定位。排查的通用入口只有一个:先看logs目录下对应时间戳的日志,控制台提示往往被截断,日志才是完整的。
5.1 解出来只有一个 setup.exe 和一堆 cab
现象:工具提示解包成功,输出目录里只有setup.exe、data.cab、embedded之类的几个文件,没有任何实际资源。
原因:这是 Inno Setup 的典型两层结构。通用解压工具只能剥掉外层自解压壳,真正的文件列表写在安装脚本里,需要专门的提取器读取。
解决:改用innoextract处理,指定输出目录即可:
# Inno Setup 专用提取,-d 指定输出目录 innoextract -d ./out/demo-003 ./samples/demo-setup.exe如果输出里提示某些条目被跳过,说明是压缩算法不支持,加--simulate先看清单,确认关键文件在不在再实跑。
5.2 中文目录名变成问号或方块
现象:解包成功,但输出目录里的中文名全部显示为????或者乱码方块。
原因:控制台代码页和文件系统编码不一致,或者工具按系统区域设置猜测编码猜错了。
解决:先临时切代码页确认是不是显示问题,如果切完还是乱码,说明是落盘时编码就错了,需要在配置文件里强制指定encoding = gbk或utf-8重跑。判断方法很直接:用十六进制查看器打开文件名,看字节序列是不是合法编码。
5.3 提示「不是有效的压缩包」
现象:一执行就退出,提示格式不支持。
原因:这个 exe 根本不是压缩封装,而是原生编译出来的可执行文件。前面那张表里的最后一行,很多人到这一步才意识到。
解决:先确认类型,别急着换工具:
# 看是否有压缩包特征字符串 strings -n 6 ./target.exe | grep -iE "nullsoft|inno|installshield|7zSFX"没有任何输出,基本可以判定不可解。这时候正确的方向是反编译或动态分析,继续换解压工具只会浪费时间。
5.4 解到一半中断,输出目录残留半成品
现象:进度到某个百分比突然停止,输出目录里有文件但明显不全。
原因:按出现频率排,依次是磁盘空间不足、单文件超过文件系统上限、安全软件实时拦截。三者日志表现不同,空间不足会写「写入失败」,文件系统上限会写「文件过大」,安全软件拦截通常只留一句「句柄无效」。
解决:先看日志确认是哪一类,再分别处理:空间不够就清cache或换盘;文件超限就把输出目录换到 NTFS;被拦截就加排除路径后重跑。重跑之前一定先清空残留的输出目录,否则rename策略会在半成品基础上再叠一层。
5.5 工具本体被杀软直接隔离
现象:刚解压完,bin目录里的可执行文件消失,或者双击提示文件不存在。
原因:解包工具的读写行为特征容易被实时防护误判,尤其是批量处理未知 exe 的时候。
解决:确认来源可信后加排除,再把工具重新展开一次。如果加排除之后仍然被删,检查是不是命中了策略下发的规则,那种情况下换目录名也躲不掉,只能换一台干净的机器处理。
6. 装完怎么验证跑通:三组样本加一次比对
装完就跑一个样本,那不叫验证。我的判断标准是:三类典型封装各跑一次,输出目录结构和条目数都对得上,再拿一次重复解包的结果做比对。三组都过,这套环境才算真的可用。
第一组用自解压包,验证基础解包链路。第二组用 Inno Setup 封装,验证依赖是否齐。第三组用一个原生编译的 exe,验证工具在不可解时能否给出明确提示,而不是静默产出一个空目录——这一组最容易被忽略,但它决定了你以后遇到怪样本时会不会误判。
# 三组样本依次跑,只看清单条目数,不写盘 for f in ./samples/*.exe; do echo "== $f" exe-unpack --list "$f" | wc -l done条目数明显为 1 或者 0 的,回去查第 5 章对应的症状。三组的预期结果对照如下:
| 样本类型 | 预期条目数 | 判定标准 |
|---|---|---|
| 自解压包 | 数十到数百 | 能列出具体资源文件 |
| Inno Setup | 数百以上 | 能看到 data.cab 内部条目 |
| 原生编译 PE | 0 到 1 | 明确提示不可解,不产生空目录 |
最后做一次重复解包比对,确认覆盖策略没写错:
# 同一份样本连跑两次,第二次应生成带后缀的新目录 exe-unpack -o ./out/verify ./samples/demo-setup.exe exe-unpack -o ./out/verify ./samples/demo-setup.exe ls ./out/verify两次输出目录名不同、内容一致,说明rename生效且解包是幂等的。如果第二次把第一次覆盖了,回去改配置文件里的overwrite。
从那以后我每次在新机器上装这套环境,都强制先跑这三组样本再碰真实项目,前后不到五分钟,却挡掉过好几次「工具装了但依赖没齐」的坑。希望帮到你。
本文还有配套的精品资源,点击获取