论文的主要研究问题和方法论介绍
主要研究问题: 本文主要研究了如何通过优化反编译器输出来提高其可读性和简洁性,从而更好地辅助逆向工程师理解二进制文件。反编译器在恶意软件分析、漏洞发现等方面具有重要作用,但传统的反编译器输出存在变量名无意义、冗余变量、缺乏代码注释等问题。
方法论介绍: 为了解决上述问题,本文提出了一种基于大型语言模型(LLM)的端到端框架DeGPT。DeGPT通过引入裁判员(R_ref)、顾问(R_adv)和操作员(R_ope)的三角色机制,将优化任务分解为细粒度的部分,逐步引导LLM进行信息重构,如有意义的变量名和注释。此外,为了确保优化后的输出不改变原始函数语义,DeGPT还提出了微片段语义计算(MSSC)方法进行功能语义检查。
方法实现
大型语言模型的选择: 本文选择了ChatGPT(gpt-3.5-turbo,温度0.2)作为LLM的支持,因其在该领域的领先地位和OpenAI提供的易于使用的接口。此外,DeGPT的设计并不局限于特定的LLM,还可以适配其他大型语言模型,如GPT-4。
程序分析框架: 由于反编译器输出符合C语言的语法,本文采用了基于tree-sitter的代码解析器inspector进行程序分析。这种方法避免了传统编译器框架对可编译代码的要求,适用于反编译器输出的分析。
三角色机制:
-
裁判员(R_ref): 负责检查每个优化任务是否必要,并向顾问(R_adv)发送优化方案。 -
顾问(R_adv): 根据裁判员的优化方案,向LLM查询具体的修正措施,并对反编译器输出进行编辑。 -
操作员(R_ope): 负责检查顾问的修正措施是否改变了原始函数语义,确保优化后的输出与原始输出保持一致。
微片段语义计算(MSSC): MSSC通过模拟函数执行,检查优化前后代码片段的符号值变化,以确定功能语义是否发生变化。具体步骤包括计算阶段和比较阶段,前者收集执行路径和符号值变化信息,后者进行调用检查和变量检查。
核心架构与创新点
核心架构: DeGPT的核心架构包括LLM、三角色机制和MSSC。LLM负责生成优化建议,三角色机制将优化任务分解为细粒度部分并逐步实施,MSSC确保优化后的输出不改变原始函数语义。
创新点:
-
三角色机制: 通过将优化任务分解为裁判员、顾问和操作员三个角色,DeGPT能够最大化LLM的优化潜力,避免不必要的API令牌消耗,并确保优化后的输出不改变原始函数语义。 -
微片段语义计算(MSSC): MSSC通过模拟函数执行,检查优化前后代码片段的符号值变化,确保优化后的输出保持原始函数语义,解决了LLM可能产生的错误响应问题。 -
多种优化类型: DeGPT不仅进行变量重命名,还进行结构简化和注释添加,提升了反编译器输出的可读性和实用性。
实验设计与结果
实验设置: 所有实验在一台配备8个处理器、128GB内存、3TB硬盘和2块RTX 3090 GPU的服务器上进行。编译器使用gcc 9.4.0,反编译器使用Ghidra 10.2.3。数据集包含来自LeetCode、Coreutils、Mirai和AudioFlux的随机函数,经过编译和反编译后得到反编译器输出。
评估指标:
-
有意义的变量比例(MVR): 优化后的变量名中有多少比例与源代码中的变量名相同。 -
努力比例(ER): 优化前后的代码理解难度变化。 -
注释正确率(CR): 优化后添加的注释中有多少比例是正确的。 -
非平凡注释比例(NR): 优化后添加的注释中有多少比例是有助于理解代码的非平凡注释。
实验结果:
-
整体效果: DeGPT在非剥离二进制和剥离二进制上的平均MVR分别为30.3%和27.0%,平均ER为75.6%,平均CR接近100%,平均NR为62.9%。这些结果表明DeGPT显著提高了反编译器输出的可读性和实用性。 -
不同优化类型的效果: 结构简化优化减少了24.4%的理解负担,变量重命名优化将30.3%的变量名重命名为有意义的名字,注释添加优化中62.9%的注释提供了实际的语义信息。 -
与现有方法的比较: 与现有的变量重命名框架DIRTY相比,DeGPT在MVR和ONR(优化后的变量名比例)上均表现更好,平均MVR为30.3%,平均ONR为93.6%,而DIRTY的平均MVR为11.1%,平均ONR为76.7%。
论文的局限性及未来研究的可能方向
局限性:
-
编译器优化级别的影响: 不同的编译器优化级别可能会对DeGPT的效果产生影响,但本文的实验结果显示DeGPT在不同优化级别下的表现相对稳定。 -
LLM的错误响应: 尽管MSSC能够有效检测LLM的错误响应,但仍有可能存在未能检测到的情况。 -
调用上下文的嵌入: 本文未涉及调用上下文的嵌入,而这是优化变量重命名和添加注释性能的一个重要因素。
未来研究方向:
-
调用上下文的嵌入: 通过有效地提供函数的调用上下文,可以进一步优化变量重命名和注释添加的性能。 -
MSSC性能优化: 函数复杂度的增加可能会导致执行路径指数级增长,影响MSSC的分析效率。未来的研究可以探索通过程序切片等方法优化MSSC的性能。 -
多反编译器支持: 虽然DeGPT已经验证了在不同反编译器上的有效性,但进一步的研究可以探索其在更多类型反编译器上的表现。
总结
本文提出了一种基于大型语言模型的端到端框架DeGPT,用于优化反编译器输出,提高其可读性和简洁性。通过引入三角色机制和微片段语义计算,DeGPT不仅能够进行变量重命名、结构简化和注释添加等多种优化,还能确保优化后的输出不改变原始函数语义。实验结果表明,DeGPT在多个数据集上的表现显著优于现有方法,具有较高的实用价值。未来的研究可以进一步探索调用上下文的嵌入和MSSC性能优化,以提升DeGPT的整体性能。
注1
微片段语义计算(Micro Snippet Semantic Calculation,简称MSSC)是DeGPT框架中的一个关键组件,用于确保优化后的反编译器输出不改变原始函数的语义。MSSC通过模拟代码片段的执行过程,检查优化前后符号值的变化,从而判断功能语义是否发生变化。以下是MSSC的详细说明:
1. 背景与动机
在反编译过程中,优化是提高代码可读性和简洁性的重要手段。然而,优化可能会引入错误,导致函数语义发生变化,从而影响逆向工程师的理解和分析。因此,需要一种方法来验证优化后的代码是否保持了原始函数的语义。
2. MSSC的基本原理
MSSC的核心思想是通过模拟代码片段的执行过程,检查优化前后符号值的变化。具体来说,MSSC会为每个代码片段生成一对执行路径:一个是原始代码的执行路径,另一个是优化后的代码的执行路径。通过比较这两条路径上的符号值变化,MSSC可以判断优化是否改变了函数的语义。
3. 实现步骤
3.1 计算阶段
-
生成执行路径:
-
MSSC首先生成原始代码和优化后代码的所有可能执行路径。对于每个代码片段,MSSC会遍历所有可能的执行路径,并记录每条路径上的符号值变化。 -
收集符号值:
-
在执行路径的每一步,MSSC会收集涉及的符号(如变量和函数调用)的值。这些符号值会在不同的执行路径上进行更新。 -
生成中间结果:
-
MSSC将收集到的符号值变化信息存储在两个集合中: SymTables
(存储符号表)和CallLogs
(存储调用日志)。SymTables
记录每个执行路径结束时符号表的状态,CallLogs
记录每个执行路径中的函数调用及其参数值。
3.2 比较阶段
-
调用检查:
-
由于DeGPT在优化调用者时不提供被调用者的源代码,因此LLM无法基于调用关系进行改变。如果优化后的代码在执行路径上与原始代码的调用日志不一致,MSSC会判定函数语义发生了变化。 -
变量检查:
-
对于返回变量和非局部变量,MSSC会比较优化前后每条执行路径上的变量值。如果在任何执行路径上,优化后的变量值与原始代码的变量值不一致,则判定函数语义发生了变化。
4. 具体实现细节
4.1 代码片段表示
MSSC处理的输入是一对代码片段:一个是原始代码片段,另一个是优化后的代码片段。这两个代码片段会被解析成抽象语法树(AST),以便进行符号值的收集和比较。
4.2 符号值分配
在计算阶段,MSSC会为每个符号(如变量和函数调用)分配唯一的随机数。这些随机数在原始代码和优化后的代码之间共享,以便进行比较。
4.3 执行路径模拟
MSSC使用深度优先搜索(DFS)或广度优先搜索(BFS)遍历所有可能的执行路径。对于每条执行路径,MSSC会更新符号表和调用日志,并记录符号值的变化。
4.4 结果判断
在比较阶段,MSSC会逐条比较原始代码和优化后的代码的执行路径。如果在任何执行路径上发现符号值不一致,MSSC会判定优化后的代码改变了函数语义,并拒绝该优化。
5. 实验结果与评估
MSSC在实验中表现出较高的准确率和召回率。具体来说,MSSC能够成功检测到84%的有害代码变化,召回率为85%。这些结果表明,MSSC能够有效地过滤掉可能导致错误的优化,确保优化后的代码保持原始函数的语义。
6. 总结
微片段语义计算(MSSC)是DeGPT框架中的一个重要组件,用于确保优化后的反编译器输出不改变原始函数的语义。通过模拟代码片段的执行过程,MSSC能够有效地检测优化引入的错误,确保优化后的代码保持原始函数的语义。实验结果表明,MSSC具有较高的准确率和召回率,能够有效地辅助逆向工程师进行代码分析和理解。
注2
将优化任务分解为裁判员(R_ref)、顾问(R_adv)和操作员(R_ope)三个角色的好处与优势主要体现在以下几个方面:
1. 提高优化效率
任务分解:将优化任务分解为细粒度的部分,使得每个角色可以专注于特定的优化任务,从而提高整体的优化效率。例如,裁判员可以快速判断哪些优化是必要的,顾问可以专注于具体的优化策略,而操作员则负责最终的优化决策和语义检查。
2. 避免不必要的优化
裁判员的作用:裁判员负责检查每个优化任务是否必要。通过这种方式,可以避免对不需要优化的部分进行浪费,从而节省计算资源(如API令牌)。实验结果显示,使用裁判员后,DeGPT可以节省高达21.9%的API令牌。
3. 提升优化质量
顾问的角色:顾问根据裁判员的优化方案,提出具体的修正措施。通过这种方式,顾问可以利用其专业知识和对问题的深入理解,提出更有效的优化策略,从而提升优化质量。
4. 确保优化后的语义一致性
操作员的作用:操作员负责检查顾问提出的优化措施是否改变了原始函数的语义。通过这种方式,可以确保优化后的代码在功能和行为上与原始代码保持一致,避免因优化引入新的错误。
5. 促进优化任务的协作与分工
角色分工:通过将优化任务分解为三个角色,可以促进团队成员之间的协作与分工。每个角色可以专注于自己的任务,发挥各自的优势,从而提高整体的工作效率和质量。
6. 提高系统的鲁棒性
多角色机制:通过引入多个角色,系统可以更好地应对不同的优化需求和复杂情况。例如,当某个角色遇到困难时,其他角色可以提供支持和补充,从而提高系统的鲁棒性。
7. 便于调试和优化
中间结果的保存:在每个角色的处理过程中,可以保存中间结果。这样,在出现问题时,可以方便地回溯和调试,找出问题的根源并进行修正。
8. 提升用户体验
优化效果的可视化:通过将优化任务分解为多个角色,可以更好地展示优化过程和结果,使用户更直观地了解优化效果,从而提升用户体验。
实验结果支持
实验结果显示,使用三角色机制的DeGPT在结构简化优化、变量重命名优化和附加注释优化方面的表现均显著优于单次实验。具体来说,三角色机制可以使DeGPT在结构简化优化方面提高2.5倍的效果,在变量重命名优化方面提高3.1倍的效果,并覆盖更多的测试用例。
综上所述,将优化任务分解为裁判员、顾问和操作员三个角色的好处与优势主要体现在提高优化效率、避免不必要的优化、提升优化质量、确保优化后的语义一致性、促进优化任务的协作与分工、提高系统的鲁棒性、便于调试和优化以及提升用户体验等方面。实验结果也验证了这一机制的有效性和优越性。
链接:https://www.ndss-symposium.org/wp-content/uploads/2024-401-paper.pdf
原文始发于微信公众号(为机器立心):[NDSS 2024]中国科学院信息工程研究所与网络安全学院联合提出DeGPT:基于LLM的逆向工程代码优化框架