在过去的几年里,我使用了一些反汇编器并尝试了一些反编译器,现在有很多关于深度学习和人工智能的讨论和东西,我想知道是否可以将一些用于这些任务(经过一些人工培训),是否有一些工具使用它已经。
AI 可以用来编写更好的反编译器/反汇编器吗?
首先,如果不定义AI 的含义,就无法回答这个问题……因为这可能是计算机科学领域中最糟糕的名称。当人们想到“模仿人类推理的程序”时,现实更多的是“自动启发式方法来识别大量样本中的模式”......
所以,我将采用更准确的人工智能定义,也就是说,我假设人工智能程序可以识别可能逃逸到人类理解的模式,并且他们可以通过自我训练来实现这一点。
现在,谈到反汇编,核心问题绝对不是识别模式,而是重建可以在二进制文件中找到的所有执行路径。因此,AI 算法根本没有兴趣选择执行路径是否比另一个更有价值,因为它们都很有趣(因为反汇编程序需要详尽地找到所有路径)。
最后,说到反编译,这是您可能希望使用 AI 识别一些模式的领域,例如:
- 使用了什么编译器或什么语言;
- 猜猜这段代码是否与您的恶意软件数据库中的另一个样本相似;
- 即使在经过混淆处理之后,也要对软件的架构(复杂的数据结构(数组、记录)、函数、对象、模块、包等)做出初步猜测;
- 认识最常见的功能以及它们的用途;
- ...可能还有许多其他可以自动化的猜测......
但是,这里的重点是我们都被反汇编问题困住了(这是一个非常强大的问题!!!),为了更进一步,我们首先需要有一个相当可靠的方法/算法/工具,以便达到下一个级别(反编译)。
虽然有几个人朝这个方向努力,你可以看看(这个列表还很不完整,我在谷歌上搜索的只有 1000 万个):
- 机器学习辅助二进制代码分析,作者:Nathan Rosenblum、Xiaojin Zhu、Barton Miller 和 Karen Hunt,NIPS 2007。
- 反汇编数据的深度学习(全文),作者:Andrew Davis 和 Matt Wolff,BlackHat 2015。
- 使用循环神经网络进行反编译,作者:Deborah S. Katz、Jason Ruchti 和 Eric Schulte,SANER 2018
- Evolving a Decompiler,作者 Matt Noonan,2018 年;
尽管我最初投票决定以主要基于意见的方式结束这个问题,但鉴于两个答案都具有相同的一般答案(“不! ”),我也会回答。我只是喜欢成为魔鬼的代言人。
一般立场
这个问题很难回答。作为来自安全领域并在过去从事过不少机器学习相关项目的人,我知道很难对是否有可能使用机器学习解决我们领域中的问题做出诚实的预测。通常,ML/AI 研究是关于反复试验的。
AI反汇编器
虽然反汇编字节序列的操作非常简单,但现在有很多问题可以通过一些巧妙的启发式方法解决。这些问题包括:
- 识别功能边界。
- 分类代码VS数据。
- 从程序集推断结构和更高级别的构造。
和更多。
随着时间的推移,其中一些问题主要通过为反汇编程序创建和改进手动编写的启发式方法和逻辑指南而得到改善。主要基于人类经验和过去看到的错误结果。
然而,在全自动反汇编程序中看到错误仍然很常见,并且作为证据,我们可以看到反汇编程序给予逆向工程师手动更正和调整自动分析的重点。有人可能会争辩说,ML/AI 方法可能会创建类似或更好的启发式方法和更复杂/准确的规则。
人工智能反编译器
即使给定完美的反汇编,反编译通常也被认为更难完成。它在很大程度上依赖于推断更高级别的构造,例如结构、对象、类和继承。它需要更准确的数据类型识别和对抽象对象的更高要求的理解和推理。即使是人类也发现那些更难手动识别,更不用说使用自动规则和启发式方法了。因此,反编译可能会为此类改进提供更肥沃的土壤。
关于流行语的一句话
如今,当初创公司因在营销中使用正确的流行语而兴衰时,很容易被吸引到使用这些流行语而不是准确的描述,并强迫解决问题而不是为手头的问题找到最佳解决方案。
不!
原因是人工智能是愚蠢的,比你想象的要愚蠢得多。它所能做的就是匹配模式以预先确定输出。使用它来反编译代码或重新创建“可读”源代码有两个主要问题:
这种搭配并不完美。例如,如果你有
mov, eax 0x10
它可以被解释为i=8;
AI 没有这个微粒训练集,但它有mov, eax 0x8
.另一个大问题是给 AI 提供什么。在翻译工具中使用句子,在图像识别中使用来自整个图像的特征。在代码中使用什么?操作码少?多少?从哪儿开始?
总而言之,人工智能(在现阶段和不久的将来)对于此目的几乎毫无用处。
我想说的是,但我不得不说NO。问题是计算机会抓取我们编写的程序并以一种对人类几乎没有意义或毫无意义的方式对其进行优化。您会看到事物相乘和使用的数组,您可以理解正在发生的事情,但以这种方式处理数据是非常不人道的。计算机和人类的思维方式截然不同。
我认为人工智能有可能做到以下几点:
- 获取程序集并进行转换,或者让人们更清楚地理解它。
- 制作一种近乎可用的装配形式。(也许......因为我们将保持计算机对相关数据的理解完整。)
举这个简单的例子:
MOV v7, DWORD PTR [v7 + 0x8]
将转换为
v7 = *(_DWORD *)(v7 + 8);
然后到
v7 = *(v7 + 8)
这可能真的是完全不同的来源。
你可能会看到类似的东西
mov eax, dword ptr ds: [ESI*deadbeef+0b0]
计算机会认为
int a = somefoovar[v5].someint
或者
int a = 1234;
两者都是正确的......如果该数组中没有变化的数据。
但是当它可能是临时的时,计算机可能会将其视为单个变量。我还注意到,在我自己的反编译工作中,您会得到更多最初开始时的静态变量。
我认为其他一些问题可能是程序可能永远不会命中函数的某些部分,并且可能无法理解所有事件路径。
就我个人而言,我想看看 AI 能想出什么。也许有一个伪代码翻译器会很好。但我知道我将不得不清理它并纠正它的理解。