SWF标签解析
一、结构
SWF文件是由一个一个的标签紧挨着而构成的这与HTML文件结构类似。
FlashPlayer在读到能识别的标签时就会执行对应的逻辑,读到不能识别的标签就直接跳过,因为每个标签带有标签字节长度的信息,在不处理标签时候能准确跳过,这个HTML则是用<>来标记标签的开始和标签的结束,它的好处在于保证了SWF文件的扩展性和运行时的稳定性。
比如:
<html>
<body>
<li>abc
<test>abc
abc
我们可以看到在浏览器运行结果如下:
当浏览器解析到test标签时无法识别所以显示结果里test标签所包括的内容未被进行任何处理。它也不会影响到后面b标签的任何显示。
唯一值得注意的是SWF的文件头内容不是按标签格式来编码,FileAttributes Tag标签固定为第一个标签End Tag标签固定为最后一个标签表现如下:
[Header][FileAttributes Tag][任意标签][任意标签][任意标签]。。。。[End Tag]
二、SWF头信息Header
swf头信息在文档里的介绍swf头部信息格式如下
Signature UI8 有可能是F或C所代表的ascii码值
Signature UI8 永远是W所代表的ascii码值
Signature UI8 永远是S所代表的ascii码值
version UI8 flash版本
FileLength UI32 文件长度(解压后的)
FrameSize RECT 文件宽高FrameRate UI16 帧率
FrameCount UI16 帧数
其中值得说明的是SWF文件前8位一定是未压缩的,之后得内容就根据前3个字节的ascii码是FWS还是CWS,如果是CWS的话就表明8个字节后的内容要进行解压缩一下,FWS标识表示该文件是未压缩文件,在flash我们只要调用byteArray的uncompress就好了。
当读到FileLength的时候我们要注意一下,我们从swf文件读出来的字节内容可能是 FF 00 00 00这样的4个字节单我们要解除实际值时需要吧顺序调转一下即为 00 00 00 FF,也就是说FF 00 00 00代表得值为255,当所要读的数据内容是超过1个字节的基本数据类型时就要用此规则来解除实际值。
接着来看RECT,在文档内的介绍的格式如下:
NbitsUB[5] Bits in each rect value field
XminSB[Nbits] x minimum position for rect
XmaxSB[Nbits] x maximum position for rect
YminSB[Nbits] y minimum position for rect
YmaxSB[Nbits] y maximum position for rect
比如我们在SWF读到所对应的字节数据如下:
78 00 05 5F 00 00 0F A0 00
78 01111000
00 00000000
05 00000101
5F 01011111
00 00000000
00 00000000
0F 00001111
A0 10100000
00 00000000
前5位是01111 = 15 即代表后面的 XminXmaxYminYmax的值为紧跟着的数据里分成15位 15位 15位 15位 所代表的值 Xmin = 0 000000000000000 ,Xmax = 11000 / 20 = 550 010101011111000 (文档里的说明是,swf文件里都是用twips代表尺寸的 20twips = 1像素) ,Ymin = 0 000000000000000,
Ymax = 8000 / 20 = 400 001111101000000,然后我们可以看到还剩7位数值0000000 这7位数值是否有用取决于紧接下来的数据结构,如果接着表示的内容还是位数据的话,那这7位数据会用,如果是字节型数据那这7个数据不代表任何东西,比如紧接着的是ub[2]那么这7位数据拿2位出来填充ub[2]里,如果是UI8那会丢弃这7位数据继续从swf文件读多一个字节出来表示UI8的值,这个叫字节对齐。
三、SWF标签结构
紧跟SWF头部信息之后得就是SWF标签了,SWF标签分为2种,一种是短标签,一种是长标签。
短标签可以用2个字节即UI16就可以代表完,长标签要用6个字节即UI16 + SI32代表。
比如在SWF头部信息解析完后我们读个SI16出来是 68 17
进行倒序 17 68转成2进制 0001000101 000100
根据文档说明标签的SI16里前10位代表标签编号,后6位代表标签长度
根据这个例子 0001000101 = 69,000100 = 4;
即68 17 说明接下来的4个字节是标签编号69即FileAttributes的内容。
当标签内容超过62个字节也即6位数不够用时会将后面的4个字节用来代表标签的长度,这时SI16里的后6位全位1不代表任何东西,这个就称之为长标签。
基于这几点我们可以我们可以就可以写一个遍历SWF文件标签列表的程序了,把头信息解了,然后读取标签编号标签长度跳过标签长度个字节,继续读下一个标签的信息直到文件结尾。