分享自:

LLMDFA:利用大语言模型分析代码数据流

期刊:Conference on Neural Information Processing Systems

关于LLMDFA:利用大语言模型进行代码数据流分析的学术研究报告

一、 研究作者、机构与发表信息

本研究的主要作者包括:Chengpeng Wang (普渡大学), Wuqi Zhang (香港科技大学), Zian Su (普渡大学), Xiangzhe Xu (普渡大学), Xiaoheng Xie (蚂蚁集团), Xiangyu Zhang (普渡大学)。该研究以论文《LLMDFA: Analyzing Dataflow in Code with Large Language Models》的形式,在第38届神经信息处理系统大会(NeurIPS 2024)上发表。

二、 学术背景与研究目标

本研究属于软件工程与程序分析领域,特别是静态数据流分析(Dataflow Analysis)方向。数据流分析是一种基础的代码分析技术,用于识别程序中不同值之间的依赖关系,对于程序优化、漏洞检测等下游应用至关重要。

传统的静态数据流分析技术存在两大主要局限性:首先,它们通常依赖于成功的编译过程来生成中间表示(IR),如LLVM IR,这使其无法分析不完整或无法编译的程序(例如,集成开发环境中正在编写的代码)。其次,为特定任务(如检测特定类型的漏洞)定制分析规则需要深厚的专业知识和复杂的配置,这阻碍了其在现实场景中应对不断变化的分析需求时的可用性。

与此同时,大语言模型(LLMs)在代码理解和生成方面展现出卓越能力,为程序分析提供了新的可能性。然而,直接将LLMs用于数据流分析面临“幻觉”(hallucinations)问题的严重威胁,即模型可能生成看似合理但实际错误的推理结果,从而影响分析的可靠性。

因此,本研究的目标是提出并实现LLMDFA,一个由LLM驱动的、无需编译且可定制化的数据流分析框架。其核心目标在于,一方面利用LLM的强大代码理解能力摆脱对编译和专家知识的依赖,另一方面通过创新的方法设计来有效缓解LLM的幻觉问题,从而获得可靠的分析结果。

三、 详细研究流程与方法论

LLMDFA将整个数据流分析任务分解为三个更易管理的子问题,并针对每个子问题设计了专门的策略来克服幻觉。

第一阶段:源与汇的提取(Source/Sink Extraction) * 研究对象与目标:针对给定的程序源代码和用户用自然语言描述的数据流分析任务(例如,“找出所有可能被赋值为0的变量(源)和所有用作除数的变量(汇)”),目标是自动、准确地识别出程序中所有符合描述条件的源变量和汇变量。 * 方法与流程:LLMDFA不直接询问LLM某行代码是否包含源/汇,而是将LLM用作代码合成器。具体流程如下: 1. 输入:用户提供的源/汇描述规范、包含示例源/汇的示例程序及其抽象语法树(AST)。 2. 合成:LLM根据上述输入,生成一个能够遍历程序AST的脚本程序(如Python脚本)。该脚本利用外部解析库(如Tree-sitter)来精确识别代码结构。 3. 验证与迭代:在示例程序上执行生成的脚本,检查其是否能正确识别所有源/汇。若识别有误(漏报或误报),则将错误信息反馈给LLM,让其修正脚本。此过程迭代进行,直到脚本在示例程序上达到100%准确率。 4. 输出:一个可重用的、针对特定分析任务的源/汇提取器。这个提取器可以应用于任何目标程序,通过解析AST来高效、确定性地找出所有源和汇。

第二阶段:数据流摘要生成(Dataflow Summarization) * 研究对象与目标:针对程序中的单个函数,目标是判断在该函数内部,从一个特定的“起始变量”(可能是源、函数参数或函数输出值)到一个特定的“目标变量”(可能是汇、函数调用参数或返回值)之间是否存在数据流事实(即值依赖关系)。 * 方法与流程:LLMDFA采用少样本思维链提示(Few-shot Chain-of-Thought Prompting) 策略来引导LLM进行精确推理。 1. 输入:目标函数的代码、待查询的变量对(起始变量@行号, 目标变量@行号)、以及一组精心设计的示例。 2. 提示设计:示例不仅展示了不同类型的数据流模式(如直接赋值、通过中间变量传递、指针操作等),还包含了逐步推理的详细解释(思维链)。这使得LLM能够学习如何像程序员一样,通过追踪变量赋值和使用的路径来推理数据流。 3. 推理与输出:LLM基于提示,对给定的变量对进行逐步推理,最终输出“是/否”的结论以及推理过程。通过将跨函数的数据流分析分解为多个独立的函数内摘要分析,LLMDFA能够处理大规模代码,并减少了因一次性分析过长代码而导致的幻觉。

第三阶段:路径可行性验证(Path Feasibility Validation) * 研究对象与目标:对于通过拼接函数摘要得到的完整数据流路径,需要验证该路径在程序实际执行时是否可行。例如,一条数据流路径可能经过一个条件分支,但该分支的条件永远无法满足(不可行路径),那么这条数据流事实在实际中不会发生。 * 方法与流程:LLMDFA再次利用LLM的代码合成能力,将复杂的逻辑推理任务外包给外部专家工具。 1. 输入:包含分支条件等信息的路径描述。 2. 合成:LLM根据路径描述,生成一个调用外部自动定理证明器(如Z3求解器)的Python脚本。该脚本将路径条件编码为约束,并询问求解器这些约束是否可满足(即路径是否可行)。 3. 验证与迭代:执行生成的脚本。如果脚本存在语法或逻辑错误,将错误信息反馈给LLM进行修正,最多迭代三次。若三次后仍无法生成正确脚本,则回退到直接由LLM判断路径可行性。 4. 输出:路径是否可行的布尔判断。只有通过可行性验证的数据流路径才会被最终报告为有效的分析结果。

整体工作流:LLMDFA首先使用第一阶段合成的提取器扫描整个程序,识别所有源和汇。然后,基于程序的控制流图(CFG),它系统地组合源、汇、函数参数和返回值,形成需要检查的变量对。对于每一对变量,它进入第二阶段,在相关函数内进行数据流摘要分析,逐步构建出跨函数的数据流路径。最后,对每一条构建出的完整路径,进入第三阶段进行可行性验证。只有从源到汇、且路径可行的数据流才会被报告,例如,用于指示一个潜在的安全漏洞。

四、 主要研究结果

研究团队在合成基准测试集(Juliet Test Suite)和真实世界程序(TaintBench中的Android恶意软件应用)上对LLMDFA进行了全面评估。

1. 在合成基准上的性能: LLMDFA使用GPT-3.5 Turbo、GPT-4、Gemini-1.0-Pro和Claude-3-Opus四种不同的LLM进行测试,针对除零(DBZ)、跨站脚本(XSS)和操作系统命令注入(OSCI)三种典型漏洞进行检测。 * 总体性能:以GPT-3.5为例,LLMDFA在DBZ/XSS/OSCI检测中分别达到了73.75%/100%/100%的精确率(Precision)和92.16%/92.31%/78.38%的召回率(Recall),平均F1分数显著提升。 * 各阶段性能: * 源/汇提取:在所有LLM和所有漏洞类型上,精确率和召回率均达到或接近100%,证明了工具合成方法的有效性。 * 数据流摘要:使用GPT-3.5时,在DBZ/XSS/OSCI检测中分别达到90.95%/86.52%/89.57%的精确率和97.57%/96.25%/85.76%的召回率,表明少样本思维链提示能有效对齐LLM与程序语义,减少幻觉。 * 路径可行性验证:使用GPT-3.5时,在DBZ/XSS/OSCI检测中分别达到81.58%/100%/100%的精确率和99.20%/100%/97.14%的召回率,证明了通过合成脚本调用SMT求解器进行验证的策略是成功的。 * 与基线对比: * 与传统静态分析器对比:LLMDFA在F1分数上显著优于不依赖编译的CodeFuseQuery(平均提升0.23)和依赖编译的Pinpoint(在DBZ检测上F1分数更高)。LLMDFA在保持高精确率的同时,获得了更高的召回率,表明其能发现更多传统分析器因建模限制而遗漏的数据流。 * 与LLM端到端分析对比:LLMDFA大幅优于直接使用少样本思维链提示进行端到端漏洞检测的方法(平均F1分数提升0.36)。这直接证明了LLMDFA通过问题分解和专用策略来缓解幻觉的有效性。

2. 在真实世界程序上的性能: 在TaintBench的39个真实Android应用中,LLMDFA(GPT-3.5)在随机抽样的80条数据流路径上达到了75.38%的精确率和61.25%的召回率,显著优于LLM端到端分析(43.48%精确率,25.00%召回率)和CodeFuseQuery(72.92%精确率,43.75%召回率)。这证明了LLMDFA在无需编译、且需为每个应用定制源/汇定义的复杂现实场景下的实用性和优越性。

3. 多语言支持能力: 通过替换Tree-sitter的解析器包,LLMDFA可以较容易地扩展到其他编程语言。研究团队将其迁移以支持C/C++和JavaScript,并在相应的基准测试上取得了与Java版本相当的良好性能(例如,在C/C++的Juliet测试集上,DBZ检测F1分数为84.77%),证明了其框架的通用性。

4. 消融研究结果: 通过移除LLMDFA的关键组件进行对比实验,进一步验证了各设计的必要性: * NoSynExt(不使用工具合成提取源/汇):导致源/汇识别错误增多,产生大量误报。 * NoCOT(不使用思维链提示进行数据流摘要):虽然在某些情况下精确率略高,但召回率大幅下降,无法识别复杂的数据流事实。 * NoSynVal(不使用工具合成验证路径可行性):在存在不可行路径的DBZ检测中,性能下降,产生了更多误报。

这些结果清晰地表明,LLMDFA的三个核心技术设计——工具合成提取、思维链提示摘要、工具合成验证——对于获得高精度、高召回率的分析结果都是不可或缺的。

五、 研究结论与价值

本研究成功提出了LLMDFA,一个开创性的、由LLM驱动的、无需编译且可定制化的数据流分析框架。其核心贡献在于,通过将复杂的数据流分析任务分解为源/汇提取、数据流摘要和路径可行性验证三个子问题,并分别采用工具合成少样本思维链提示等策略,有效缓解了LLM在代码推理中的幻觉问题,从而实现了可靠的分析。

科学价值:LLMDFA展示了一种将LLM的语义理解能力与形式化方法、外部专家工具相结合的新型程序分析范式。它证明了LLM不仅可以作为“解释器”直接回答问题,更可以作为“协调者”和“合成器”,组织并调用更可靠的专业工具来完成复杂任务,这为LLM在程序验证、程序合成等其他需要精确推理的软件工程任务中的应用提供了宝贵思路。

应用价值:LLMDFA显著降低了数据流分析的技术门槛和应用限制。开发者无需等待代码可编译,也无需具备深厚的程序分析专业知识,仅用自然语言描述分析目标,即可对代码进行深入的数据流检查。这使得在开发早期进行安全漏洞检测、代码质量评估成为可能,并能快速适应新的分析需求。

六、 研究亮点

  1. 创新性的问题分解与集成策略:将传统上统一的数据流分析流程拆解为三个针对性强的子任务,并分别为之设计最适配的LLM交互策略(合成工具 vs. 思维链提示),是本研究方法上的核心创新。
  2. “LLM作为合成器”的巧妙运用:两次利用LLM合成代码来调用外部工具(解析库、SMT求解器),将LLM不擅长的精确符号处理和逻辑推理外包,是保证结果可靠性的关键。
  3. 出色的性能表现:在合成和真实数据集上,LLMDFA在精确率、召回率和F1分数上均显著优于传统静态分析器和直接的LLM端到端方法,以扎实的实验数据证明了其有效性。
  4. 强大的实用性与泛化性:框架实现了真正的“无需编译”和“自然语言定制”,并成功迁移至多种编程语言,展示了其在现实软件开发环境中的巨大应用潜力。

七、 其他有价值的内容

研究还讨论了LLMDFA的局限性与未来工作方向,例如:提示可能较长导致Token成本较高;对于包含大型函数或复杂指针操作的程序,数据流摘要可能不精确;路径条件编码可能出错影响完备性。作者提出了潜在的改进方案,如通过微调LLM、总结路径条件模式进行过近似等。这些讨论为后续研究指明了方向。

此外,论文在附录中提供了详细的提示词模板、示例、以及更多的实验结果分析(如工具合成所需的修复轮数统计),为其他研究者复现和拓展本工作提供了充分的信息。

上述解读依据用户上传的学术文献,如有不准确或可能侵权之处请联系本站站长:admin@fmread.com