这是什么编码/压缩算法?

时间:2014-03-01 23:20:10

标签: string encoding compression reverse-engineering

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

现在,经过多次试错,我发现文件的某些部分是以运行编码的。每次运行都以一个字节开始,该字节指示将跟随多少字节以及检索数据的位置。

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

以下是一个例子:

  

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

     

First 224 bytes of the file

  .     .  .  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),但到目前为止我还没有找到任何匹配此描述的算法。我也不确定整个文件是这样编码的,还是只是部分编码。

你知道这个编码吗?或者,您是否有任何关于我可能在文件中查找以识别编码的提示?

2 个答案:

答案 0 :(得分:1)

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

  

以下元素特定于此算法。

     

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

     

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

     

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

     

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

答案 1 :(得分:1)

编辑后我认为LZF与您的观察结果存在以下差异:

  • 在您的示例中已删除了魔术标头和压缩与未压缩的指示(如果它嵌入文件中,则不会太令人惊讶)。
  • 你把块长度作为一个字节,但它是两个字节和big-endian,所以前面的0x00是长度的一部分,它仍然可以工作。