可以使用哪些算法/技术来检测内存转储中的代码



我正在寻找一种算法/技术,使我能够从给定的内存转储中检测代码。

例如,我可以让程序学习一种新的语言。一种新的语言将是一套尊重给定语法的指令。

通过给程序一组十六进制值(随机数据+代码),我想确定一个尊重语言语法的代码存在的概率。

已经有一些类似的工具了,所以你可能想看看现有的实现,看看它们是如何做到的

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

  1. 收集你正在寻找的那种代码的大型"参考语料库"。

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

  3. 将所有n克计数增加一;这被称为加性平滑,使匹配过程更加稳健。

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

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

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

生成的原始数本身用处不大(尽管你可以通过将其除以输入的长度来获得更有意义的东西),但可以与其他n-gram模型的相应对数似然值进行有用的比较。结果最大的一个是最有可能匹配的。

特别是,作为基线"零模型",您可能希望计算输入为纯随机字节的对数可能性。你不需要实际构建一个n-gram的随机数据模型;输入是纯随机字节的对数似然性仅为−log(256)乘以以字节为单位的输入长度(这就是为什么在比较之前将log似然除以输入长度是有用的)。

(作为对实现的一致性检查,您可能希望检查一下,如果您从空语料库中构建平滑的n-gram模型,这也是您获得的日志可能性。)

最后,如果你怀疑你的输入可能包含不同类型的数据,你可以在分析之前简单地将其分解成块。或者,当您沿着输入文件移动时,您可以通过从日志似然性中减去掉出窗口的每3克的日志计数(并加上每2克的日志数)来计算某个合适大小(例如,几千字节)的移动窗口上的日志似然性的运行平均值。

最新更新