什么 algorithms/techniques 可用于检测内存转储中的代码?

What algorithms/techniques can be used to detect code within a memory dump?

我正在寻找一个 algorithm/technique 可以让我从给定的内存转储中检测代码。

比如我可以让程序学习一门新语言。一种新语言将是一组遵循给定语法的指令。

通过为程序提供一组十六进制值(随机数据 + 代码),我想确定存在符合语言语法的代码的概率。

已经有 some tools 这样的产品了,所以您可能想看看现有的实现,看看它们是如何实现的。

也就是说,如果我是从头开始写这篇文章,我的第一个想法是构建数据的 n-gram model 模型,并将其与我们正在寻找的代码类型的类似模型进行比较为了。维基百科文章似乎有点重理论而缺乏实际实施细节,但基本上,您可以这样做:

  1. 收集大量 "reference corpus" 您正在寻找的代码。

  2. 将参考语料库中的代码分成(重叠)片段,例如三个字节,并计算每个片段 ("tri-gram") 在语料库中出现的次数。这是您的基本原始 n-gram 模型,对于 n = 3 和字节作为基本数据单位。

  3. 将所有 n-gram 计数加一;这称为 additive smoothing,使匹配过程更加稳健。

  4. 通过将以每个两个字节的前缀。还预先计算 所有 平滑后的 3 克计数的总和。 (这只是参考语料库的总字节长度,减去n−1 = 2倍其中的独立文件数,加上2563 用于平滑。)

  5. 为了更好的匹配速度和数值稳定性,取所有(平滑的)3-gram 和 2-gram 计数(以及总计数)的对数。将这些存储为您的实际(平滑、对数)n-gram 模型。 (方便地,log(1) = 0,因此通过加 1 并取对数,任何在平滑之前最初为零的 3-gram 计数再次变为零;如果你有很多这样的计数,请考虑只存储非零计数.)

  6. 使用这个预处理的 n-gram 模型,您可以遍历输入文件并计算它与参考语料库匹配的近似对数似然在输入文件中找到的每 3-gram 的对数计数之和,减去在输入文件中找到的每 2-gram 的对数计数(第一个和最后一个除外),减去总和的对数平滑的 3 克计数。我将在这里跳过数学的细节,因为这是 SO,而不是 math.SE,但相信我,它有效。

生成的原始数字本身没什么用(尽管您可以通过将其除以输入的长度来获得更有意义的东西),但可以与 [ 的相应对数似然值进行有用的比较=39=]other n-克模型。结果最大的是最有可能匹配的。

特别是,作为基线 "null model",您可能希望计算输入为纯随机字节的对数似然。您不必实际构建随机数据的 n-gram 模型即可;输入是纯随机字节的对数似然只是 -log(256) 乘以以字节为单位的输入长度(这就是为什么在比较它们之前将对数似然除以输入长度可能很有用)。

(作为对您的实施的一致性检查,您可能希望检查这是否也是您构建平滑的 n-gram 模型时将获得的对数似然来自一个空的语料库。)

最后,如果您怀疑您的输入可能混合了不同类型的数据,您可以在分析之前简单地将其分解成块。或者,您可以通过减去每个 3 克的对数计数(并添加当您沿着输入文件移动时,那些落在对数似然 window 之外的每 2 克)。