SWF文件格式探秘[一]

SWF文件格式探秘[一]
2008年12月21日 星期日 上午 08:43

    由于 Macromedia 公司为了推广 Flash,而将 SWF 的文件格式公开,使得 SWF 文件再无秘密可言,从而害得 SWF 文件的加密、解密软件层出不穷。今天上网闲逛,发现 Adobe 公司同样公开了 Flash9 与 Flash10 的 SWF 文件格式,下来一看,大叫不好,是英文版的!发现网上没有中文版下载,只有几篇谈论 SWF 文件格式的文章,索性自己也写一篇吧。首先提供下载链接:

Adobe官方SWF文件格式说明文档(pdf)下载:http://www.adobe.com/devnet/swf/pdf/swf_file_format_spec_v9.pdf
(注:包含9.0、8.0、7.0、6.0,最新的10.0需另下)

Adobe官方FLA文件格式说明文档(pdf)下载:http://www.adobe.com/devnet/flv/pdf/video_file_format_spec_v9.pdf

pdf文件阅读器(没有的朋友请下载)下载:http://www.duote.com/soft/12426.html

UltraEdit(用于查看和更改 SWF 文件)下载:http://www.duote.com/soft/68.html

    首先,我创建了一个默认的 SWF 文件,即舞台大小为 550*400,帧频为 12,背景为白色,仅一帧的文件。首先用 UltraEdit 打开这个文件,我们可以看见二进制的文件结构:

    每行自 ; 号以后(包括 ; 号)的字符都不用理会。首先给出 SWF 文件头的各属性列表:

字段            类型           说明
标识            8位             表示文件是否被压缩("46" F 为没有压缩,"43" C 为被压缩)。
标识            8位             总是 "57" W。
标识            8位             总是 "53" S。
版本号        8位             代表SWF文件的版本(如果是9,就为 "09")。
文件长度     32位           表示文件的大小。
帧大小        RECT结构 表示舞台的大小。
帧频            16位           每秒要播放的帧数。
帧数            16位           总共的帧数。

是否压缩标识:
    我们从 UltraEdit 中打开的文件来看,前 3 个字节为 46 57 53,即 FWS,Flash 默认情况下会压缩 SWF 文件,但是我们的文件为空,所以没有被压缩。

版本号:
    第四个字节为 09 表示是用 Flash9 制作的文件,注意是 16 进制,如果是 Flash12(如果有的话) 制作的,会显示 0C。

文件大小:
    第五个字符到第八个字符表示文件大小,为 24 00 00 00,注意是 16 进制,并且低位在前,表示文件大小是 36 个字节。这里有必要详细的介绍一下,这里表示的文件大小是没有压缩时的文件大小,如果文件被压缩过(前 3 个字节为 CWS 的话),这里的大小会和实际大小不一致,会大许多。

    再说说文件大小的算法,我专门搞了个没有压缩的文件,大小为 45023 字节(43.9KB),这里显示为 DF AF 00 00 (压缩后输出文件实际大小为 29.4KB,但是还是显示 DF AF 00 00 数字),那么它是怎么表示文件大小的呢?“16 进制,并且低位在前。”其实这句话已经告诉我们了,真正的文件大小为 00 00 AF DF 即把这四个字符反过来就行,去掉 0 即 AFDF,用计算器一看 AFDF 的十进制就是 45023。最大可显示 FF FF FF FF,这表示的大小是 4GB,即硬盘文件系统 FAT32 支持的单个文件最大的大小。

帧大小:
    接下来的是帧大小,表示舞台的大小,是文件头里最麻烦的了,网上资料暴少,官方文件说得太简单(其实是我英语水平太简单-_-!),先暂时放下,如果要看帧大小算法请点击这里。根据介绍可以推出帧频与帧数的地址。

帧频:
    提示为 16 位,且高位在前,得知地址为第二行的 1 和 2,即 00 0C,同样去掉 0,得 C,计算器转换为十进制为 12。

帧数:
    提示为 16 位,且低位在前,紧跟帧频就是第二行的 3 和 4 了,即 01 00,倒过来 00 01 转换后是 1。

    SWF 文件头介绍完了,但是我们发现文件还有近一半的数据,这是因为 SWF 文件头的各属性仅仅能提供 SWF 文件的基本属性,下面是一个 SWF 文件的基本构造:

FileAttributes 标签(必有标签):
    我们看见紧跟 Header(文件头) 的是名为 FileAttributes 的标签, FileAttributes 标签仅仅是 Flash8 及更早版本输出的 SWF 文件里必须的内容,但是也存在 Flash9 输出的 SWF 文件里。开始的 44 11 为其标签,后面紧跟的 08 00 00 00 为内容, FileAttributes 的标签前面的 08 比较复杂,包含 5 个属性,后面的 00 00 00 则是必须设置为 0。

SetBackgroundColor 标签(必有标签):
    背景色设定的标签,开始的 43 02 为其标签,后面紧跟的 FF FF FF 为背景色,为 RGB 格式,你可以改成 FF 00 00,另存为一个新 SWF 文件看看背景色是不是变成红色了。

ShowFrame 标签(必有标签):
    SWF 文件的倒数第二个标签,显示为 40 00。

End 标签(必有标签):
    SWF 文件的倒数第一个标签,显示为 00 00,表示文件已经结束。

注意:
    被压缩过的 SWF 文件(即第一个字符为 43)或被加密过的文件,是无法正常显示的,必须先将其解压,才能在 UltraEdit 里正常显示其 2进制 源码。
    被压缩过的 SWF 文件是从文件头之后开始压缩的,文件头能正常显示。

    自此,我们已经分析了一个完整的空白 SWF 文件的构成。

 

[补充]帧大小RECT结构算法
2008年12月21日 星期日 下午 09:29

    在 SWF文件格式探秘[一] 文章里没有说明 帧大小(指示舞台大小的RECT结构)的算法,这里给予补充,首先是默认的 SWF 文件(舞台大小为 550*400,帧频为 12,背景为白色,仅一帧)的二进制码:

    再是自定义的 SWF 文件(舞台大小为 2880*2880,帧频为 12,背景为白色,仅一帧)的二进制码:

    下面我们通过计算获取这两个文件的舞台大小:

默认文件:
    先获取第一行的 8 标签下的字符,即表示帧大小的第一个字符,是 78,用计算器将 16进制 的 78 转换为 2进制,得 1111000,一个字符有 8 位,补足 8 位,得 01111000,取前 5 个数字(为什么取前 5 个数字,请看官方文档里的说明),得 01111,去掉第一个 0 得 1111,用计算器将 2进制 的 1111 转换为 10进制,得 15,表示是按 15 个数字来进行分割。通过官方文档得知 RECT 结构为 UB[5](前 5 个数字)、SB[*](表示 Xmin)、SB[*](表示 Xmax)、SB[*](表示 Ymin)、SB[*](表示 Ymax)。而表示舞台大小时,Xmin 与 Ymin 都为 0,按 15 个数字来分割,共有 4 个 SB 要表示,即需要 15*4=60 个数字,至少要 8 个字符才能表示完,所以一共要取出 9 个字符:

取出:78 00 05 5F 00 00 0F A0 00

转换:01111000 00000000 00000101 01011111 00000000 00000000 00001111 10100000 00000000

分割:01111 000000000000000 010101011111000 000000000000000 001111101000000 0000000

    把最后的不足 15 个数字的 0 舍去,把上面分割后的数字用 10进制 转换得:

转换:15 0 11000 0 8000

    除第一个 15 不管外,这里的单位都不是像素,而是 twip(1像素 = 20twip),将其转换为像素得:

像素:0 550 0 400

    通过上面的转换,我们得出了默认的 SWF 文件(舞台大小为 550*400,帧频为 12,背景为白色,仅一帧)的舞台大小,对比一下,正确!

    为了保险,我们用同样的方法获取自定义的 SWF 文件(舞台大小为 2880*2880,帧频为 12,背景为白色,仅一帧)的舞台大小:

自定义文件:
    算法省去,算出按 17 个数字来分割,即需要 17*4=68 个数字,至少要 9 个字符才能表示完,所以一共要取出 10 个字符:

取出:88 00 01 C2 00 00 00 70 80 00

转换:10001000 00000000 00000001 11000010 00000000 00000000 00000000 01110000 10000000 00000000

分割:10001 00000000000000000 01110000100000000 00000000000000000 01110000100000000 0000000

    直接转换到像素大小得:

像素:0 2880 0 2880

    一切 OK!书面表达有限,不知道你搞懂没有,以上算法来自一篇文章,下面给出那篇文章的链接:http://hi.baidu.com/jlby/blog/item/680825f44e70d7ee7709d7ed.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值