SWF标签解析

发表于2016-03-24
评论0 5k浏览

一、结构

SWF文件是由一个一个的标签紧挨着而构成的这与HTML文件结构类似

FlashPlayer在读到能识别的标签时就会执行对应的逻辑读到不能识别的标签就直接跳过因为每个标签带有标签字节长度的信息在不处理标签时候能准确跳过这个HTML则是用<>来标记标签的开始和标签的结束它的好处在于保证了SWF文件的扩展性和运行时的稳定性

比如:

<html>

<body>

<li>abc

<test>abc

abc

我们可以看到在浏览器运行结果如下:

http://top.oa.com/captures/201206/1339988095_32.jpg

当浏览器解析到test标签时无法识别所以显示结果里test标签所包括的内容未被进行任何处理。它也不会影响到后面b标签的任何显示。

 

唯一值得注意的是SWF的文件头内容不是按标签格式来编码FileAttributes Tag标签固定为第一个标签End Tag标签固定为最后一个标签表现如下:

[Header][FileAttributes Tag][任意标签][任意标签][任意标签]。。。。[End Tag]

 

二、SWF头信息Header

swf头信息在文档里的介绍swf头部信息格式如下

Signature UI8 有可能是FC所代表的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我们只要调用byteArrayuncompress就好了。

 

当读到FileLength的时候我们要注意一下我们从swf文件读出来的字节内容可能是 FF 00 00 00这样的4个字节单我们要解除实际值时需要吧顺序调转一下即为 00 00 00 FF,也就是说FF 00 00 00代表得值为255当所要读的数据内容是超过1个字节的基本数据类型时就要用此规则来解除实际值。

 

接着来看RECT在文档内的介绍的格式如下:

Nbits UB[5] Bits in each rect value field

Xmin SB[Nbits] x minimum position for rect

Xmax SB[Nbits] x maximum position for rect

Ymin SB[Nbits] y minimum position for rect

Ymax SB[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 即代表后面的 Xmin Xmax Ymin Ymax的值为紧跟着的数据里分成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 = 69000100 = 4;

68 17 说明接下来的4个字节是标签编号69FileAttributes的内容

当标签内容超过62个字节也即6位数不够用时会将后面的4个字节用来代表标签的长度这时SI16里的后6位全位1不代表任何东西这个就称之为长标签

基于这几点我们可以我们可以就可以写一个遍历SWF文件标签列表的程序了把头信息解了然后读取标签编号标签长度跳过标签长度字节继续读下一个标签的信息直到文件结尾

 

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引