困扰很久的问题...

一游戏依赖的文件,里面存了大量的图片...因为好多图片都使用一个调色板,所以调色板只存了几个...对于普通的图片,数据流长度是width*height,很容易被解析出来,但这个文件里还有其他好几种格式,却看不懂.
0000148ch: 43 52 50 53 00 00 00 0C B5 F7 01 00 F4 1C 00 00 ; CRPS....调..?..
这是一个图片的定位方法.
第一个DWORD,是ASCII标识
第二个DWORD,如果是00000000话,是普通图片,如果是0000000C的话,就是我下面需要解析的图片...
第三个DWORD,是该图片所依赖的调色板在文件中的偏移量
第四个DWORD,是该图片开始位置在文件中的偏移量

图片:
第一个DWORD,是宽,第二个DWORD,是高,其后是数据.
0F 00 00 00 17 00 00 00 03 00 82 D8 58 04 00 83 E7 D5 58 05 00 84 E7 DB D5 58 06 00 85 E7 DB C3 
D8 58 08 00 87 E7 D8 C3 C8 D5 B7 58 09 00 88 E7 D5 C8 C8 C8 CA C3 58 0A 00 89 E7 D5 C8 C8 C8 C8
C8 C8 B7 0C 00 8B E7 CA C8 C8 C8 C8 C8 C8 C8 C8 58 0E 00 8D E7 CA CA CA CA CA CA CA CA CA CA B5
58 0F 00 8E E7 CA CA CA CA CA CA CA CA CA CA CA C3 58 10 00 8F E7 CA D5 D5 D5 C4 55 55 55 50 50
50 50 50 38 10 00 8F E7 D5 D5 D5 C9 7A 29 1A 1A 1A 1A 1A 1A 1A 1A 10 00 8F E7 D5 D5 D5 91 37 18
17 17 17 17 17 17 18 18 10 00 8F E7 D8 D8 CB 6D 30 18 17 17 17 17 17 17 17 18 10 00 8F E7 D8 CE
6F 31 30 17 17 17 17 17 17 17 17 17 07 00 86 E2 D6 90 37 30 30 06 00 85 E0 92 6C 30 30 06 00 CE
6F 31 30 30 05 00 84 7A 32 30 30 04 00 83 37 30 30 03 00 82 30 30 03 00 82 30 30 02 00 81 30

数据长度不等于宽*高,但看起来很有规律,因为一些XX 00的数据,个数正好是图片高度,且其后的数据长度正好等于他,且数据里没有00数据...根据规律看也不是RLE压缩格式..如果去掉XX 00这些数据后,数据长度也小于宽*高.看似象压缩格式,但数据里重复的还很多.这个问题困扰我一年了,不知大家看到过这种格式的图片格式吗?只需告诉我规律,我会自己编程来解析的...
声明:我确定是这是图片数据...因为游戏采用DIRECTX技术,无法动态跟踪到这里,要不早解出来了...

  • 标 题:答复
  • 作 者:smartbear
  • 时 间:2009-03-17 05:07:09

终于用双显示器实现了这个游戏的跟踪,通过跟踪发现,这是一种原始的透明图片的压缩方法。现将解析过程写出来和大家分享一下。

    因为透明图片的透明色只有一种,且可能在图片中大量存在,所以作者把这个色给舍掉了。所以图片的容量大大减小,而不是现有的压缩方法,将重复数用特殊标志来压缩。

   1、前两个DWORD为源图片宽高;
   2、数据第一个WORD为行开始,表示该行现有的BYTE数,并不是处理后的BYTE数。
      如果这个数为00 00,表示该行全是透明色,需要我们用透明色来填充,通过观察发现数据中无00数据,所以该色就是透明色了,我们可以用源图片宽数的00来填充,同时源行数加1。
   3、数据开始,数据中不允许出现00,(透明色嘛),第一个BYTE为标志位,分两种情况:
   1)如果<=0x7F,则表示要跳过多少个BYTE,即处理时需要你用多少个00来填充。
   2)如果>0x7F,则表示其后的数据为源数据,数据的长度为该BYTE & 0x7F,即减去0x80,不信大家可以演算一下。
   处理完后,如果不到行尾,则重复1)、2)步,如何判断呢?当然是该行生成的BYTE数和源图片的宽来比较。如果到行尾,生成的BYTE数小于源图片的宽度,后面补00。
   4、如果行数==源图片的高,则处理结束。

举例:
03 00 82 D8 58
04 00 83 E7 D5 58
05 00 06 83 E7 DB D5 

   D8 58 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   E7 D5 58 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   00 00 00 00 00 00 E7 DB D5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00


   dwWidth  dwHeight  wSize (bFlags bits ...) wSize ....

看过图片解析(一)的朋友,看完后会说,原来这么简单呀,确实,跟踪处理过程后看,确实简单,但如果不好跟踪,光从数据上看,没几个人能看出规律来...下面还有一些图片,又采用了不同的算法进行了压缩,到目前为止,还没跟踪上,先和大家静态分析一下:
000006b4h: 53 4E 50 53 03 00 00 08 76 1A 00 00 7C 07 00 00; SNPS....v...|...
这是一个图片的定位方法.
第一个DWORD,是ASCII标识
第二个DWORD,如果是00000000话,是普通图片,如果是0000000C的话,图片解析一已经破解,03 00 00 08新格式图片...
第三个DWORD,是该图片所依赖的调色板在文件中的偏移量(通过观察发现这个调色板只有0x80长度,可以从点入手)
第四个DWORD,是该图片开始位置在文件中的偏移量

开始图片数据:
前两个DWORD仍为图片的宽高
1B 00 00 00 17 00 00 00 06 0A 81 60 04 81 80 8E 00 00 00 00 08 60 80 95 07 00 90 00 00 00 0D 07
81 80 02 89 55 65 48 85 50 01 81 60 0C 05 81 60 01 8E 85 55 84 82 85 58 55 8E 00 00 05 88 88 83
33 44 44 88 58 08 00 00 8E 00 06 05 88 34 31 11 11 12 43 45 58 00 00 8E 00 56 05 C4 22 23 22 21
22 12 43 8C 56 00 0D 03 96 58 A3 42 35 84 42 43 22 12 33 C8 8E 88 5B 8C 46 85 54 54 45 44 32 12
43 8C 00 8E 08 55 55 48 55 88 45 54 64 44 21 12 85 00 8E 00 8A 84 85 85 85 55 58 44 53 32 21 8C
00 8E 08 EB E8 85 85 5B 55 53 55 54 51 13 58 C0 8E 85 0E EE 55 65 88 55 88 85 55 32 22 58 00 8E
00 EE CB 45 45 55 88 58 85 88 32 54 85 00 8E 0A CC 8C E6 58 B8 88 88 88 85 44 18 48 50 8E 0B 58
0B 8C E6 88 88 5B B8 84 55 85 50 00 8E B0 00 58 8B 86 84 58 85 88 55 5B 85 05 00 8E 00 08 98 08
88 8B FC 88 9C 5B 88 86 00 00 0C 06 93 A8 BC 8B E8 58 FE 5B 8B 58 50 8E 00 00 00 05 80 88 E5 85
88 4C 55 00 80 00 8E 00 00 00 5C 00 8E 08 05 EC 85 50 80 00 00 8E 00 00 00 00 00 C0 05 08 0C 08
00 00 00 00 06 0F 81 60 04 81 60

图片中有大量00数据,且长度都不一样,应该不是什么特殊标识了...调色板长度虽然只有0x80,但数据中却有大于这个值出现,有可能是特殊标识...看规律不象是RLE8格式...大家和我共同分析一下吧...

  • 标 题:答复
  • 作 者:smartbear
  • 时 间:2009-03-25 22:53

又成功解析出该格式的图片.
附一张解析出来的图片(本来为BMP格式,上传时不允许,才转成GIF格式的:


这种图片看起来很不错,但有没有想到其中只用了16种颜色...我真佩服作者,用16种颜色就能把图片做得这么逼真...

由于只用了16种颜色,所以一个字节可以表示源码的两个字节,所以解析后图片流中不可能出现大于0x10的数据...
每行的第一个BYTE确实为本行的长度nSizeLine,不过有些说法...
  (1) 如果nSizeLine>0x7f,则表示本行为源码,行长度为nSizeLine&0x7F,其后的每个BYTE中的4位为源码...
  (2) 如果nSizeLine<=0x7f,则表示本行内0多,其后的数据中有标志位的...如果标志位nflags > 0x7f,表示其后为源码,解析方法同(1),如果nflags<0x7f,表示有nflags个0...

例子,图片宽1B:(数据均为16进制表示法):
06 0A 81 60 04 81 80//06为本行的长度
   00 00 00 00 00 00 00 00 00 00 06 00 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00
    //0A个00, 81 60为什么为变成06,81表示其后有一个源码,60解析成两位06 00由于只有一个有效的源码,所以00舍掉,04个00, 81 80,同理,解析为1个08
0C 05 81 60 01 8E 85 55 84 82 85 58 55//0C为本行的长度 
   00 00 00 00 00 06 00 08 05 05 05 08 04 08 02 08 05 05 08 05 05 00 00 00 00 00 00
    //5个00,1个06,1个0,0E个源码...
8E 00 00 00 00 08 60 80 95 07 00 90 00 00 00//本行的长度为8e & 0x7f = 0E
   00 00 00 00 00 00 00 00 00 08 06 00 08 00 09 05 00 07 00 00 09 00 00 00 00 00 00  
   //全是源码,均是一变二

  • 标 题:答复
  • 作 者:smartbear
  • 时 间:2009-04-01 20:19

图片虽然只用了0x10种颜色,但调色板长度是0x80.为什么呢?因为这个游戏是用颜色来区分玩家的.根据玩家选择的颜色来定位调色板的初始索引值.如:
color  n
兰    0
红    1
黄    2
...
青    7
pPal += n * 0x10;

这样就用一个调色板实现了8种部队色的变化...作者很强...