【问题标题】:What encoding/compression algorithm is this?这是什么编码/压缩算法?
【发布时间】:2014-03-01 23:20:10
【问题描述】:

我正在尝试对二进制文件格式进行逆向工程,但它没有魔法字节,也没有特定的扩展名。我只能影响文件的一个方面:一个短字符串。通过尝试不同的字符串,我能够弄清楚数据是如何存储在文件中的。似乎整个文件使用了某种简单的编码。我希望找到确切的编码可以让我缩小对文件格式的搜索范围。我知道该文件是由用 C++ 编写的 Windows 程序生成的。

现在,经过多次反复试验,我发现文件的某些部分是在 runs 中编码的。每次运行都以一个字节开始,该字节指示后面有多少字节以及从何处检索数据。

  • 000ddddd(1 个字节)
    从编码数据中取出以下 (ddddd)+1 个字节。
  • 111····· ···ddddd ···bbbbb(3 个字节)
    在解码后的数据中返回 (bbbbb)+1 个字节,并从中取出下一个 (ddddd)+9 个字节。
  • ddd····· ··bbbbbb(2 个字节)
    在解码后的数据中返回 (bbbbbb)+1 个字节,并从中取出下一个 (ddd)+2 个字节。

这是一个例子:

这是文件的开头,其中编码了 UTF-16 字符串 abracadabra:

  .     .  .  a  .  b  .  r     .  .  c     .  .  d     .  €  .
  0C 20 03 04 61 00 62 00 72 20 05 00 63 20 03 00 64 20 03 80 0D

解码字符串:

  0C                      number of Unicode chars: 12 (11 chars + \0)
  20 03       . . .       ??
  04                      next 5
  61 00       a .
  62 00       b .
  72          r
  20 05       . a .       back 6, take 3
  00                      next 1
  63          c
  20 03       . a .       back 4, take 3
  00                      next 1
  64          d
  20 03       . a .       back 4, take 3
  80 0D       b . r . a . back 14, take 6

这会导致 (UTF-16):

  a  .  b  .  r  .  a  .  c  .  a  .  d  .  a  .  b  .  r  .  a  .
  61 00 62 00 72 00 61 00 63 00 61 00 64 00 61 00 62 00 72 00 61 00

但是,对于这可能是什么编码/压缩算法,我没有线索。它看起来像是 LZ 的一些变体,不使用字典(如 LZ77),但到目前为止,我还没有找到任何与此描述匹配的算法。我也不确定整个文件是这样编码的,还是只是其中的一部分。

你知道这种编码吗?或者您对我可能会在文件中查找以识别编码的内容有任何提示吗?

【问题讨论】:

  • 您确定文件包含文本吗?
  • @Hidde 我可以命令程序给我一个大文件,其中包含我选择的特定 18 个字符串。这些是我选择的字符串,以及它们在结果文件中的相应编码版本。我无法在二进制文件中找到任何其他字符串,但这可能是由于编码。
  • 看来第一个字节是十六进制字符串的长度。
  • 如果此编码用于压缩,它必须赢得最差压缩方法奖,永远!
  • 请提供空字符串、单个字符和单个非 ASCII 字符(即需要 UTF-8 或 UTF-16 编码)的结果。

标签: string encoding compression reverse-engineering


【解决方案1】:

在您编辑后,我认为它是LZF,与您的观察结果有以下不同:

  • 已在您的示例中删除了魔术头和压缩与未压缩的指示(如果它嵌入在文件中,这并不奇怪)。
  • 您将块长度作为一个字节,但它是两个字节和大端,所以前面的 0x00 是长度的一部分,仍然有效。

【讨论】:

  • 是的!你似乎一针见血。我怀疑它是容器中的一个或多个 LZF 压缩文件。
【解决方案2】:

可能是 NTFS 压缩,即LZNT1。这个想法得到了平台和明显的 2 字节结构以及实际数据的字节对齐的支持。

以下元素特定于此算法。

块:压缩、未压缩或表示缓冲区结束的数据段。

块标头:压缩或未压缩数据块的标头。

标志字节:一个位标志,其位从低位读取到高位,指定随后数据元素的格式。例如,位 0 对应于第一个数据元素,位 1 对应于第二个数据元素,依此类推。如果设置了一个数据元素对应的位,则该元素是一个2字节的压缩字;否则,它是一个 1 字节的文字值。

标志组:标志字节后跟零个或多个数据元素,每个数据元素是单个文字字节或 2 字节压缩字。

【讨论】:

  • 你可能正在做某事。我会调查的。
  • 我更深入地查看了文件,似乎不仅是字符串,而且整个文件(或至少部分文件)都是使用一些 LZ 变体压缩的。但是,它不是 LZNT1,因为它以一个 16 位的块头开始,指示块的大小。如屏幕截图所示,第一个 16 位值是 1,并且该块肯定不是 1 字节长。但我会继续寻找。 +1 建议。
  • @Virtlink:前面可能还有一个特定于应用程序的标题。如果您扫描,任何字节对于块大小是否合理?
  • 我找不到任何指示块大小的东西,也找不到任何重复间隔(例如每 4K)的标题或类似边框的结构。但是,我已经能够对使用的编码进行逆向工程,但我不认识它,也找不到任何东西。请参阅我大量更新的帖子。
猜你喜欢
  • 2010-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-29
  • 2010-09-28
  • 1970-01-01
  • 2020-11-25
  • 2015-09-25
相关资源
最近更新 更多