1
月
在社区成长 1 月
LEVEL 1
1 XP
一、背景与目标
面对来源不明的 Windows PE 文件,最危险的做法不是“分析得不够深”,而是在缺乏隔离、快照和观测手段时直接双击运行。实际分析中还经常遇到加壳、反调试、延迟执行、子进程派生、网络不可达以及工具崩溃等情况。因此,一套可复现的分析流程应先回答三个问题:样本是什么、运行后改变了什么、证据是否足以支持结论。
本文以本地授权实验室中的可疑 EXE 为例,建立“静态分诊—受控执行—调试定位—证据归档”的工作流。重点不是破解商业软件,也不涉及真实目标,而是用于恶意样本防御分析、告警复核与应急响应。文中的 sample.exe 应替换为你有权分析的文件。
二、核心原理
PE 文件由 DOS 头、NT 头、节表、导入表、导出表、资源和可选调试信息等结构组成。静态分析通过这些结构推测程序能力,例如网络通信、持久化、进程操作和内存权限修改。动态分析则记录程序真正触发的文件、注册表、进程、模块和网络行为。
两者必须交叉验证。导入 VirtualAlloc 并不代表一定会解密载荷;没有静态导入网络 API,也不代表不会联网,因为程序可能使用 LoadLibrary、GetProcAddress 动态解析函数。可靠结论应写成“观察到什么证据”,而不是仅凭字符串或单个 API 猜测。
三、前置条件与隔离边界
建议准备一台专用虚拟机,Windows 10 或 Windows 11 均可,并安装以下工具:
1. Detect It Easy 或 PE-bear:查看 PE 结构、编译器特征和壳特征。
2. FLOSS 或 Sysinternals Strings:提取普通字符串及可能的栈字符串。
3. capa:从代码特征归纳能力。
4. Ghidra:反编译和交叉引用分析。
5. x64dbg:用户态动态调试。
6. Process Monitor、Process Explorer:记录系统行为和进程关系。
7. Wireshark、FakeNet-NG:观察并模拟网络服务。
8. 可选工具:Regshot、PE-sieve、Sysmon。
虚拟机应使用快照,关闭共享剪贴板、共享目录、拖放、USB 自动挂载和宿主机盘映射。网络优先选择 Host-only;如需观察联网行为,使用 FakeNet-NG 或 INetSim 模拟 DNS、HTTP 等服务,不应把未知样本直接连接生产网络或家庭局域网。分析账号不要保存真实凭据、浏览器 Cookie、SSH 密钥或云访问令牌。
四、第一阶段:样本登记与静态分诊
第一步不是打开文件,而是生成可重复核验的标识。将样本放入只用于分析的目录,然后计算哈希:
certutil -hashfile sample.exe SHA256
certutil -hashfile sample.exe SHA1
PowerShell 也可以使用:
Get-FileHash .\sample.exe -Algorithm SHA256
记录文件大小、获取时间、原始文件名、哈希和分析环境快照编号。后续若工具输出不一致,应先核对哈希,避免分析对象已被覆盖或隔离软件修改。
接着用 Detect It Easy 检查文件类型、位数、入口点、编译器或打包器提示。重点观察以下异常:
1. 入口点是否落在名称异常或权限异常的节中。
2. 是否存在同时具备可写和可执行权限的节。
3. 节的原始大小与虚拟大小是否差异悬殊。
4. 导入函数是否极少,但文件体积较大。
5. 节熵是否普遍偏高,资源中是否嵌入大块数据。
6. 数字签名是否存在、是否有效,以及签名主体与文件来源是否匹配。
高熵只能作为压缩或加密的线索,不能单独证明恶意。安装包、游戏资源和合法保护壳同样可能呈现高熵。
使用 FLOSS 提取字符串:
floss.exe sample.exe > floss.txt
对结果进行分类,而不是只搜索“可疑词”。建议分别整理:URL 与域名、文件路径、注册表路径、互斥体、命令行片段、错误信息、用户代理、PDB 路径和加密相关常量。字符串也可能是未使用代码、诱饵或第三方库内容,必须回到交叉引用确认。
然后运行 capa:
capa.exe sample.exe -vv > capa-report.txt
重点关注能力组合。例如“枚举进程”本身很常见,但若同时出现“写入其他进程内存”“改变内存权限”“创建远程线程”,就应进一步检查是否存在进程注入链。capa 的结果是定位入口,不是最终定性。
五、第二阶段:用 Ghidra 建立代码假设
在 Ghidra 中导入样本并完成自动分析。先从入口点、导入表和字符串交叉引用入手,不必一开始逐函数阅读。
可以按照能力创建标签:NET、PERSIST、PROC、CRYPTO、CONFIG、ANTI。若发现 URL 字符串,查看引用该字符串的函数,再向上追踪调用者;若字符串没有直接引用,检查是否在运行时解码。对于 GetProcAddress,观察传入的 API 名称,以及返回地址最终被哪个间接调用使用。
一个常见的配置解码函数可能表现为循环读取字节、与固定值或短密钥异或、随后将结果传给网络或文件 API。此时不要急于编写通用解密器,应先确认输入数据地址、长度来源和输出缓冲区。可在动态阶段对该函数返回点下断点,直接检查解码后的内存,从而减少静态猜测。
建议为每个假设记录三项:静态证据、预期动态现象、验证位置。例如:
假设:样本会在用户启动目录建立持久化。
静态证据:发现 Startup 路径字符串,并交叉引用到 CopyFileW。
预期现象:运行后出现新文件。
验证位置:Procmon 的 CreateFile、WriteFile 和 SetRenameInformationFile 事件。
六、第三阶段:受控动态观测
恢复到干净快照,先启动观测工具,再运行样本。Process Monitor 建议设置过滤器:
Process Name is sample.exe -> Include
Operation is Process Create -> Include
Operation begins with RegSet -> Include
Operation is CreateFile -> Include
Operation is WriteFile -> Include
不要只按 sample.exe 过滤到底。如果样本派生 rundll32.exe、powershell.exe 或其他子进程,过窄的过滤器会漏掉关键行为。可以先记录全部事件,再按照进程树回溯相关 PID。
运行前后分别使用 Regshot 创建快照,对比注册表和文件系统变化。Process Explorer 用于观察父子进程、命令行、加载模块和签名状态。Wireshark 可使用以下显示过滤器缩小范围:
dns || http || tls
如果使用 FakeNet-NG,应记录它分配的模拟地址、DNS 查询、HTTP Host、URI、请求头和响应触发条件。不要仅因出现 DNS 查询就断言数据外传;需要结合请求内容、频率、载荷大小和调用栈判断。
动态执行应设置时间上限,例如五分钟。到期后保存 Procmon PML、网络 PCAP、进程树截图及工具日志,然后关机并恢复快照。不要让样本长期后台运行,也不要在同一快照上连续测试多个样本,否则状态污染会使结论难以复现。
七、第四阶段:使用 x64dbg 验证关键路径
在 x64dbg 中加载样本时,先确认架构匹配:32 位程序使用 x32dbg,64 位程序使用 x64dbg。可在以下 API 上设置断点,用于验证能力而非盲目单步:
bp kernel32!CreateProcessW
bp kernel32!VirtualAlloc
bp kernel32!VirtualProtect
bp kernel32!WriteProcessMemory
bp kernel32!CreateRemoteThread
bp winhttp!WinHttpSendRequest
不同 Windows 版本中,导出可能转发到 KernelBase 或底层 ntdll。若断点未命中,应检查模块是否已加载,并在对应模块加载后重新设置断点。对于动态解析 API 的样本,可在 LoadLibraryW 和 GetProcAddress 上断下,记录模块名、函数名及返回地址。
命中 VirtualProtect 时,应重点记录目标地址、区域大小和新权限。如果某块内存先被写入,随后从 RW 变为 RX,并且控制流跳入该区域,这比“导入了 VirtualProtect”更有证据价值。此时可以在目标区域设置执行断点,继续运行到真实代码入口。
如果怀疑加壳,常见现象包括入口点附近存在解压循环、导入极少、运行后出现新的可执行内存以及最终跳转到另一片代码区。到达疑似原始入口点后,可用调试器或 PE-sieve 保存内存映像,再单独分析转储文件。转储文件必须重新计算哈希,并明确标注为“运行时内存转储”,不能与原始样本混为一谈。导入表重建失败时,不应强行得出“样本损坏”的结论;它也可能使用手工映射、哈希解析 API 或仅在特定条件下解密完整代码。
八、失败恢复与证据保全
分析过程经常失败,关键是保留可回退路径:
1. 样本立即退出:检查命令行参数、当前目录、缺失 DLL、互斥体、系统时间和网络响应,不要直接认定为反虚拟机。
2. 调试器下行为消失:对比无调试器运行记录,检查 IsDebuggerPresent、CheckRemoteDebuggerPresent、NtQueryInformationProcess 和异常处理链,但避免为了绕过检测而修改过多位置,否则会改变样本路径。
3. Procmon 数据量过大:先按进程树确定相关 PID,再按操作类别过滤;保留原始 PML,导出的 CSV 仅作为工作副本。
4. 网络请求没有出现:确认 DNS、默认路由、FakeNet-NG 监听状态和防火墙规则,并检查样本是否延迟执行或依赖配置文件。
5. 工具崩溃:不要在污染快照上反复重试。保存崩溃时间点、工具版本和样本哈希,恢复快照后换用另一工具交叉验证。
6. 样本修改自身:保留原始只读副本,比较运行前后哈希,并记录新生成文件与父进程关系。
每个重要结论至少关联一种原始证据,例如 PML 事件、PCAP 数据包、断点参数、内存地址、反编译交叉引用或文件哈希。截图可辅助说明,但不应替代可检索的原始日志。
九、风险与注意事项
未知样本可能利用虚拟机漏洞、窃取共享资源或横向访问局域网,因此隔离配置比调试技巧更重要。不要在宿主机直接解压并运行样本;若必须传输,使用加密压缩包并通过受控中转目录完成,传输后立即关闭共享功能。不要把样本上传到未经授权的在线沙箱,因为文件可能包含客户数据、内部证书或尚未公开的代码。
不要把所有异常行为都归因于恶意。安装程序也会写注册表、创建服务和释放临时文件。定性时需要结合来源、签名、行为目的、持久化方式、网络目的地和是否存在规避行为。分析报告中应区分“已观察”“高度怀疑”和“尚未验证”。
十、常见问题
问:看到 UPX 标记就能直接脱壳吗?
答:不能。标记可能被伪造,也可能是修改版 UPX。先用工具测试是否能正常识别,再通过运行时内存权限变化和控制流转移确认。
问:没有联网行为是否说明样本安全?
答:不能。样本可能只执行本地破坏、等待日期、读取特定配置、检测环境后退出,或需要命令行参数触发。
问:断点设置很多是否更容易抓到行为?
答:通常相反。大量断点会显著改变时序,并产生难以整理的噪声。应根据静态假设设置少量关键断点,命中后记录参数、返回值和调用栈。
问:字符串中出现域名能否直接作为封禁指标?
答:应先确认是否被代码引用、是否实际解析或连接,以及是否属于合法第三方组件。未经验证的字符串更适合作为待调查线索。
问:怎样判断分析可以结束?
答:当主要能力已有静态与动态证据互相支持,关键文件、注册表、进程和网络指标已归档,未验证项已明确列出,并且其他分析人员能依据步骤复现结果时,可以结束本轮分析。
十一、总结
高质量的 PE 样本分析不是堆砌工具,而是管理假设、证据和失败路径。先通过哈希、PE 结构、字符串和能力识别建立假设,再用 Procmon、网络模拟和调试断点验证真实行为;遇到加壳或反分析时,优先保存现场并恢复快照,而不是在污染环境中无限试错。最终报告应给出可核验的行为链、证据来源、置信度和未决问题。这样得到的结果既能支持防御规则与应急处置,也能避免把静态线索误写成事实。
面对来源不明的 Windows PE 文件,最危险的做法不是“分析得不够深”,而是在缺乏隔离、快照和观测手段时直接双击运行。实际分析中还经常遇到加壳、反调试、延迟执行、子进程派生、网络不可达以及工具崩溃等情况。因此,一套可复现的分析流程应先回答三个问题:样本是什么、运行后改变了什么、证据是否足以支持结论。
本文以本地授权实验室中的可疑 EXE 为例,建立“静态分诊—受控执行—调试定位—证据归档”的工作流。重点不是破解商业软件,也不涉及真实目标,而是用于恶意样本防御分析、告警复核与应急响应。文中的 sample.exe 应替换为你有权分析的文件。
二、核心原理
PE 文件由 DOS 头、NT 头、节表、导入表、导出表、资源和可选调试信息等结构组成。静态分析通过这些结构推测程序能力,例如网络通信、持久化、进程操作和内存权限修改。动态分析则记录程序真正触发的文件、注册表、进程、模块和网络行为。
两者必须交叉验证。导入 VirtualAlloc 并不代表一定会解密载荷;没有静态导入网络 API,也不代表不会联网,因为程序可能使用 LoadLibrary、GetProcAddress 动态解析函数。可靠结论应写成“观察到什么证据”,而不是仅凭字符串或单个 API 猜测。
三、前置条件与隔离边界
建议准备一台专用虚拟机,Windows 10 或 Windows 11 均可,并安装以下工具:
1. Detect It Easy 或 PE-bear:查看 PE 结构、编译器特征和壳特征。
2. FLOSS 或 Sysinternals Strings:提取普通字符串及可能的栈字符串。
3. capa:从代码特征归纳能力。
4. Ghidra:反编译和交叉引用分析。
5. x64dbg:用户态动态调试。
6. Process Monitor、Process Explorer:记录系统行为和进程关系。
7. Wireshark、FakeNet-NG:观察并模拟网络服务。
8. 可选工具:Regshot、PE-sieve、Sysmon。
虚拟机应使用快照,关闭共享剪贴板、共享目录、拖放、USB 自动挂载和宿主机盘映射。网络优先选择 Host-only;如需观察联网行为,使用 FakeNet-NG 或 INetSim 模拟 DNS、HTTP 等服务,不应把未知样本直接连接生产网络或家庭局域网。分析账号不要保存真实凭据、浏览器 Cookie、SSH 密钥或云访问令牌。
四、第一阶段:样本登记与静态分诊
第一步不是打开文件,而是生成可重复核验的标识。将样本放入只用于分析的目录,然后计算哈希:
certutil -hashfile sample.exe SHA256
certutil -hashfile sample.exe SHA1
PowerShell 也可以使用:
Get-FileHash .\sample.exe -Algorithm SHA256
记录文件大小、获取时间、原始文件名、哈希和分析环境快照编号。后续若工具输出不一致,应先核对哈希,避免分析对象已被覆盖或隔离软件修改。
接着用 Detect It Easy 检查文件类型、位数、入口点、编译器或打包器提示。重点观察以下异常:
1. 入口点是否落在名称异常或权限异常的节中。
2. 是否存在同时具备可写和可执行权限的节。
3. 节的原始大小与虚拟大小是否差异悬殊。
4. 导入函数是否极少,但文件体积较大。
5. 节熵是否普遍偏高,资源中是否嵌入大块数据。
6. 数字签名是否存在、是否有效,以及签名主体与文件来源是否匹配。
高熵只能作为压缩或加密的线索,不能单独证明恶意。安装包、游戏资源和合法保护壳同样可能呈现高熵。
使用 FLOSS 提取字符串:
floss.exe sample.exe > floss.txt
对结果进行分类,而不是只搜索“可疑词”。建议分别整理:URL 与域名、文件路径、注册表路径、互斥体、命令行片段、错误信息、用户代理、PDB 路径和加密相关常量。字符串也可能是未使用代码、诱饵或第三方库内容,必须回到交叉引用确认。
然后运行 capa:
capa.exe sample.exe -vv > capa-report.txt
重点关注能力组合。例如“枚举进程”本身很常见,但若同时出现“写入其他进程内存”“改变内存权限”“创建远程线程”,就应进一步检查是否存在进程注入链。capa 的结果是定位入口,不是最终定性。
五、第二阶段:用 Ghidra 建立代码假设
在 Ghidra 中导入样本并完成自动分析。先从入口点、导入表和字符串交叉引用入手,不必一开始逐函数阅读。
可以按照能力创建标签:NET、PERSIST、PROC、CRYPTO、CONFIG、ANTI。若发现 URL 字符串,查看引用该字符串的函数,再向上追踪调用者;若字符串没有直接引用,检查是否在运行时解码。对于 GetProcAddress,观察传入的 API 名称,以及返回地址最终被哪个间接调用使用。
一个常见的配置解码函数可能表现为循环读取字节、与固定值或短密钥异或、随后将结果传给网络或文件 API。此时不要急于编写通用解密器,应先确认输入数据地址、长度来源和输出缓冲区。可在动态阶段对该函数返回点下断点,直接检查解码后的内存,从而减少静态猜测。
建议为每个假设记录三项:静态证据、预期动态现象、验证位置。例如:
假设:样本会在用户启动目录建立持久化。
静态证据:发现 Startup 路径字符串,并交叉引用到 CopyFileW。
预期现象:运行后出现新文件。
验证位置:Procmon 的 CreateFile、WriteFile 和 SetRenameInformationFile 事件。
六、第三阶段:受控动态观测
恢复到干净快照,先启动观测工具,再运行样本。Process Monitor 建议设置过滤器:
Process Name is sample.exe -> Include
Operation is Process Create -> Include
Operation begins with RegSet -> Include
Operation is CreateFile -> Include
Operation is WriteFile -> Include
不要只按 sample.exe 过滤到底。如果样本派生 rundll32.exe、powershell.exe 或其他子进程,过窄的过滤器会漏掉关键行为。可以先记录全部事件,再按照进程树回溯相关 PID。
运行前后分别使用 Regshot 创建快照,对比注册表和文件系统变化。Process Explorer 用于观察父子进程、命令行、加载模块和签名状态。Wireshark 可使用以下显示过滤器缩小范围:
dns || http || tls
如果使用 FakeNet-NG,应记录它分配的模拟地址、DNS 查询、HTTP Host、URI、请求头和响应触发条件。不要仅因出现 DNS 查询就断言数据外传;需要结合请求内容、频率、载荷大小和调用栈判断。
动态执行应设置时间上限,例如五分钟。到期后保存 Procmon PML、网络 PCAP、进程树截图及工具日志,然后关机并恢复快照。不要让样本长期后台运行,也不要在同一快照上连续测试多个样本,否则状态污染会使结论难以复现。
七、第四阶段:使用 x64dbg 验证关键路径
在 x64dbg 中加载样本时,先确认架构匹配:32 位程序使用 x32dbg,64 位程序使用 x64dbg。可在以下 API 上设置断点,用于验证能力而非盲目单步:
bp kernel32!CreateProcessW
bp kernel32!VirtualAlloc
bp kernel32!VirtualProtect
bp kernel32!WriteProcessMemory
bp kernel32!CreateRemoteThread
bp winhttp!WinHttpSendRequest
不同 Windows 版本中,导出可能转发到 KernelBase 或底层 ntdll。若断点未命中,应检查模块是否已加载,并在对应模块加载后重新设置断点。对于动态解析 API 的样本,可在 LoadLibraryW 和 GetProcAddress 上断下,记录模块名、函数名及返回地址。
命中 VirtualProtect 时,应重点记录目标地址、区域大小和新权限。如果某块内存先被写入,随后从 RW 变为 RX,并且控制流跳入该区域,这比“导入了 VirtualProtect”更有证据价值。此时可以在目标区域设置执行断点,继续运行到真实代码入口。
如果怀疑加壳,常见现象包括入口点附近存在解压循环、导入极少、运行后出现新的可执行内存以及最终跳转到另一片代码区。到达疑似原始入口点后,可用调试器或 PE-sieve 保存内存映像,再单独分析转储文件。转储文件必须重新计算哈希,并明确标注为“运行时内存转储”,不能与原始样本混为一谈。导入表重建失败时,不应强行得出“样本损坏”的结论;它也可能使用手工映射、哈希解析 API 或仅在特定条件下解密完整代码。
八、失败恢复与证据保全
分析过程经常失败,关键是保留可回退路径:
1. 样本立即退出:检查命令行参数、当前目录、缺失 DLL、互斥体、系统时间和网络响应,不要直接认定为反虚拟机。
2. 调试器下行为消失:对比无调试器运行记录,检查 IsDebuggerPresent、CheckRemoteDebuggerPresent、NtQueryInformationProcess 和异常处理链,但避免为了绕过检测而修改过多位置,否则会改变样本路径。
3. Procmon 数据量过大:先按进程树确定相关 PID,再按操作类别过滤;保留原始 PML,导出的 CSV 仅作为工作副本。
4. 网络请求没有出现:确认 DNS、默认路由、FakeNet-NG 监听状态和防火墙规则,并检查样本是否延迟执行或依赖配置文件。
5. 工具崩溃:不要在污染快照上反复重试。保存崩溃时间点、工具版本和样本哈希,恢复快照后换用另一工具交叉验证。
6. 样本修改自身:保留原始只读副本,比较运行前后哈希,并记录新生成文件与父进程关系。
每个重要结论至少关联一种原始证据,例如 PML 事件、PCAP 数据包、断点参数、内存地址、反编译交叉引用或文件哈希。截图可辅助说明,但不应替代可检索的原始日志。
九、风险与注意事项
未知样本可能利用虚拟机漏洞、窃取共享资源或横向访问局域网,因此隔离配置比调试技巧更重要。不要在宿主机直接解压并运行样本;若必须传输,使用加密压缩包并通过受控中转目录完成,传输后立即关闭共享功能。不要把样本上传到未经授权的在线沙箱,因为文件可能包含客户数据、内部证书或尚未公开的代码。
不要把所有异常行为都归因于恶意。安装程序也会写注册表、创建服务和释放临时文件。定性时需要结合来源、签名、行为目的、持久化方式、网络目的地和是否存在规避行为。分析报告中应区分“已观察”“高度怀疑”和“尚未验证”。
十、常见问题
问:看到 UPX 标记就能直接脱壳吗?
答:不能。标记可能被伪造,也可能是修改版 UPX。先用工具测试是否能正常识别,再通过运行时内存权限变化和控制流转移确认。
问:没有联网行为是否说明样本安全?
答:不能。样本可能只执行本地破坏、等待日期、读取特定配置、检测环境后退出,或需要命令行参数触发。
问:断点设置很多是否更容易抓到行为?
答:通常相反。大量断点会显著改变时序,并产生难以整理的噪声。应根据静态假设设置少量关键断点,命中后记录参数、返回值和调用栈。
问:字符串中出现域名能否直接作为封禁指标?
答:应先确认是否被代码引用、是否实际解析或连接,以及是否属于合法第三方组件。未经验证的字符串更适合作为待调查线索。
问:怎样判断分析可以结束?
答:当主要能力已有静态与动态证据互相支持,关键文件、注册表、进程和网络指标已归档,未验证项已明确列出,并且其他分析人员能依据步骤复现结果时,可以结束本轮分析。
十一、总结
高质量的 PE 样本分析不是堆砌工具,而是管理假设、证据和失败路径。先通过哈希、PE 结构、字符串和能力识别建立假设,再用 Procmon、网络模拟和调试断点验证真实行为;遇到加壳或反分析时,优先保存现场并恢复快照,而不是在污染环境中无限试错。最终报告应给出可核验的行为链、证据来源、置信度和未决问题。这样得到的结果既能支持防御规则与应急处置,也能避免把静态线索误写成事实。