
简介《计算机病毒原理与防范第2版》实验详细内容是一套面向信息安全专业学生、网络安全从业者及进阶用户的配套实验资源包旨在通过动手实践掌握病毒分析、传播机制、防护策略、系统安全设置、数据恢复与安全法规等关键环节。压缩包内共514个文件大小约39.3MB主要文件类型包括C/C源码、Visual Studio工程配置、编译生成的库与可执行程序、实验报告文档并配以大量编译日志与调试记录便于从源码阅读到编译运行的完整实验流程。目前已有139人学习下载。资源内含PE结构解析、病毒扫描器示例、修改入口表与入口代码等感染方式演示项目可对照教材逐项复现理解恶意代码的构造与查杀思路提升系统防护和数据恢复的实际操作能力。1. 这门课不是让你背病毒的实验包打开的姿势决定了你能学到多少翻开《计算机病毒原理与防范第2版》的实验目录很多人第一反应是找个“实验报告模板”直接抄等到期末答辩被问一句“这个病毒为什么绕过了你的查杀”就当场卡壳。这门课的实验包真正要训练的不是“运行病毒然后截图”而是建立一套从样本分析到防御落地的闭环思维——拿到一个来路不明的PE文件你能说清楚它改了哪些注册表键、写入了哪个启动项、流量发往哪里然后给出针对性的清除方案。这套实验内容适合三类人正在修这门课、需要独立完成实验报告的学生刚接触恶意代码分析的开发者和运维以及想系统补上“攻防视角”这一课的安全爱好者。后面的内容全部围绕实验包中常见的实验模块展开包括实验环境构建、静态与动态分析、查杀对抗、行为取证一路写到参数怎么调、坑在哪里、结果怎么验证保证你看完能照着把实验跑通并且知道自己每一步在做什么。2. 用虚拟机搭一个“中毒不心疼”的实验台沙箱隔离与快照回滚2.1 为什么要坚持在虚拟机里做病毒实验我在带新人做恶意代码实验时第一条规定永远是“物理机禁止运行任何样本”。病毒感染不是电影里的视觉特效它往往静默完成——改写MBR、注入系统进程、释放驱动等你看到弹窗或文件被加密时系统已经处于被控制状态。实验包里的样本虽然大多是可公开获取的教学样本但“教学”不代表“无害”一旦在物理机触发重装系统是最轻的代价内网横向渗透才是真正的灾难。虚拟机的核心价值在于两层隔离。第一层是CPU级隔离VMware或VirtualBox的虚拟机监控器将客户机指令限制在独立的内存和CPU上下文中虚拟机内的进程无法直接访问宿主机内存第二层是网络隔离通过NAT或仅主机模式虚拟机对外部网络的访问完全可控。你可以在虚拟机里放开手脚观察样本行为同时保证宿主机不暴露在风险中。实验包要求的环境配置通常不复杂我一般建议分配2个虚拟CPU、2GB以上内存、40GB动态磁盘操作系统选用Windows 7 x64或Windows 10 LTSC。选择Windows 7不是因为它先进而是它的内核结构相对简单注册表和进程机制的改动能被各类监控工具完整捕获不会被系统自身的新特性干扰判定。2.2 快照就是病毒实验的“后悔药”快照机制是虚拟化平台给恶意代码分析提供的最佳礼物。它记录虚拟机某一时刻的完整磁盘状态和内存状态恢复时能精确回到该时刻。在运行样本前打一个“干净快照”实验结束后无论系统被折腾成什么样一句话就能还原。我常用的快照策略是“两层快照”安装好操作系统并完成基础配置后打一个“基础快照”每次开始一组新的实验前再打一个“实验前快照”。这样如果单个实验做砸了恢复“实验前快照”即可不用重新配置系统环境。VMware和VirtualBox都提供了命令行快照工具适合批量管理和自动化场景。下面这组命令是VMware Workstation Pro的常用操作# 列出当前虚拟机的所有快照 vmrun listSnapshots D:\VMs\Win7_Lab\Win7_Lab.vmx # 创建一个名为lab-before-ransomware的快照 vmrun snapshot D:\VMs\Win7_Lab\Win7_Lab.vmx lab-before-ransomware # 恢复到指定快照-t参数指定恢复到当前快照并幂等处理 vmrun revertToSnapshot D:\VMs\Win7_Lab\Win7_Lab.vmx lab-before-ransomware这段命令的逻辑是先把当前虚拟机的快照列表打出来确认基准点然后新建快照最后在需要回滚时直接恢复。snapshot命令先于样本执行确保样本运行前系统处于已知良好状态。参数-t在部分版本中用于指定快照类型无特殊需求时默认即可。VirtualBox的对应命令稍有不同# 创建快照 VBoxManage snapshot Win7_Lab take clean-baseline --description 系统纯净状态 # 恢复快照 VBoxManage snapshot Win7_Lab restore clean-baseline使用快照时有一条血泪经验一定不要在“样本已运行但尚未分析完”时覆盖快照。快照一旦覆盖之前记录的系统异常状态就消失了你只能从头再复现一次样本行为浪费时间不说有些样本的行为具有随机性第二次可能不触发。2.3 实验网络的三种模式与流量观察窗口病毒实验的网络配置直接决定两层东西一是样本能否顺利运行有些样本需要联网下载第二阶段载荷二是你能观察到多少网络行为。实验包里的样本按网络行为可分为三类——完全离线型、触发后联网型、常驻通信型对应不同的网络策略。从落地角度我把网络模式按风险和控制粒度做个对比网络模式虚拟机访问外部网络宿主机可达性典型用途风险等级NAT可以经宿主机转发虚拟机外发可见观察HTTP/DNS外联中仅主机不可以虚拟机与宿主机互通静态分析和文件传输低自定义虚拟网络可控规则可控模拟内网环境中高默认情况下我推荐NAT模式。虚拟机里的样本发起网络请求时流量会经过宿主机VMnet8网卡转发此时在宿主机上用Wireshark抓包就能看到样本与外部IP的完整通信过程。仅主机模式适合不需要联网的样本——比如只做静态分析或只观察文件系统改动这时切断外网等于给样本上了锁链。运行联网型样本前建议先在虚拟机里打开procmonProcess Monitor并设置网络过滤条件然后启动样本观察它访问了哪些域名和IP。不要急着拦截第一次运行的目的是“看”看清楚了再考虑限制。3. 静态与动态分析的基本功用文件指纹和行为快照还原样本意图3.1 静态分析的第一步不是“运行”而是“别运行”拿到实验包里的exe或dll样本新手最容易犯的错误是双击运行。正确顺序是先把样本当“嫌疑犯”审一遍——不做任何执行只从文件本身提取信息。这个阶段使用的工具未必需要昂贵的商业套件系统自带的命令和几个开源小工具就能完成大部分工作。我在静态分析阶段必做的四件事计算哈希、查看文件类型、提取字符串、解析PE头。这四步层层递进——哈希用于唯一标识样本和查VirusTotal文件类型用于确认是不是PE文件字符串能暴露样本的路径、域名、注册表键PE头则揭示导入函数、节区、数字签名等关键结构。下面这组命令在Windows的cmd或PowerShell里直接可用# 计算SHA-256哈希用于样本定位和威胁情报查询 Get-FileHash .\sample.bin -Algorithm SHA256 | Format-List # 查看文件头信息确认真实文件类型 Format-Hex .\sample.bin | Select-Object -First 4 # 提取文件中的ASCII和Unicode字符串 # 需要Sysinternals工具包里的strings64.exe .\strings64.exe -a .\sample.bin strings_output.txt # 查看PE文件的DOS头和NT头关键字段 # 使用dumpbinVisual Studio自带或pefile库 dumpbin /headers .\sample.binGet-FileHash输出的SHA-256值是样本的唯一身份证记录到实验报告中是基本要求。Format-Hex看文件前四个字节——正常PE文件的起始字节为4D 5AMZ如果看到其他字节说明文件可能被处理过或根本不是PE。strings64.exe的-a参数让工具扫描整个文件而不只扫描特定节区这样可以找出藏在资源段或附加数据中的字符串。然后是重头戏PE结构解析。这一步建议直接用Python的pefile库写脚本输出信息比工具默认展示的更容易理解import pefile pe pefile.PE(sample.bin) # 展示导入函数表看样本调用了哪些系统API print( Imported DLLs and Functions ) for entry in pe.DIRECTORY_ENTRY_IMPORT: print(f[{entry.dll.decode()}]) for imp in entry.imports: print(f {imp.name.decode() if imp.name else ordinal str(imp.ordinal)}) # 展示节区信息重点关注节区名称和熵值 print(\n Sections ) for section in pe.sections: name section.Name.rstrip(b\x00).decode(errorsreplace) entropy section.get_entropy() print(f{name}: virtual_size{section.Misc_VirtualSize}, entropy{entropy:.2f})这个脚本的输出分两部分。导入表列出样本用到的DLL和函数——比如看到CreateRemoteThread和VirtualAllocEx组合几乎可以断定是注入类行为看到CryptEncrypt和InternetOpenUrl组合则很可能指向勒索或数据外传。节区信息中熵值大于7的节区通常指示加密或压缩内容——正常程序编译出来的代码节熵值在5.5到6.5之间异常高熵节往往是加壳或加密的痕迹。3.2 动态分析让样本在监控下“表演”静态分析能给出“它可能想干什么”动态分析则是让样本真正跑起来观察它实际干了什么。实验包中的动态分析模块通常包含注册表监控、进程行为监控、文件系统监控三块对应的工具组合是procmon Wireshark 火绒剑或Process Explorer。在启动样本前我先给procmon设置好三类过滤规则操作类型限定为RegSetValue、RegCreateKey、WriteFile、CreateFile、Process Create和Network Operation路径排除系统正常活动的噪音路径比如C:\Windows\System32下的部分通用操作进程名限定为样本自身的进程名。这样procmon记录到的行为日志就不会被系统自身的刷屏操作淹没。启动样本后等待2到3分钟让样本完成初始化然后停止捕获并导出日志。导出为CSV后用Excel做透视表分析或者用Python脚本提取关键行为链。下面这段脚本能从procmon导出的CSV中快速提炼出高价值行为import csv HIGH_VALUE_KEYS [ rSoftware\Microsoft\Windows\CurrentVersion\Run, rSoftware\Microsoft\Windows\CurrentVersion\RunOnce, rSystem\CurrentControlSet\Services, ] with open(procmon_log.csv, newline, encodingutf-8) as f: reader csv.DictReader(f) for row in reader: operation row[Operation] path row[Path] # 注册表持久化位置是高危信号 if operation in (RegSetValue, RegCreateKey) and any( key.lower() in path.lower() for key in HIGH_VALUE_KEYS ): print(f[PERSISTENCE] {operation}: {path} {row[Result]}) # 写入可执行文件到系统目录 if operation WriteFile and path.lower().endswith((.exe, .dll, .sys)): print(f[DROP] WriteFile: {path}) # 进程注入行为目标进程非系统正常进程 if operation Process Create and Temp in path: print(f[PROCESS] {row[Process Name]} - {path})这段脚本把procmon日志中三类关键信号提出来写入启动项的注册表操作、在系统目录释放可执行文件、从临时目录创建进程。脚本本身不复杂但它的价值在于帮你从几十万条噪音记录中快速锁定异常行为——手工翻日志找这些信号会花掉你大量时间而且容易漏。看到[PERSISTENCE]输出时实验报告里就该写“样本通过修改Run键实现开机自启”而不是模糊地写“该样本具有持久化能力”。3.3 内存分析动态分析的“最后一层皮”实验包中进阶一点的实验会要求做内存转储分析。原因是某些样本的恶意行为不落地到磁盘——它们直接在被注入的进程中以内存形式存在。这种情况下磁盘看是干净的但内存已经沦陷。常见做法是用Mimikatz或DumpIt抓取进程内存镜像再用Volatility分析。Volatility的关键命令如下# 识别镜像对应的操作系统版本 volatility -f memory.dmp imageinfo # 列出进程列表查找异常进程 volatility -f memory.dmp --profileWin7SP1x64 pslist # 检查网络连接查找可疑外联 volatility -f memory.dmp --profileWin7SP1x64 netscan # 扫描隐藏进程对抗进程伪装 volatility -f memory.dmp --profileWin7SP1x64 psscanimageinfo是所有后续分析的前提它的输出会告诉你镜像对应的操作系统版本和profile名称后续命令必须指定这个profile才能正确解析。netscan输出的TCP或UDP连接列表与Wireshark抓包对照能确认样本是否还在与外部保持通信。psscan的价值在于检测通过DKOM直接内核对象操作隐藏的进程——普通pslist看不到psscan直接从内存池中扫描进程对象隐藏的进程也无所遁形。内存分析属于进阶操作实验包里未必每个实验都要求但如果你打算在答辩时秀一手“我不仅做了行为分析还做了内存取证”这组命令值得提前跑通。4. 查杀对抗与免杀实验从“被杀”到“理解杀”的过程4.1 免杀实验的本质不是攻击是理解查杀的盲区实验包里有一类实验让不少人困惑为什么要求我们做“免杀”如果目标是防范病毒为什么还要教如何让病毒躲过查杀我的理解是——不了解查杀引擎的判定逻辑就无法真正写好查杀规则或加固主机。一个只知道“用杀软扫描”的人面对杀软报不了毒的样本时束手无策而做过免杀实验的人知道特征码定位、加壳混淆、行为拆分这些技术正对应了查杀引擎的三个弱环静态特征匹配、文件结构扫描、行为序列关联。实验包里的免杀实验通常限定在“修改样本特征以规避特征码查杀”这一层面不涉及真正的漏洞利用或持久化对抗。你可以把它理解成一个“白帽走查”——通过修改样本的字节内容让病毒查杀引擎无法将文件与已知病毒库中的特征匹配。4.2 特征码定位找到那个让杀软“认脸”的字节区间特征码是杀软比对文件时使用的唯一标识片段它可能是一个字符串、一段汇编指令序列或者某个特定结构。定位特征码的常见手段是“二分法”——把样本切成若干段逐段测试哪一段被查杀然后缩小范围。手工做这件事很痛苦我一般用Python写一个自动替换脚本来完成粗定位import hashlib import os # 读取样本并做切分 with open(sample.bin, rb) as f: data f.read() chunk_size 512 chunks [data[i:ichunk_size] for i in range(0, len(data), chunk_size)] # 将每块数据替换为0x00然后计算哈希用于识别 for idx, chunk in enumerate(chunks): temp_data bytearray(data) start idx * chunk_size temp_data[start:startchunk_size] b\x00 * len(chunk) temp_path fpatched_{idx}.bin with open(temp_path, wb) as f: f.write(temp_data) # 这里不直接调用杀软而是记录每个变体的哈希供自动化测试 sha hashlib.sha256(temp_data).hexdigest() print(fChunk {idx:03d}: offset{start:#010x}, sha256{sha[:16]}...)这个脚本的逻辑是将样本按512字节切块逐一将某一块用零字节替换生成一个变体文件并计算哈希。实际检测时需要你把每个patched_*.bin放到装有杀软的测试机上扫描记录哪些变体不再被查杀。如果一个变体的第N块被替换后杀软不再报警说明特征码就在这一块中。定位到特征码后修改方式因特征类型而异。如果是字符串特征直接改字母大小写或用等价同义词替换如果是汇编指令特征用功能等效的指令序列替换——比如把mov eax, 0改成xor eax, eax效果相同但字节不同。这里有一条实操经验不要只改一处至少改三处以上否则杀软升级特征后很快会重新检出。4.3 加壳与脱壳为什么实验报告里必须写清“壳”的类型加壳实验是另一个高频模块。壳的本质是用一段解密程序包裹原始代码运行时先解密再执行。加壳后的样本静态分析几乎看不到有效字符串和导入表动态分析也需要先等自解密完成。实验包里通常要求你用UPX、VMP或Themida给样本加壳再观察杀软和工具的反应。我在指导学生做加壳实验时经常强调一个点加壳不是给样本“穿上隐身衣”而是把恶意逻辑从一个显式的文件内容变成一个动态的解密过程。杀软对加壳样本的处理方式有两种直接报“可疑”或尝试脱壳后再报毒。因此实验报告若只写“加壳后杀软不查杀了”是不够的——你需要说明杀软是不查杀了还是报为Heuristic启发式类型还是脱壳后依然杀。UPX加壳的命令极简单适合教学演示# 对样本进行UPX压缩/加密处理 upx -9 -o packed_sample.exe sample.bin # 验证壳信息 upx -t packed_sample.exe-9表示最高压缩级别-o指定输出文件名。注意UPX加壳并不会改变文件的入口点指向解密代码的方式但upx -t能验证壳是否完整——测试失败说明壳被破坏或样本本身不支持加壳。实验报告里应该同时记录加壳前后文件大小、入口点偏移、节区数量这三个指标它们能直观反映壳的加壳强度。加壳对抗的是静态查杀但现代杀软早已加入动态行为查杀层——样本运行时一旦出现文件遍历、注册表写入和网络外联等行为序列即便没有任何静态特征也会触发拦截。这就解释了为什么免杀实验越做越深入后结论会落回“行为检测才是查杀的终局手段”。4.4 免杀实验中的伦理边界写到这里必须停下来说清楚一条红线免杀实验的全部意义在于理解查杀引擎的工作原理、掌握特征提取方法用于提升防御方能力——比如给杀软补充特征、给EDR调优检测规则、给蓝队做攻防演练。如果读者学完这套内容后去改造真实恶意样本、绕过企业安全防护那不仅偏离了课程设计意图还可能触犯法律。我的个人习惯是做完免杀实验后立即重启虚拟机并恢复快照样本分析产生的临时文件一律不进宿主机目录。5. 避坑指南五类实验翻车现场与排查思路5.1 虚拟机和宿主机之间“文件传不出来”现象在虚拟机里分析完样本导出报告或日志时发现共享文件夹无法访问提示权限不足或者直接找不到共享路径。原因共享文件夹功能依赖VMware Tools或VirtualBox Guest Additions。如果虚拟机内的安全软件把Tools的某些组件禁用了或者系统更新后Tools版本与虚拟机监控器不匹配共享就会失效。解决不用共享文件夹改用HTTP服务或FTP中转。在宿主机上起一个临时HTTP服务虚拟机内用curl或浏览器下载所需文件。反向传输时在虚拟机里起服务、宿主机来取。这种方法不依赖Tools兼容性最好。或者尝试重装Tools但有时安全策略会再次干扰。5.2 样本一运行系统直接蓝屏现象双击样本后虚拟机瞬间蓝屏重启后系统异常或直接无法引导。原因样本触发了内核级行为——加载恶意驱动或修改关键内核结构超出了虚拟机的容错能力导致系统崩溃。这种情况在小内存配置小于1GB或精简系统镜像上更常见。解决第一步不要慌从“基础快照”恢复即可。第二步调整虚拟机内存到2GB以上并关闭虚拟机的“内存预留”选项。第三步改用安全的内存转储配置——在系统属性中设置“小内存转储256KB”蓝屏时生成的minidump文件可以交给调试分析。如果反复蓝屏且无法分析行为可以考虑换一台配置更高的机器做动态分析或者改用“仅主机模式”减少外部干扰。5.3 杀软把实验工具和样本一起杀了现象准备分析工具的阶段procmon或Wireshark突然被系统自带的安全中心查杀复现实验时刚拷贝进来的样本还没运行就被隔离了。原因默认安全策略过于激进将“可疑文件”和“黑客工具”等同处理。这与样本本身的恶意性无关是安全产品的“宁可错杀”策略在起作用。解决在虚拟机内明确添加排除项——把实验工具安装目录和样本存放目录都加入Windows Defender的排除列表。具体操作是“设置—更新和安全—Windows安全中心—病毒和威胁防护—管理设置—排除项”。如果你用的是第三方安全软件同样在其白名单中添加排除路径。这是实验环境的正常配置不需要在实验报告中掩盖。5.4 快照恢复后网络不通现象从快照恢复后虚拟机内显示“未识别的网络”或网络适配器没有分配到IP但快照创建前网络是正常的。原因快照恢复改变了虚拟机的MAC地址——某些虚拟化平台在恢复快照时重新分配MACWindows会把新MAC对应的网络视为陌生网络并重置防火墙配置。同时NAT网络服务可能在快照恢复过程中被宿主机重置。解决先确认VMware NAT服务是否在运行——Windows服务管理器里找VMware NAT Service未运行则手动启动。再删除并重建虚拟机的网络适配器重新设置为NAT模式。以上两步能解决九成问题。剩下的一成是Windows防火墙需要重新允许相关协议——保险起见直接在虚拟机内关闭防火墙仅限实验环境。5.5 样本怎么等都“不出事”实验做不下去现象按实验指导书操作运行样本后等了十分钟procmon里一个异常行为都没有网络连接也干干净净实验没法收尾。原因两根常见原因。第一是样本存在“环境检测”机制——它检测到虚拟机环境VMware Tools进程、虚拟网卡MAC、特定CPU指令后主动进入睡眠或退出这是恶意软件规避分析环境的常见手段。第二是运行缺少参数——部分样本需要配置特定的命令行参数或运行条件才能触发恶意行为。解决先说环境检测的应对——安装VMware Tools时选择“不自动运行”让样本难以通过进程名检测到虚拟化或者改用“影子服务”工具隐藏虚拟环境特征。再说参数问题——观察样本导入表中的GetCommandLineA函数如果存在说明样本可能依赖命令行参数用cmd.exe带不同参数运行样本配合procmon观察行为差异。如果以上都试了依然无行为去查样本的编译时间和数字签名——可能是准备阶段的下载器样本需要配合特定时间或远程服务器响应才能激活。6. 行为日志的验证闭环用时间轴还原“查杀结论”是否站得住做完实验不等于实验报告成立。我见过大量报告写着“样本会通过Run键持久化”但对应的procmon时间戳和行为序列截图对不上。要避免这种逻辑漏洞最后一步必须做行为日志的时间轴重建——把进程创建、文件写入、注册表修改、网络外联四类事件按时间排列验证它们构成一条有逻辑链条的攻击序列。实操方法是用Python解析procmon导出的CSV按进程PID和时间戳聚合事件生成带时间轴的执行摘要import csv from collections import defaultdict timeline [] with open(procmon_full.csv, newline, encodingutf-8) as f: reader csv.DictReader(f) for row in reader: # 过滤掉系统进程的刷屏记录只保留样本及其子进程 if row[Process Name] in (sample.exe, cmd.exe, powershell.exe): timeline.append({ time: row[Time of Day], pid: row[PID], operation: row[Operation], path: row[Path], result: row[Result], }) # 按时间排序并输出关键行为 timeline.sort(keylambda x: x[time]) print( 关键行为时间轴 ) for event in timeline: if event[operation] in ( Process Create, RegSetValue, WriteFile, TCP Connect, UDP Send ): print(f{event[time]} | PID {event[pid]} | {event[operation]} | {event[path]} | {event[result]})脚本做的事情是过滤出样本及其子进程的事件并且只保留五类关键操作——进程创建、注册表写入、文件写入、TCP连接、UDP发送。输出结果就是一个时间轴你能直观看到“进程启动→写入文件→修改注册表→发起外联”这一完整链路。实验报告里贴出这段时间轴再配合分析结论说服力远大于单张截图。有了时间轴还需要做一件事验证查杀结论的“可复现性”。恢复快照到干净状态至少再跑一次样本对比两次时间轴是否一致。如果两次启动的时间轴差异很大说明样本存在反分析的时间延迟或随机化行为这种情况要在实验报告中明确标注“样本行为存在不稳定性”而不是强行下结论。时间轴重建也是后续做防御方案的基础。当你清楚了样本的行为顺序你就能针对第一个触发点做针对性拦截——不需要等样本完成全部行为链在第一步写入文件或修改注册表时就阻断这也是EDR这类产品“终端检测响应”的核心思路不依赖特征识别而是依赖行为链命中。最后说一个我自己的教训早年做实验中招过“样本确实被查杀了但分析结论全部跑偏”的情况。原因是没有把杀软的查杀记录纳入同一时间轴——杀软可能在样本运行后第10秒才检测并阻断而我的procmon记录的只是样本前10秒的行为后面的行为全部没有发生。后来我习惯在启动样本的同时记录杀软的日志两边的时标对齐分析结论才真正站得住。做实验做到这份上答辩时被问到“你的结论凭什么成立”心里才有底。希望你能在实验清单之外也把这份严谨的验证习惯一起带走做技术的路才能越走越扎实。本文还有配套的精品资源点击获取