大语言模型已经成为逆向工程中颇为得力的助手:它们能够清理反编译器的输出、为函数提供更恰当的命名、就陌生代码回答有针对性的问题,并编写小型辅助脚本。我在 REcon 2024 的演讲 The Future of Reverse Engineering with Large Language Models 中讨论过其中一些 LLM 辅助逆向的应用场景。不过到目前为止,模型大多仍处于辅助角色:由我们来决定哪些线索值得跟进、下一步要检查什么,以及在哪里需要投入更深入的逆向工作。
真正改变这一格局的是智能体 (agent) 的兴起。一旦模型能够在循环中使用工具、检查中间结果、并自主推进分析,它就可以接管工作流中富有意义的部分。我们已经在诸如求解 CTF 挑战、生成模糊测试 harness、恶意软件分析,以及漏洞生成实验等任务中看到了这一趋势。不过,尽管智能体本身已经颇为有用,一旦获得合适的环境、工具与引导,它们的效能还会显著提升。
在本文中,我们将展示如何在实践中构建这样一条智能体化的恶意软件分析流水线。我们将通过一个具体的恶意软件案例研究来加以说明:在该样本中,部分功能可以通过字符串和 API 轻易识别,而另一些部分则需要更深入的分析才会浮现。我们首先介绍智能体工作流的基本组成要素,接着考察一个强大的通用智能体仅凭自身能在样本中发现些什么,最后将其与嵌入到结构化工作流中的同一智能体进行对比。如此一来,我们就能看清:目前已经奏效的是什么、流水线带来了哪些改进、又遗留了哪些局限。
包含分析环境、流水线及样本配置的配套代码仓库,可在此处获取。
智能体
就本文而言,我们可以采用一个简单的定义:智能体是一个能够在循环中调用工具以达成目标的 LLM。它不再只是在一次提示中给出单次回答,而是能够审视工具输出、决定下一步动作、执行下一步,并持续推进直至得出结果。这正是从 LLM 辅助逆向工程走向 智能体化工作流的关键转变。
其基本循环非常直接:模型接收任务、选择工具、查看结果,然后不断重复这一过程,直到能够给出最终答案。用简化的伪代码来表示,这样一个逆向工程智能体大致可以写成下面的样子:
# define toolstools = {"strings": strings,"disasm": disasm,"decompile": decompile,}# set LLM instructionsmsgs = [ {"role": "system","content": ("You are a reverse-engineering agent. ""Use tools to analyze binaries." ), }, {"role": "user","content": ("Figure out what function sub_401230 does." ), },]# agent loopwhileTrue: r = llm(msgs, tools=tools)if r.type =="final":print(r.content)break result = tools[r.tool_name](**r.tool_args) msgs += [ r, {"role": "tool","name": r.tool_name,"content": str(result), }, ]该智能体可以获取字符串、反汇编以及反编译器输出,决定接下来调用哪个工具,观察执行结果,并迭代地完善自己的理解,直到能够回答问题。即便是这样一个简单的设置,也已足以把模型从被动助手转变为主动的分析循环。
虽然从零实现这种循环有其充分的理由,OpenAI 与 Anthropic 也分别提供了直接展示该方式的官方示例和文档,但在实际中,许多人会选择使用命令行智能体,例如 OpenAI 的 Codex CLI、Anthropic 的 Claude Code,或者像 opencode 这样的开源智能体。这些工具已经替我们处理了交互循环、工具执行以及会话状态。
对于逆向工程来说,接下来的问题是:如何接入合适的分析工具,以及如何引导整个工作流。模型上下文协议 (Model Context Protocol, MCP)在其官方规范中规定了智能体发现并调用外部工具的标准方式。借助 MCP,智能体可以查询反汇编器、收集元数据、检查交叉引用,或者执行辅助脚本,而无需我们手动来回复制结果。诸如 GhidraMCP 与 ida-pro-mcp 之类的项目,直接把这种集成带给了 Ghidra 和 IDA Pro。
而 智能体技能 (Agent skills)则是面向智能体、可复用、针对特定任务的工作流。它们的主要作用,是告诉智能体应当如何处理某项任务。在实际中,一个 skill 可以包含工作流、辅助脚本、文件模板、示例,以及对输出的具体期望。这种模式适用于许多逆向工程任务:对于 crackme,我们可能希望智能体先识别出关键的输入校验和成功路径,然后再着手对二进制进行打补丁;对于混淆代码,我们可能希望它先对保护机制进行分类、判定它在二进制中出现的位置和方式,再据此推导出合适的去混淆工作流与工具策略;在恶意软件分析中,我们可能希望智能体先收集广泛的证据,例如字符串与 API 导入,识别出最相关的关注点,然后再到反汇编器中检查其周围的代码区域。
然而,即便有了工具接入和工作流引导,也仍未解决无结构的智能体运行所面临的主要现实瓶颈:_上下文窗口_。这是智能体在一次会话中能够保留的临时信息量,包括聊天历史、工具输出、笔记以及中间观察。在逆向工程中,这一窗口很快就会被填满。大量的反汇编或反编译器输出,尤其是针对大型函数或一组相关函数,就已经能消耗掉相当一部分可用上下文。一旦上下文过大,智能体通常会将其压缩为摘要。其后果是:细节可能丢失、分析方向可能漂移、工作可能被重复,或者智能体干脆就迷失了方向。
为了应对这种受限的上下文,实际中有两个手段尤其有用:子智能体与规划。借助 子智能体 (subagents),主智能体可以把聚焦的工作交给一个拥有自己上下文窗口的子智能体去处理,例如分析单个函数,或者追踪某个字符串的引用。Anthropic 在文档中明确将这一模式称为 subagents,OpenAI 则以 multi-agent orchestration 的形式讨论了类似的委派结构。_规划 (planning)_ 解决的则是同一问题的另一面:它并不增加智能体的上下文,但能帮助它更有意识地花费上下文。例如,Claude Code 显式提供了 Plan Mode,在该模式下,智能体先用只读操作探查问题,梳理出需要收集哪些证据、哪些线索值得跟进。
不过,无论是子智能体还是规划,都没有解决根本问题。一旦上下文被压缩,智能体仍可能丢失先前的发现,因为它没有 _持久化记忆_、没有可供恢复的稳定笔记,也没有可以可靠地继续推进的工作流。
铺垫至此,接下来我们就来看看,仅凭工具接入,一个强大的智能体能做到些什么。之后,我们再围绕同样的设置构建一条流水线,考察这能在多大程度上改变分析的深度与可靠性。
基线:无结构的智能体化恶意软件分析
为了感受一下,一个强大的通用智能体在无人帮助的情况下究竟能做到些什么,我们从一个简单的设置开始:直接接入反汇编器,但不提供针对任务的工作流、不维护持久化的案例文件,除分析提示之外也不再附加任何额外引导。换句话说,智能体可以驱动工具,但调查的组织方式得由它自己来决定。这种设置在实际中已经颇为有用,我们应能期望它给出像样的初步分流和一些具体的线索。更有意思的问题是:一旦样本需要更深层次的还原,它会在哪里开始失去推进力。
作为我们的测试用例,我们使用德国 "Staatstrojaner"(联邦木马)案例中的 mfc42ul.dll,该案例由混沌计算机俱乐部 (Chaos Computer Club, CCC) 公之于众。这一样本相当合适:它的部分功能仅凭字符串、导入表以及对代码的快速浏览就比较容易识别,例如截屏、Skype 拦截、持久化以及隐蔽通信。但它同时也包含一些较深的逻辑,在浅层分析中很难还原,包括与进程相关的激活、命令分发、协议细节、硬编码的 C2 信息,以及静态嵌入的 AES 密钥。这正是它作为测试用例的价值所在:既能让我们判断智能体是否发现了有价值的线索,也能看出分析在深度上究竟走到了哪一步。
在最初的运行中,我们使用 OpenAI 的 Codex CLI,搭配 gpt-5.4 xhigh,并让它接入我提供的无头 Binary Ninja MCP 服务器 binary-ninja-headless-mcp。然后我们要求该智能体通过 MCP 服务器分析样本,并产出一份关于该恶意软件、其特性以及对应代码位置的详细概览。此时,智能体已具备检视这份二进制文件并自行驱动分析所需的一切:
› Analyze the malware in examples/samples/mfc42ul.dll Give me a detailed overview of the sample's functionality and features, together with the corresponding code locations. Use the MCP server to perform the analysis.第一个有用的观察是:智能体并不会随机行事。即便没有额外的工作流引导,它也会从一个相当合理的分流策略入手:打开样本、收集高层元数据、从字符串和导入中识别可能的行为,然后顺着这些线索深入到代码之中。下面这段摘录展示了运行起步时的样子:
• I'm analyzing examples/samples/mfc42ul.dll with the Binary Ninja MCP tools.• Updated Plan └ Static malware triage and behavior reconstruction for the DLL using Binary Ninja MCP. □ Open the DLLin Binary Ninja and collect high-level metadata. □ Identify likely behavior clusters from strings/xrefs. □ Trace the main execution paths andmap capabilities to concrete code locations.• Called └ binary_ninja_headless_mcp.session.open({...}) ok session_id=...随着运行继续推进,这一模式始终保持可见:先广泛收集元数据,再以可疑的字符串和导入为切入点,然后才逐步对代码进行更深入的检查。
• The file is a 32-bit PE DLL with a large code surface, so I'm doing a fast triage pass before drilling into behavior. I'm collecting exports, imports, and structural metadata now, then I'll pivot off suspicious strings and entry-point code.这已经是一个相当有用且合理的起点。智能体并非盲目猜测,而是以有条理的方式使用工具,并遵循一套合乎情理的初始工作流。但与此同时,局限也已显现:分析主要由那些显而易见的切入点驱动,例如字符串、导入以及表层结构。这对初步分流而言往往已经足够,但未必足以还原样本背后更深层的逻辑。
经过大约 15 分钟、268 次工具调用之后,智能体给出了样本的第一份高层摘要。该结果对初步分流来说已经相当有用。智能体:
识别出释放的驱动 winsys32.sys、相应的安装逻辑以及驱动设备\\.\KeyboardClassC,并把它们与sub_1000e8a0、sub_10003a40等函数关联起来,注意到与 Skype 相关的标记和目标进程名,并将其与 sub_10007490附近的控制逻辑联系起来,还原了 sub_1000ead0中的代理发现逻辑,包括基于注册表对 Internet Explorer 代理设置的处理,在 sub_10006790中识别出基于 HTTPCONNECT的代理感知出站传输,以及协议标记C3PO-r2d2-POE,并在 sub_1000d470附近发现了一条次级载荷路径,包括临时文件的暂存、执行以及随后的清理。
这对初期分析而言已是显著的提速:智能体产出了样本特性的高层概览,并把它们映射到具体的代码位置。但与此同时,结果仍相当浅显。它并未识别出加密相关的代码、未还原硬编码密钥,也未重建更深层的协议逻辑。换句话说,这是一份不错的初步分流,但还称不上深入分析。
另一个实际问题是:这次运行几乎耗尽了可用的上下文窗口。到末尾时,只剩下一小部分上下文可用。这让整个设置变得脆弱:即便智能体找到了有用的线索,一旦调查规模变大、或者需要对相关代码反复深挖,它也很难把这些发现保留下来并加以扩展。大段的反汇编和反编译器输出会迅速吞噬上下文,而一旦先前的发现被压缩成摘要,细节就很容易丢失。
因此,这种基线设置已经有所助益,但主要还是停留在分流层面。它把我们指向相关的功能、还原了若干显见的特性,并为人工检查提供了具体的切入点;但它尚未给出对该恶意软件内部组织方式的更深入还原。
为了判断这究竟是 Codex 特有的局限,还是一种更普遍的模式,我们可以用另一个强大的智能体重复同一实验。当采用 Anthropic 的 Claude Code,搭配 Opus 4.6与 high effort时,整体情况略有改善。在大致相同的时间内,Claude 还原出一些额外的细节:
音频录制流水线,包括双声道采集以及相关的 waveIn*处理,反分析逻辑中基于 SNMP 的主机指纹识别,以及随之而来的 VMware MAC 前缀过滤,以及 运行时读取 DLL 自身文件名的逻辑,这暗示样本会检查自己是否仍以预期的模块名运行。
但与此同时,整体格局并未改变:Claude 同样给出了一份不错的初步概览,但仍未真正还原出样本更深层的逻辑。
总体而言,这些实验表明:更换模型只能带来有限的帮助,并不能解决主要问题。正如我们将看到的,真正重要的,是智能体是否拥有清晰的引导、结构化的计划,以及在上下文窗口被重置之后仍能继续推进分析的方法。下面我们就来看看,如何把这些要素融入到工作流之中。
智能体化分析流水线
前面的实验已经显示出了工作流需要解决的主要局限。一个能够接入二进制分析引擎的强大通用智能体,可以产出有用的初步分流:它能还原可见的功能、找到合理的切入点,并把显见的行为映射到代码位置。在我们的例子中,这已经足以识别出一些较容易发现的特性,但还不足以触及加密代码、更深层的协议逻辑,或者样本的内部组织。与此同时,这次运行已经接近了上下文窗口的极限。
为了解决这些问题,我们需要一种工作流,它既能为智能体提供清晰的分析结构,又能给它一份可以反复回看的持久化外部记忆。归根结底,我们的目标是让分析更具可重复性、可恢复性,并且能够走得比无结构的工具驱动式探索更深,同时不必无谓地耗尽上下文窗口。基于此,我们可以为该工作流定义如下四项设计目标:
- 以广泛的指纹识别为起点。
智能体应当首先收集大量信号 -- 字符串、API 导入、符号名、加密相关指标、关注点以及其他易于提取的工件 -- 在陷入更深的分析之前,先勾勒出样本的高层轮廓。 - 将原始证据与高层推理分离。
原始工件 (例如字符串)、提取出的信号、规划结果、假设以及解读不应混在一起。这样智能体就能基于结构化摘要工作,同时仍能访问底层证据。 - 遵循阶段分明的流程。
工作流应当明确写出:已经完成了哪些工作、接下来该做什么、哪些问题仍未解决,以及每个阶段预期产出什么。在实现上,各阶段由模板、预期的产出工件以及轻量级校验器来定义,后者会在工作流继续之前检查所需文件和字段是否齐备。这能确保工作流产出明确的中间工件,后续阶段可以直接基于这些工件构建。 - 将状态外化到磁盘。
笔记、工件、进度、假设以及报告都应写入持久化存储,这样即使上下文窗口被填满,分析也能继续进行。
我们围绕一个分阶段的工作流来组织智能体,以达成上述目标。这一工作流大致映射人类分析师处理恶意软件样本的方式:先收集字符串、API 导入和签名等广泛信号;然后勾勒出样本的大致轮廓;形成初步假设;对最有希望的线索进行优先级排序;最后通过更深入的分析对这些假设加以验证或证伪。为使该工作流可控,我们将职责 分离到三个角色之中:编排者 (orchestrator)、规划者 (planner) 与汇报者 (reporter)。
编排者负责协调执行、初始化案例目录、检查工件的完整性,并管理阶段之间的过渡。_规划者_ 把中间证据转化为假设、优先级以及具体的深入分析任务。_汇报者_ 把累积的工件整理成一份可供阅读的成果,把观察到的事实与推断出的论断区分开来,并记录其中的不确定性以及下一步动作。在探索过程中,编排者还可以把聚焦的收集任务委派给子智能体,并将它们的输出合并回案例状态。
总体来看,该工作流大致如下:
- 广泛指纹识别与分流:
收集低成本信号,例如文件元数据、哈希、与熵相关的提示、字符串、导入、符号名、 YARA匹配、capa结果、编译器或加壳器线索、加密相关指标,以及其他显见的关注点,以此勾勒出样本的初始画像。 - 过滤与分组:
过滤原始输出,将相关的发现归类,把看起来最有相关性的字符串、导入、能力线索和代码区域突出出来。 - 构建假设:
利用上述发现形成初步的想法,推测样本在做什么、它似乎包含哪些主要组件,以及哪些线索值得跟进。 - 绘制内部结构图:
构建一份关于样本内部组织方式的工作图,识别出哪些部分负责持久化、通信、信息收集、注入或其他主要任务,以及它们彼此之间如何衔接。 - 深入分析规划:
在最适合用二进制分析工具进行深入检查的函数、组件、特性和假设中进行选择并排定优先级。 - 有针对性的深入分析:
借助二进制分析工具检查这些高优先级目标,以验证或修正先前的假设,并补回缺失的底层逻辑。
关键的提升来自把结构化的工作流强加于分析过程之上。工作流不再让智能体以开放式的方式与工具交互,而是把过程组织成明确的阶段,并附以具体的中间工件。先收集原始证据,再加以过滤和分组,然后再转化为假设、结构图以及面向更深检查的计划。随着新证据的出现,智能体可以修正先前的假设,更新案例状态,同时基于已有的工件继续推进。
为了支持这一点,流水线为每个样本维护一个持久化的磁盘上案例目录。每完成一个主要步骤之后,工件、笔记、排序后的观察、假设、计划和报告都会被更新并存入磁盘。事实上,这个目录就成了智能体外化出来的工作记忆。一旦上下文窗口被压缩,智能体可以重新读取先前的工件,并从当前状态继续推进。这同时也让工作流变得可检视、可复现,因为中间结果不再隐藏于易逝的模型上下文之中。
我们把这一流水线实现为一个可移植的分析环境,把辅助脚本、可复用的编排 skill 以及通过 MCP 连接的反汇编工具整合到一个工作流中。智能体在专门的 Docker 容器中运行,该容器由 Dockerfile 定义,并可访问可用的工具、脚本以及 MCP 服务器。该工作流被打包为一个 面向 Claude Code 的 malware-analysis-orchestratorskill,并附有一个与之对应的 Codex 变体,静态分析既可以使用我们的 Binary Ninja Headless MCP server,也可以使用 Ghidra Headless MCP server。该方案的设计目标,是在不同智能体、二进制格式以及分析后端之间保持通用。完整的流水线已发布在 GitHub 上。
有了这些之后,我们就可以在结构化工作流下重新分析同一份 mfc42ul.dll样本,并将结果与此前的分析进行比较。
评估
下文我们将聚焦于 Claude Code 的运行结果,因为它在本节中产出了最为清晰的成果。运行时长大致仍在此前的范围之内。Codex 在启用工作流之后也朝着同一方向有所改善,但我们在此略去其输出,因为这并不会改变整体结论。
在转向结果之前,让我们先简要回顾一下 mfc42ul.dll中已知的内容。一些特性 -- 例如截屏捕获、Skype 拦截、持久化以及代理处理 -- 仅凭字符串、API 导入和对代码的浅层浏览,就比较容易识别。然而,该样本同时也包含较深的逻辑和嵌入的数据,这些都难以还原,包括与进程相关的激活、命令分发、协议细节、硬编码的 C2 信息,以及静态嵌入的 AES 密钥。这些恰恰是结构化工作流必须证明其价值的地方。
为了对此进行评估,我们对此前的查询稍作扩展,并明确指示智能体使用 malware-analysis-orchestratorskill:
❯ Analyze the malware in examples/samples/mfc42ul.dll -- Give me a detailed overview of the sample's functionality and features, together with the corresponding code locations. Use the skill /agent/agent_helpers/claude/skills/malware-analysis-orchestrator/ for analysis.大约 17 分钟之后,工作流完成了第一轮分析。智能体填充了全部 13 个所需的案例文件、识别出 13 个功能组件、记录了 10 条行为假设,并对其中 8 条赋予 HIGH 置信度。即使尚未进行任何专门的深入验证步骤,所得到的概览在内容上也已实质性地超过此前那份偏向分流的摘要。为便于呈现,我们在下面给出第一轮输出的略有删节版本:
● Analysis complete. All13 artifacts populated. Here is the detailed overview:1.Process-AwareInitialization (sub_1000f590 @0x1000f590)2.Persistence — AppInit_DLLs (sub_1000d680 @0x1000d680)3.Persistence — KernelDriverService (sub_10003a40 @0x10003a40)4.C2Communication (sub_10006790 @0x10006790)5.SkypeVoIPInterception (sub_10007720 @0x10007720)6.CentralOrchestrator (sub_1000ecc0 @0x1000ecc0)All artifacts are in status/000-mfc42ul.dll/.The analysis identified13 functional components, 10 behavior hypotheses (8HIGH confidence),56 capa capabilities, and produced comprehensive IOCsfor detection engineering.在这一阶段,工作流就已经不再止步于可见特性。它开始把功能归类为若干组件,把这些组件映射到具体的代码区域,并指向样本的内部控制结构。这本身就已经是性质上不同的结果。
差别不仅在于工作流找出了更多内容,它产出的还远不止一份简短的最终摘要。相反,这一轮运行产出了一整套面向假设、组件映射、规划、优先级排序与汇报的详细中间工件。下面这些文件只是工作流所产生的案例状态的几个示例:
05_behavior_hypotheses.md记录了当前的假设、支持证据、置信度,以及尚待验证的检查项。 08_deep_analysis_plan.md把这些假设转化为具体的后续任务,并附上目标函数、目标以及预期发现。 09_priority_queue.md跟踪哪些尚未解决的问题最为重要、为何重要,以及哪些后续工作依赖于它们的解决。 10_reporting_draft.md把当前的发现、代码引用、IOC 以及尚存的空白整合成一份草拟的报告,供智能体后续返回继续完善。
从更高的视角看,前一次运行与结构化工作流之间的对比如下:
更重要的是,这第一轮运行不再只留给我们一份简短的摘要。由于它产出了带优先级的假设以及一份持久化的案例目录,我们可以直接从该状态继续推进,而无需重启整个调查。因此,我们让智能体去验证那 8 条 HIGH 置信度的假设。大约 30 分钟之后,工作流给出了一轮深得多的分析结果:
Validation ResultsH1: Full-Featured Surveillance RAT — VALIDATED- Discovered complete command dispatch vtable at 0x1003d7d0 with 10 remotely-callable commands- Mapped orchestrator vtable at 0x1003d7f8 with C2 data loop, heartbeat (byte 0x26), fingerprintingH3: Process-Aware Module Activation — VALIDATED- Confirmed GetModuleFileNameA + case-insensitive path matching in sub_10003990- Full init chain: DllMain → process detect → module alloc → orchestratorH6: C2 with AES-128 Encryption — VALIDATED- Protocol vtable at 0x1003d330: encrypt+send, recv+decrypt, raw I/O via WinSock send()/recv()- Encrypt: sub_10012130, Decrypt: sub_10013260, Key expansion: sub_10014410- Wire format: C3PO-r2d2-POE → 4-byte length → AES-128-ECB encrypted payload这里有三处改进尤为突出。第一,工作流恢复出了内部的命令分发,而不再止步于样本表层可见的高级能力。第二,它验证了与进程相关的激活逻辑,并重建出从 DllMain进入编排器的完整初始化链。第三,它开始还原协议层本身,包括协议 vtable、收发路径,以及与 C2 通信配套使用的加密例程。
更进一步地观察所恢复出的命令分发表,可以一窥这一深入分析阶段所能揭示的内部结构:
sub_1000d270 | ||||
sub_1000e2b0 | ||||
sub_1000e210 | ||||
sub_1000d680 | ||||
sub_1000db50 | ||||
sub_1000e120 | ||||
sub_1000e370 | ||||
sub_1000d470 | ||||
sub_10006710 | ||||
sub_10006780 |
综合来看,这相比此前的运行是实质性的跃升。工作流不仅仅是给出了一份更长的可见特性清单,它开始揭示该恶意软件的内部组织:能力是如何被分发的、激活如何依赖于宿主进程,以及协议处理与加密例程在 C2 通信中所处的位置。在这一阶段,智能体留下的样本工作模型已经远比一次常规的初轮分流要有用得多。
结果仍不完美。在这次运行中,智能体并未还原出硬编码的 C2 服务器或嵌入的 AES 密钥,且报告为 AES-128-ECB,而该样本实际使用的是 AES-256-ECB。不过,我们应当结合上下文来看待这次失误。工作流确实识别出了相关的协议路径、报文格式、ECB 模式的使用以及 C2 通信中所涉及的加密例程。换句话说,它并未完全错过协议层,只是在一些更细致的细节上还原得不够完整。同时,这次运行仍然是非确定性的:重新运行可能还原出更多细节、强调样本的不同部分,或犯下不同的错误。因此,这一结果不应被视为最终报告,而应被视为一个中间状态。
即便存在这些缺口,提升仍是显著的。结构化工作流把智能体推到了远超粗略分流的位置上,留下的中间状态也更为厚实:一个包含证据、带优先级的假设、优先事项以及部分已验证的内部结构的案例目录。在实际中,这可以为分析师节省数小时甚至数天的早期工作。我们不必再把大部分时间花在收集显见线索和整理初步印象上,而可以聚焦于验证更深层的发现、解决尚未解决的未知,以及修正智能体仍然出错的地方。
由于工作流保留了显式的案例状态,后续分析也会变得更加锐利。分析师可以引导智能体专注于某个具体的假设、子系统或尚未解决的问题,而智能体则可以基于已经积累的证据继续推进,而不必从头开始。它还可以对分析数据库本身进行标注 -- 例如重命名符号、附加笔记并标注相关函数 -- 从而让人类分析师从一个结构更佳、文档更完善的起点继续工作。
正如我们所见,智能体已经在以不容忽视的方式改变着逆向工程。在本文中,即便是无结构的运行,作为初步分流也已颇有价值:它还原了可见的功能、指向了相关的代码位置,并为后续工作给出了具体的线索。然而,真正的提升来自于赋予智能体一套结构化的工作流、持久化的案例状态以及合适的分析工具。这也表明智能体目前特别擅长的领域是:扩展分析中机械的部分、收集证据、关联工件、生成脚本,并以远快于人类的速度产出对二进制的初步结构化理解。
而我们仍处在早期阶段。模型、工具以及智能体化的工作流都在迅速演进,当前这一代已经显示出有多少重复性的逆向工程工作可以被自动化。随着时间推移,这很可能会让人类分析师从亲自完成每一步的角色中抽身,转而更多地去引导工作流、验证结果、打磨假设,并决定在哪里需要进行更深入的分析。
但这并不意味着人类专业知识就此失去价值。逆向工程仍然是一项对抗性的任务:二进制可能与众不同、有意带有迷惑性,或被高度混淆。在这些场景下,听上去合理的答案并不等于正确的答案。智能体可以帮助探索并加速,但一旦分析需要新颖的推理、强力的验证,或在策略上发生转变,它们仍会力有不逮。
混淆就是一个很好的例子。即便是那些在分流和结构化分析上表现出色的智能体化工作流,一旦遇到强控制流混淆、虚拟化、自定义打包或非标准的数据编码,也仍然可能失灵。在那一刻,挑战会从单纯地驱动工具,转变为去理解保护机制是如何运作的、把假设拿到二进制上加以测试,以及设计合适的定制工具或去混淆工作流。LLM 可以在这个过程中提供帮助,但方向仍然必须由分析师来把握。
从这个意义上说,智能体并未消除对逆向工程专业能力的需求,而是抬高了这种能力最重要的那部分门槛。如果说有哪个领域能让这一点尤其凸显,那便是去混淆。对于在实际中需要处理受保护或被混淆二进制的分析师,我在自己的实操培训《Software Deobfuscation Techniques》中讲解了许多这类工作流。
---
免责声明:本博客文章仅用于教育和研究目的。提供的所有技术和代码示例旨在帮助防御者理解攻击手法并提高安全态势。请勿使用此信息访问或干扰您不拥有或没有明确测试权限的系统。未经授权的使用可能违反法律和道德准则。作者对因应用所讨论概念而导致的任何误用或损害不承担任何责任。
夜雨聆风