(转载)SWF 文件分析(一)

原文:http://rcant.com/wordpress/archives/260

SWF 文件头分析 (一)

swf文件头包含的信息量巨大。告诉了人们SWF文件工作的方式方法等基本信息呵

Macromedia Flash文件格式是Macromedia Flash播放器在互联网上进行矢量图形和动画发布的文件格式。

SWF文件格式不是为图像编辑器之间共享图像而是为高效的解释格式设计的,它的设计是为了满足以下条件:

A:在屏幕上即时显示:此格式的最主要目标是在屏幕上即时显示和支持实例,彩色图像的快速播放,动画和交互式按钮。

B:可扩展性:此格式为标签式格式,因此其播放器能够通过增加新的特性来进行升级而兼容其播放器的早期版本。

C:网络发布:此格式能够在有限的网络资源和不可预测的网络状况下进行传输,文件被压缩到很小并且支持流式播放。SWF文件是一种二进制格式的文件,它不能像HTML文件一样可以直接阅读和理解。SWF文件使用了诸如位压缩、可选字段式结构等方法来减小文件的尺寸。

D:简易性:此格式简单的结构使Flash播放器变得很小且便于携带。另外,Flash播放器仅仅依赖操作系统特性中有限的集合。

E:文件独立性:文件的显示不依赖任何诸如字体之类的扩展资源。

F:可变性:文件能够在有限的硬件环境下很好的工作,而且能够尽可能的利用更好的硬件,这一点很重要,因为用户的计算机有着不同的显示器设置和色彩深度。

G:速度:文件能够以很快的速度和很高的质量播放。

H:支持脚本:此格式包含了约定格式的标签,标签规定了堆栈式机器解释字节码的顺序。字节码支持一种叫做ActionScript(动作脚本)的语言。Flash播放器规定了运行时的ActionScript(动作脚本)模式,此模式允许原始的绘制、服务和Flash播放器特性之间相互作用。

SWF文件的扩展名为.swf,它是一种MIME(多用途的网际邮件扩充协议)类型的应用程序(X-Shockwave-Flash)。

SWF格式经历了若干个版本。在第5个版本中,SWF的标签设置经过了一次较大规模的充实和完善。从第6个版本之后,文件格式变化较小,例如仅在ActionScript中越来越多的Flash新特性部分或者完全的被实现。因此,如果打算增加SWF文件中使用较新特性的内容,那么就应该熟悉Flash播放器提供的ActionScript对象模型,对于这些最好的参考是OReilly的《ActionScript: the Definitive Guide》,由科林·莫克出版社出版。

SWF文件头:所有的SWF文件均以以下头部开始:

我们先看下关于SWF文件头的官方说明

区域 数据类型 数据类型

标识

UI8(8位二进制无符号整数)

“F”表示该文件是未压缩的

“C”表示压缩文件(SWF6及后续版本支持)

标识 UI8 总是”W”
标识 UI8 总是”S”
版本 UI8 SWF文件版本
文件大小 UI32 文件字节大小
画面尺寸 RECT twips为单位(单位帧的尺寸)
帧速 UI16 8.8形式的定点小数
总帧数 UI16 总帧数

文件头部是由一个三字节的标识符开始,为0×460×570×53(“FWS”)或者0×430×570×53(“CWS”)其中之一。“FWS”标识符说明该文件是未压缩的SWF文件,“CWS”标识符则说明该文件前8个字节之后(即文件长度字段之后)的全部数据为开源的标准ZLIB方式压缩。

ZLIB库所使用的数据格式在19501952年的请求注解, Internet标准文档(RFCS)中被详细说明。CWF文件压缩形式仅适用于版本6或者更高。

标识符之后是一个字节的版本号,这个版本号并不是一个ASCII码,而是一个8位的数字,比如,版本40×04标识,而不是ASCII码“4”(0×35)。

文件长度字段是整个包含文件头在内的文件字节长度,如果是未压缩的SWF文件(标识符FWS),那么长度字段应该是和文件大小恰好匹配,如果是一个经过压缩的SWF文件(标识符CWS),那么文件长度字段是指文件经过解压缩之后的总长度,因此它一般不会和文件大小匹配,使用未压缩的文件尺寸能够让解压过程获得更高的效率。

帧尺寸字段定义了影片的宽度和高度,它使用了RECT结构进行存储,这就意味着它的尺寸能够根据坐标编码所需的位数变化。帧尺寸的RECT结构使用的XY轴的最小值总为0。而XY轴最大值分别表示了宽度和高度(参阅位值的使用)

帧率是以帧每秒为单位的帧回放比率,此比率在SWF文件包含流式声音数据或者Flash播放器运行在低速CPU下时并不会得到保证。

帧数是整个SWF影片帧的总数量。

SWF文件结构

文件头之后是一系列连续的标签数据块,所有的标签都共享一种通用格式,因此任何解析SWF文件的程序都能跳过它不能识别的数据块。块内数据能够指向当前一个块内的偏移量,但不能指向其它数据块内的偏移量。这就使得标签能够被处理SWF文件的工具进行移除、插入或修改操作。

编写一个简单的SWF文件:

1
2
3
4
5
6
7
8
9
10
11
12
package
{
    import flash.display.Sprite;
    [SWF(width="240",height="120")]
    public class AS3Test extends Sprite
    {
        public function AS3Test()
        {
            
        }
    }
}

通过Release生成一个 SWF 文件:

Download

通过Hex Workshop 打开文件可以显示以下数据

一个简单的SWF的二进制数据:

OK了,对应着它我们来分析下刚才生成的文件

数据 含义
43 “C”,表示压缩的
57 “W”
53 “S”
0a SWF文件版本为10
44 03 00 00 文件大小为0×00000344836字节

可以看到 这是压缩过的,SWF的压缩方式 使用的是标准的ZLIB压缩的,所以可以使用7-ZIP打开刚才下载下来的压缩文件:

我们取出 分解出来的 SWF文件 
Download SWFTest_1.swf

右击其属性可以看到 他的文件大小是 836 字节的

通过Hex Workshop 打开文件可以显示以下数据
SWF的二进制数据:

分析:
首先: 前面 8 字节

数据 含义
43 “F”,表示未压缩的
57 “W”
53 “S”
0a SWF文件版本为10
44 03 00 00 文件大小为0×00000344836字节

接着分析 70 00 09 60 00 00 4B 00 00
第一个 字节 70 = 01110000
 5位(原因不明) 01110 = 14 表示定义位数
我们在重新算一下需要的数组数,4xmin,xmax,ymin,ymax)×14(定义位数的值)+5(定义位数)6161/8= 7.625
接着   8 

读取 70 00 09 60 00 00 4B 00
换成2进制  0111 0000 0000 0000 0000 1001 0110 0000 0000 0000 0000 0000 0100 1011 0000 0000
接着按位排列下: 01110 00000000000000 01001011000000 00000000000000 00100101100000 000
代表的意义: (定义位数)(xmin=0 xmax=4800 (ymin=0) (ymax=2400) (多余的)
得到的值 width = (xmax-xmin)/20 ; height = (ymax-ymin)/20; 为什么 要除以 20,我也不是很懂哦。
最后得到的 SWF 文件的尺寸大小:240×120;

接着是帧频:00 18 ,表示帧频为 24
然后是帧数:01 00 ,这个也要倒序来算 所以是 00 01,是1
这就是所有的SWF文件头的内容,接下来的内容就是SWF的真正内容了
请见 SWF 文件分析(二)讲解

原文地址:https://www.cnblogs.com/finger/p/2519595.html