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

String 这是什么编码/压缩算法?,string,encoding,compression,reverse-engineering,String,Encoding,Compression,Reverse Engineering,我正在尝试对二进制文件格式进行反向工程,但它没有魔法字节,也没有特定的扩展名。我只能影响文件的一个方面:短字符串。通过尝试不同的字符串,我能够弄清楚数据是如何存储在文件中的。整个文件似乎使用了某种简单的编码。我希望找到准确的编码可以缩小对文件格式的搜索范围。我知道这个文件是由一个用C++编写的Windows程序生成的。 现在,经过多次尝试和错误,我发现文件的某些部分是以运行方式编码的。每次运行都以一个字节开始,该字节指示后面将有多少字节以及从何处检索数据 000ddddd(1字节)从编码数据中

我正在尝试对二进制文件格式进行反向工程,但它没有魔法字节,也没有特定的扩展名。我只能影响文件的一个方面:短字符串。通过尝试不同的字符串,我能够弄清楚数据是如何存储在文件中的。整个文件似乎使用了某种简单的编码。我希望找到准确的编码可以缩小对文件格式的搜索范围。我知道这个文件是由一个用C++编写的Windows程序生成的。 现在,经过多次尝试和错误,我发现文件的某些部分是以运行方式编码的。每次运行都以一个字节开始,该字节指示后面将有多少字节以及从何处检索数据

  • 000ddddd
    (1字节)
    从编码数据中提取以下(ddddd)+1字节
  • 111··ddd··bbbbb
    (3个字节)
    返回(bbbbb)+解码数据中的1个字节,并从中取出下一个(ddddd)+9个字节
  • ddd············································
下面是一个例子:

这是文件的开头,其中编码了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):

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


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

可能是NTFS压缩,也就是说。平台和明显的2字节结构以及实际数据的字节对齐支持了这一想法

以下元素特定于此算法

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

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

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

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


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

  • 在您的示例中,magic头和compressed vs uncompressed的指示已被删除(如果它嵌入到文件中,也就不足为奇了)
  • 您将块长度作为一个字节,但它是两个字节和big-endian,因此前面的0x00是长度的一部分,它仍然有效

你确定文件包含文本吗?@Hidde我可以命令程序给我一个大文件,其中包含我选择的特定18个字符串。这些是我选择的字符串,以及它们在结果文件中对应的编码版本。我在二进制文件中找不到任何其他字符串,但这可能是由于编码的原因。第一个字节似乎是十六进制字符串的长度。如果此编码用于压缩,它将赢得有史以来最差压缩方法奖!请提供空字符串、单个字符和单个非ASCII字符(即需要UTF-8或UTF-16进行编码的字符)的结果。您可能会发现一些问题。我将深入研究它。我深入研究了文件,似乎不仅仅是字符串,而是整个文件(或至少部分文件)都使用了LZ变体进行了压缩。但是,它不是LZNT1,因为它从一个16位的块头开始,指示块的大小。如屏幕截图所示,前16位的值是
1
,而块肯定不是1字节长。但我会继续寻找+1表示建议。@Virtlink:前面可能还有一个特定于应用程序的标题。如果您浏览,是否有任何字节对于块大小合理?我找不到任何指示块大小的内容,也找不到重复间隔(例如,每4K)的任何类似头或边框的结构。然而,我已经能够对所使用的编码进行反向工程,但我无法识别它,也无法在上面找到任何东西。请看我大量更新的帖子。是的!你好像一针见血。我怀疑是容器中的一个或多个LZF压缩文件。
  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