
简介这份资源是《恶意代码分析实战》一书的课后练习配套实验文件面向正在学习逆向工程与恶意代码分析的安全从业者、CTF选手及高校学生帮助读者在真实样本环境中完成书中各章节的动手实验弥补仅阅读理论而缺乏实操素材的短板。压缩包共74个文件约973KB以52个exe可执行样本和11个dll动态链接库为主另含2个sys驱动、2个py脚本、2个bin二进制文件以及pdf、dat、csv、txt、ini等辅助说明与哈希校验文件覆盖从基础静态分析到高级动态调试的多种样本类型。内容按章节组织涵盖多个实验模块并附有哈希清单便于样本核对与溯源。目前已有812人学习下载适合希望系统练习PE结构解析、加壳识别、行为监控与反汇编调试的读者可配合书中实验步骤逐步验证分析思路积累真实样本处理经验。1. 恶意代码分析实战课后练习实验文件从一份样本到可复现的分析链路拿到「恶意代码分析实战课后练习实验文件」这个标题的人多半不是想听概念而是手里已经有一份样本或者一套练习环境想知道怎么把它跑起来、怎么看出门道、怎么把结论写成能交付的东西。恶意代码分析这件事最怕的不是样本复杂而是环境没隔离、工具链没对齐、观察点没定好最后跑了一堆命令却说不清样本干了什么。课后练习实验文件的价值恰恰在于它把「可控样本 明确目标 可重复步骤」这三件事凑齐了适合刚入门的安全方向学生、想转二进制分析的开发以及需要给团队做内部培训的工程师。这一篇就按真实动手顺序把环境搭建、静态与动态分析、行为取证、避坑和进阶技巧讲透让你拿到实验文件后能独立走完一遍完整链路。2. 实验环境怎么搭隔离、快照与工具链的三件套恶意代码分析的第一原则是「别在主系统上跑」。很多人第一次做练习时图省事直接在物理机上双击样本结果要么被反虚拟机逻辑识破导致行为不触发要么清理不干净留下持久化项。正确的做法是先搭一个可回滚的隔离环境再谈工具。2.1 虚拟机隔离与快照策略常见做法是用一台宿主系统跑虚拟化平台里面装一台分析用虚拟机。虚拟机网络建议先设成「仅主机」或「内部网络」需要联网抓包时再临时切到 NAT并且抓完立刻切回。装好系统后第一件事不是装工具而是打一个干净快照命名成clean_base。之后每分析一个样本前从clean_base克隆一份新快照分析完直接丢弃。这样做的原因是恶意代码可能修改注册表、释放驱动、写入计划任务靠手动清理几乎不可能干净快照回滚是最省心的后悔药。虚拟机配置上内存给 4GB 起步磁盘 60GB 以上因为动态分析会产生大量日志和内存镜像。CPU 核心数不用太多2 到 4 核即可太多反而可能触发某些样本的反沙箱判断。系统版本建议选一个较老的 Windows 版本做主力再备一个较新的版本做对比因为不同系统上样本的 API 调用路径会不一样。2.2 工具链清单与安装顺序工具不要一次装几十个按分析阶段分组装装完一组打一次快照方便定位是哪个工具引入了干扰。下面这份清单是我常用的最小集合。阶段工具用途静态十六进制编辑器看文件头、节区、字符串静态PE 解析工具看导入表、导出表、节区属性静态反汇编器看汇编逻辑、函数调用动态进程监控看进程创建、模块加载动态文件与注册表监控看持久化与配置写入动态网络抓包看 C2 通信与协议取证内存抓取工具抓运行态内存做字符串与结构分析安装顺序建议先装监控类工具再装分析类工具最后装抓包工具。原因是监控类工具需要驱动装早了如果和后续工具冲突回滚成本低。装完后统一关闭自动更新和云同步避免分析过程中系统自己联网产生噪声流量干扰抓包判断。2.3 网络与时间基准的预处理动态分析前有两件事必须做一是把虚拟机时间调到一个固定值二是记录基线流量。时间固定是因为很多样本会用时间做反调试或触发条件时间乱跳会导致行为不稳定。基线流量是指在没跑样本前先抓 5 分钟包记录系统自身的 DNS 查询和心跳后面分析时把这段流量减掉剩下的才是样本产生的。# 在分析虚拟机内固定时间示例按实际系统调整 date -s 2024-01-01 10:00:00 # 抓取基线流量保存为 baseline.pcap tcpdump -i any -w baseline.pcap -G 300 -W 1这段命令的作用是把系统时间固定并用抓包工具抓 5 分钟基线流量。-G 300表示 300 秒后轮转文件-W 1表示只保留一个文件避免占满磁盘。抓完后把baseline.pcap存到宿主机后面用对比方式过滤噪声。注意抓包接口要选实际联网的那张网卡选错会抓到空文件。3. 静态分析怎么下手从文件指纹到关键 API 的排查顺序静态分析的目标是在不运行样本的前提下尽可能缩小怀疑范围。很多人一上来就丢进反汇编器看汇编结果被几万行代码淹没。正确的顺序是先看文件层面信息再看结构最后才看代码。3.1 文件指纹与加壳判断第一步是算哈希、看文件类型、看熵值。哈希用于唯一标识样本方便后续检索和对比。文件类型不能只看扩展名要用文件头判断真实格式。熵值高通常意味着加壳或加密熵值接近 8 基本可以判定有压缩或加密段。import hashlib def file_fingerprint(path): with open(path, rb) as f: data f.read() # 计算三种哈希便于不同平台检索 md5 hashlib.md5(data).hexdigest() sha1 hashlib.sha1(data).hexdigest() sha256 hashlib.sha256(data).hexdigest() # 读取前两个字节判断文件头 magic data[:2] print(fMD5: {md5}) print(fSHA1: {sha1}) print(fSHA256: {sha256}) print(fMagic: {magic.hex()}) file_fingerprint(sample.bin)这段脚本读取样本并输出三种哈希和文件头。哈希用于标识文件头用于判断真实格式比如4D5A开头是 PE 文件7F45开头是 ELF。参数上没什么可调的注意读取大文件时不要一次性全读进内存练习样本一般不大但养成用分块读取的习惯更好。如果熵值计算出来超过 7.0先别急着反汇编优先做脱壳或解密。3.2 导入表与字符串的交叉验证导入表能告诉你样本用了哪些系统能力字符串能告诉你样本可能访问哪些域名、路径、注册表项。两者交叉验证能快速定位可疑点。比如导入表里出现创建进程、写文件、连网络的 API字符串里又出现一个陌生域名那这个域名大概率是 C2。# 用 strings 提取可打印字符串过滤长度小于 6 的噪声 strings -n 6 sample.bin strings.txt # 统计出现频率最高的字符串快速看重点 sort strings.txt | uniq -c | sort -rn | head -30-n 6表示只输出长度不小于 6 的字符串太短的字符串噪声太大。统计频率是为了把重复出现的路径、域名、互斥体名挑出来这些往往是样本的关键配置。注意有些样本会混淆字符串提取出来是乱码这时候要结合反汇编看字符串解密逻辑不要硬猜。3.3 反汇编阅读的切入点反汇编不要从入口点一路往下读效率太低。切入点通常是导入表里的敏感 API 调用处比如创建进程、写文件、网络连接。找到调用点后往回看参数是怎么构造的往前看调用后的分支判断。这样一段一段啃比通读快得多。阅读时重点关注三类模式一是循环里做异或或加减运算通常是解密二是调用 API 前有大量压栈操作通常是在构造参数三是条件跳转依赖某个全局变量通常是反调试开关。把这三类模式标记出来基本就能还原样本的主要逻辑。4. 动态分析怎么观察进程、文件、注册表、网络四条线动态分析的核心是「跑起来看行为」但看行为不是盯着屏幕而是提前布好监控点让工具替你记录。四条线分别是进程、文件、注册表、网络每条线都要有对应的监控工具和记录格式。4.1 进程行为监控与父子关系还原进程监控要记录进程创建、模块加载、线程创建。重点是还原父子关系因为很多样本会通过父进程创建子进程来隐藏真实行为。比如一个文档样本启动后创建了一个系统进程再由那个系统进程去连网络这时候只看单个进程就会漏掉链路。# 用进程监控工具记录进程创建事件输出到 CSV procmon /Quiet /Minimized /BackingFile procmon.pml # 跑完样本后导出为 CSV 便于分析 procmon /OpenLog procmon.pml /SaveAs procmon.csv这段命令启动进程监控并记录到文件跑完样本后导出 CSV。/Quiet表示静默启动/Minimized表示最小化窗口/BackingFile指定日志文件。导出 CSV 是为了用脚本做过滤和统计比如筛选出所有进程创建事件按父进程分组。注意监控工具本身会产生大量事件跑样本前先清空日志跑完后立刻停止记录避免日志过大。4.2 文件与注册表写入的持久化排查文件监控关注样本释放了哪些文件、写到了哪些目录。注册表监控关注样本是否写了自启动项、服务项、浏览器辅助对象。这两条线要一起看因为持久化通常是「释放文件 写注册表」的组合。排查时重点看这几个位置启动目录、运行键、服务键、计划任务。如果样本写了这些位置基本可以判定有持久化意图。记录时要记下写入的路径、数据内容、时间戳这些是后续清理和写报告的素材。4.3 网络通信抓包与 C2 特征提取网络抓包要抓 DNS 查询、TCP 连接、HTTP 请求。DNS 查询能看出样本想连哪个域名TCP 连接能看出端口和频率HTTP 请求能看出协议格式和 User-Agent。C2 特征通常藏在请求路径、参数名、心跳间隔里。from scapy.all import rdpcap, DNSQR, TCP packets rdpcap(sample.pcap) for pkt in packets: # 提取 DNS 查询域名 if pkt.haslayer(DNSQR): print(DNS:, pkt[DNSQR].qname.decode(errorsignore)) # 提取 TCP 目标端口 if pkt.haslayer(TCP): print(TCP:, pkt[TCP].dport)这段脚本用抓包库读取 pcap 文件提取 DNS 查询和 TCP 目标端口。参数上注意rdpcap会一次性加载整个文件大文件要分块读。提取出的域名和端口要结合基线流量过滤去掉系统自身的查询。如果发现样本用了固定间隔的心跳记录下间隔时间这是写检测规则的重要依据。4.4 内存取证与运行态字符串提取有些样本会把关键配置解密到内存里磁盘上看不到。这时候需要抓内存镜像再从镜像里提取字符串和结构。抓内存要在样本运行一段时间后、行为稳定时抓太早可能还没解密太晚可能已经清理。提取内存字符串后重点找域名、路径、互斥体名、加密密钥。这些内容往往比磁盘上的字符串更有价值因为它们是运行态的真实配置。注意内存镜像很大提取时要限定进程和区域不要全盘扫描否则耗时太长。5. 避坑与常见问题五条血泪经验这一章记录的是我在做练习和带人做练习时反复遇到的坑每条按现象、原因、解决写清楚。5.1 样本不触发行为现象是跑完样本后监控工具里几乎没记录或者只有系统自身活动。原因通常是样本检测到虚拟机环境或分析工具主动休眠或退出。解决方法是先检查虚拟机是否暴露了常见虚拟化标识再检查监控工具是否被样本识别。可以尝试调整虚拟机配置去掉明显的虚拟化特征或者换一个更干净的系统镜像。5.2 抓包文件里全是噪声现象是抓包文件很大但分不清哪些是样本产生的。原因是分析前没抓基线流量系统更新、时间同步、云同步都在产生流量。解决方法是分析前先抓 5 分钟基线分析时用过滤器排除基线里的域名和 IP。另外把系统自动更新和云同步关掉能减少一大半噪声。5.3 反汇编看到一半跟丢现象是读汇编时跳转太多读着读着不知道跟到哪了。原因是没做函数标记和注释纯靠记忆。解决方法是每进入一个新函数先标记用途遇到循环和分支先画个简单草图把关键跳转的条件记下来。不要追求一次读完分段读、分段记比通读有效。5.4 快照回滚后工具失效现象是回滚快照后某些监控工具启动不了或者驱动报错。原因是工具安装时写了系统级驱动回滚后驱动和当前系统状态不匹配。解决方法是装完工具后打一个「工具就绪」快照每次分析从这个快照克隆而不是从最干净的clean_base克隆。这样既保证环境干净又保证工具可用。5.5 报告写不出结论现象是分析做了很多但写报告时说不清样本到底干了什么。原因是分析时没按「行为链」记录只记了零散事件。解决方法是分析过程中就按「进程创建 → 文件释放 → 注册表写入 → 网络连接」的顺序记录每个环节记下证据来源。这样写报告时直接按链条展开结论自然清晰。6. 进阶技巧用脚本把重复劳动自动化练习做多了会发现很多步骤是重复的算哈希、提字符串、过滤抓包、导出进程树。这些步骤完全可以用脚本串起来把时间留给真正的逻辑分析。我一般会写一个分析辅助脚本输入样本路径自动完成指纹计算、字符串提取、基础 PE 信息解析输出一份初步报告。import hashlib import subprocess import os def basic_triage(sample_path, out_dir): os.makedirs(out_dir, exist_okTrue) # 计算哈希 with open(sample_path, rb) as f: data f.read() hashes { md5: hashlib.md5(data).hexdigest(), sha256: hashlib.sha256(data).hexdigest(), } # 提取字符串 strings_out os.path.join(out_dir, strings.txt) with open(strings_out, w, encodingutf-8) as f: subprocess.run([strings, -n, 6, sample_path], stdoutf) # 输出初步报告 report os.path.join(out_dir, triage.txt) with open(report, w, encodingutf-8) as f: for k, v in hashes.items(): f.write(f{k}: {v}\n) f.write(fstrings: {strings_out}\n) print(ftriage done: {report}) basic_triage(sample.bin, triage_out)这段脚本把哈希计算和字符串提取串起来输出一份初步报告。参数上out_dir是输出目录建议每次分析用独立目录避免覆盖。strings命令的-n 6可以根据样本调整如果字符串混淆严重可以降到 4 再人工过滤。这个脚本只是起点后面可以按需加入 PE 节区解析、导入表导出、YARA 规则扫描。自动化不是为了替代分析而是把机械劳动压缩让你有更多时间盯真正可疑的逻辑。验证分析结论是否可靠我习惯用「交叉验证法」静态看到的可疑 API要在动态监控里找到对应事件动态看到的网络连接要在抓包里找到对应流量抓包里的域名要在内存字符串里找到对应配置。三条线对得上结论才站得住。对不上就说明有环节漏了要么是样本有反分析逻辑要么是监控点没布全。最后说个我自己的习惯每分析完一个样本不管结论多简单都写一份不超过一页的笔记记下样本指纹、关键行为、证据来源、没搞清的问题。这份笔记不对外只给自己看。积累多了会发现很多新样本的行为模式在旧笔记里出现过排查速度会快很多。恶意代码分析没有捷径但有积累。希望帮到你。本文还有配套的精品资源点击获取