swf 解析

简介: 引用:http://blog.sina.com.cn/s/blog_6859df370100wtk4.html 概述 SWF 文件是由一个文件头,和跟在后面的一系列的标签组成。标签有定义型标签和控 制型标签两类。

引用:http://blog.sina.com.cn/s/blog_6859df370100wtk4.html

概述

SWF 文件是由一个文件头,和跟在后面的一系列的标签组成。标签有定义型标签和控

制型标签两类。定义型标签把对象定义为角色存储在字典里,控制型标签操作这些角色并控

制影片的流程。

如下图

swf文件格式解析(二)

上回合已经解析完文件头 本会合接着解析Tag

首先,官方理论知识补充

定义型标签和控制型标签

Swf 文件有两类标签:定义型和控制型

A定义型标签定义SWF 文件的内容如Shapes、文本、位图、声音等等。每一个标签会为

定义的内容分配一个唯一的编号称做角色编号(character ID)。之后Flash Player 将角色

character)存储在称作字典(dictionary)的仓库。定义型标签本身不产生渲染。

B控制型标签创建和操作已渲染的字典中角色的实例,同时控制文件流程。

 

SWF文件的处理过程

Flash Player 会处理所有的标签直到遇到ShowFrame 标签。此时,显示列表被复制到屏

幕,然后播放器继续处理直到下一帧需要显示。第一帧的内容累计了第一个ShowFrame 

签之前所有控制型标签的执行结果,第二帧的内容累计从文件开始到第二个ShowFrame 

签的所有控制标签的执行效果,以此类推。

 

长标签和短标签

Tag分为长标签跟短标签

这个有一个官方的介绍

每一个标签的开始都是标签的类型和长度。标签头可以是短标签头类型也可以是长标签

头类型。短标签头类型用于数据在62 字节之内的标签。如果标签的数据长度不超过62 个字

节使用短标签。而长标签头类型可以用于数据在4G 之内的任何标签。

 

标签头记录(短类型)

字段

类型

说明

TagCodeAndLength

UI16(两个字节)

10 位表示标签类型

6 位表示标签长度

 

注意事项:

TagCodeAndLength 字段是一个两个字节的字,而不是一个10 位的字段跟随一个6

位字段。SWF 使用低位在前(little-endian)造成上述两种情况是不同的。

(ps:如果TagCodeAndLength 字段的十六进制是44 11 那么实际上的值是11 44 

进制为00010001 0100010010 位的值是69 表示这是一个FileAttributes

签)

标签的长度不包括标签头记录自己的长度,仅表示其后面数据的长度。

长标签

标签头记录(长类型)

字段

类型

说明

TagCodeAndLength

UI16(两个字节)

10 位表示标签类型

6 位始终为0x3F111111

Length

SI32

标签的长度

在开始解析之前,我引用一下swf_file_format_spec_v10白皮书中关于标签字段数值跟类型的对应表

 

Tag value Tag name

0 End

1 ShowFrame

2 DefineShape

4 PlaceObject

5 RemoveObject

6 DefineBits

7 DefineButton

8 JPEGTables

9 SetBackgroundColor

10 DefineFont

11 DefineText

12 DoAction

13 DefineFontInfo

14 DefineSound

15 StartSound

17 DefineButtonSound

18 SoundStreamHead

19 SoundStreamBlock

20 DefineBitsLossless

21 DefineBitsJPEG2

22 DefineShape2

23 DefineButtonCxform

24 Protect

26 PlaceObject2

28 RemoveObject2

32 DefineShape3

33 DefineText2

34 DefineButton2

35 DefineBitsJPEG3

36 DefineBitsLossless2

37 DefineEditText

39 DefineSprite

43 FrameLabel

45 SoundStreamHead2

46 DefineMorphShape

48 DefineFont2

56 ExportAssets

57 ImportAssets

58 EnableDebugger

59 DoInitAction

60 DefineVideoStream

61 VideoFrame

62 DefineFontInfo2

64 EnableDebugger2

65 ScriptLimits

66 SetTabIndex

69 FileAttributes

70 PlaceObject3

71 ImportAssets2

73 DefineFontAlignZones

74 CSMTextSettings

75 DefineFont3

76 SymbolClass

77 Metadata

78 DefineScalingGrid

82 DoABC

83 DefineShape4

84 DefineMorphShape2

86 DefineSceneAndFrameLabelData

87 DefineBinaryData

88 DefineFontName

89 StartSound2

90 DefineBitsJPEG4

91 DefineFont4

 

 

下边继续分析我们上一回合那个swf

重新用Hex workshop打开,截一张图

swf文件格式解析(二)

 

第一个标签:
记录头部 44 11 11 44 0001000101 000100
因为 000100!= 111111 所以是短格式而且这个标签的长度为 4 ,标签的类型为 69 FileAttributes(文件属性),(貌似是从swf6之后第一个标签都是这个FileAttributes

内容是19 00 00 00

 

继续分析下第二个标签,这是一个长标签,注意跟短标签有什么不同
记录头部 7f 13 13 7f 0001001101 111111
因为 111111 所以是长格式取后四位(因为lengthSI32CB 01 00 00(作为这个标签的长度 0x000001CB = 459 ,标签的类型为 77
属性是 Metadata 内容为后边459个字节

.

.

.直到最后的结束标签

记录头部:00 00 = 00 00 = 0000000000 000000
短标签:标签长度为0,标签类型为0
标签属性:End
标签头  内容(内容为空)为 00 00

下边的标签就不一一赘述,按照这种方式都可以一一解析完毕

其中最重要的一个标签为82 DoABCActionscript ByteCode)标签 AVM2中执行as代码的地方,这个TAG解析是一件非常浩大的工程,很多前辈都放弃了,如果我有生之年有遗力,一定单独解析一下,以了却那么多前辈的心愿

 

对应上边的表格 我们可以查到SymbolClass对应的编号为76,我们想得到swf中的链接类其实就是重点解析SymbolClass这个Tag

 

下边理论上分析一下SymbolClass

 

先看以下官方白皮书介绍

SymbolClass

The SymbolClass tag creates associations between symbols in the SWF file and

ActionScript 3.0 classes. It is the ActionScript 3.0 equivalent of the ExportAssets tag. If the

character ID is zero, the class is associated with the main timeline of the SWF. This is how the root class of a SWF is designated. Classes listed in the SymbolClass tag are available for

creation by other SWF files (see StartSound2, DefineEditText (HasFontClass), and

PlaceObject3 (PlaceFlagHasClassName and PlaceFlagHasImage). For example, ten SWF files that are all part of the same website can share an embedded custom font if one file embeds and exports the font class.

 

这个无非就是介绍了导出类的概念 以及导出类可以被其他swf调用等等,这个都不难理解

之后就是ADOBE 坑爹的一段,为了澄清我对他的污蔑,我把它的白皮书直接截图下来

swf文件格式解析(二)

上边是解释symbolclass的一个表格 意思就是

这个tag的组成部分由 header(symbolclass这标签)+NumSymbols(这个标签导出类的数量占两个字节)+类一ID+类一名字(字符串格式)N ID+ N名字。

于是 我就按照这个形式一个字节一个字节解析,结果解析了半下午啊

尼玛我这看来看去啊!!

白皮书很值得信任有木有啊!!

哥一个字一个字翻译有木有啊!!!

英文不好的程序员伤不起啊!!

 

到后来,还是用Hex workshop 一个字节一个字节自己的看16进制

 

上截图

 

swf文件格式解析(二)

 

 

 

两个类之间跟不仅仅是一个两个字节的Tag ID

尼玛明明有三个字节啊!!!!!!

 

好了,咆哮之后淡定,我这理解就就是adobe白皮书的一个错误,据过来人说白皮书中有三四处错误,

如果是我冤枉ADOBE了,谁给我指正 在下同样感激涕零…..

 

 

以下是用AS3写的一个对SymbolClass解析,包括之前文件头的解释 源码如下

 

package symbolClass

{   

import flash.display.Sprite;

import flash.utils.ByteArray;

import flash.utils.Endian;

 

import flashx.textLayout.elements.InlineGraphicElement;

 

public class ByteArrayTest extends Sprite

{   

 

[Embed(source = "mainCity.swf", mimeType="application/octet-stream")]

private var TestSwf:Class;  

private var _swfByteArray:ByteArray = new ByteArray; 

    

private const COMPRESSED:String = "CWS"; 

private var _swfSize:int; 

private var _frameRate:int; 

private var _frameTotal:int; 

private var _version:int; 

 

private var TestClass:Class

public function ByteArrayTest()

{       

super();     

var tempByteArray:ByteArray = new TestSwf();

//是否 压缩  

var compressed:String = tempByteArray.readUTFBytes(3);

 

//swf 版本

_version = tempByteArray.readByte();

 

//

var length:uint = tempByteArray.readUnsignedInt();   

 

tempByteArray.position = 8; 

tempByteArray.readBytes(_swfByteArray); 

 

            

if(compressed == COMPRESSED)

{

_swfByteArray.uncompress(); 

}  

_swfByteArray.endian = Endian.LITTLE_ENDIAN;

// 解析 swf 宽度 高度 数据 rect 数据

_swfSize = _swfByteArray.readUnsignedByte()>>3;

 

_swfByteArray.position = Math.ceil((_swfSize*4)/8+5);// 计算 rect 结束位置

trace(_swfByteArray.position); 

_frameRate = _swfByteArray.readShort()/256;//读取帧频 因为低8位是小数,所以需要除以2的8次方

 

_frameTotal = _swfByteArray.readShort();//读取 总帧数

 

trace("compressed:",compressed,"swf_version:",_version,"frameRate:",_frameRate,"frameTotal:",_frameTotal);

parseTagType();   

   

 

 

private function parseTagType():void

{     

//设置读取数据的字节顺序为倒序(以字节为单位)

_swfByteArray.endian = Endian.LITTLE_ENDIAN; 

while(_swfByteArray.bytesAvailable)

{

var tagHead:int = _swfByteArray.readShort();

var tagType:int = tagHead>>6;

 

     

//0x3F  00111111

var tagLength:int = tagHead & 0x3F;   

if(tagLength == 63) //如果tag 是长类型

{

tagLength = _swfByteArray.readUnsignedInt();

}

// 解析 symbolClass tag

if(tagType == 76) 

{   

parseSymbolClass(tagLength); 

}

else

{

_swfByteArray.position += tagLength;

}

}

}  

 

 

 

private var _classList:Array; 

private function parseSymbolClass(length:int):void

{

_classList = [];

var classNum:int = _swfByteArray.readShort();

while(classNum --)

{   

var classId:int = _swfByteArray.readUnsignedShort();

// trace("classId之后的位置是"+_swfByteArray.position);

var char:int = _swfByteArray.readByte(); 

var name:String = "";

while(char)

  

{    

name += String.fromCharCode(char);    

char = _swfByteArray.readByte(); 

}

                                trace("导出类名为"+name);

_classList.push(name);

}

 

 

上边那个例子嵌入了我自己的一个swf 大家可以换下自己的进行实验,会依次输出swf的类名 如下图

swf文件格式解析(二)

至于如

相关文章
|
JavaScript 前端开发 HTML5
PDF转图片,PDF转JPG/PNG,完全由JS实现
原理 使用pdf.js预览图片,pdf.js将pdf通过canvas将每一页渲染出来,然后我们通过canvas的toDataURL方法保存为jpg或png格式。pdf.js是Mozilla开源的一个js库,无需任何本地支持就可以在浏览器上显示pdf文档。
14267 1
|
JavaScript
js:通过正则表达式从base64编码的图片中获取扩展名
js:通过正则表达式从base64编码的图片中获取扩展名
185 0
|
移动开发 Linux HTML5
Linux下将swf文件用浏览器读取打开(html、html5嵌入swf格式文件)
Linux下将swf文件用浏览器读取打开(html、html5嵌入swf格式文件)
|
Java 文件存储 Maven
将PDF文件转换成PNG图片
有这样一个业务场景:需要在 WEB 页面中浏览 PDF 文件,PDF 文件存储在 FTP 服务器上,即 PDF 文件对外提供的访问地址的协议是 ftp 的。有如下几个硬条件、软需求的要求: - WEB 页面本身的可视区域不是很大; - 不想弹出对话框展示 PDF 文件; - 谷歌浏览器不支持在 http 协议的页面里内嵌 ftp 协议的路径; - 在 WEB 页面中使用系统默认的 PDF 阅读器的体验不是很好,滚动条啦,边框啦。
281 0
|
存储 算法 Android开发
聊一聊几种常用web图片格式:gif、jpg、png、webp
在大多数的web页面中,图片占到了页面大小的60%-70%。因此在web开发中,不同的场景使用合适的图片格式对web页面的性能和体验是很重要的。图片格式种类非常多,本文仅针对几种web应用中常用的图片格式:gif、png、jpg、webp进行一个基本的总结。
|
JavaScript 内存技术
HTML加载FLASH(*.swf文件)详解
HTML加载FLASH(*.swf文件)详解引言在web项目中经常会遇到在线浏览word文档,通常解决方法将word转换成pdf,然后在线浏览,但是在实际实现过程中,由于阅读器的原因,用户可以直接下载该pdf,这显然不是我们想要的,通过网络搜索,发现可以将word文档转换成swf文件,通过flash实现在线浏览,本文将详细介绍具体实现的方法。
1842 0