惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Project Zero
Project Zero
N
Netflix TechBlog - Medium
P
Privacy International News Feed
Cisco Talos Blog
Cisco Talos Blog
Recorded Future
Recorded Future
C
Cybersecurity and Infrastructure Security Agency CISA
The Register - Security
The Register - Security
P
Palo Alto Networks Blog
GbyAI
GbyAI
量子位
Simon Willison's Weblog
Simon Willison's Weblog
Cyberwarzone
Cyberwarzone
M
MIT News - Artificial intelligence
T
Threatpost
腾讯CDC
MyScale Blog
MyScale Blog
P
Privacy & Cybersecurity Law Blog
罗磊的独立博客
博客园 - 叶小钗
V
V2EX
美团技术团队
NISL@THU
NISL@THU
Y
Y Combinator Blog
Google DeepMind News
Google DeepMind News
C
Cisco Blogs
C
CXSECURITY Database RSS Feed - CXSecurity.com
Google Online Security Blog
Google Online Security Blog
PCI Perspectives
PCI Perspectives
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
爱范儿
爱范儿
G
Google Developers Blog
博客园 - Franky
P
Proofpoint News Feed
T
The Blog of Author Tim Ferriss
B
Blog
Spread Privacy
Spread Privacy
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Latest news
Latest news
The GitHub Blog
The GitHub Blog
T
Threat Research - Cisco Blogs
D
DataBreaches.Net
F
Full Disclosure
L
LINUX DO - 热门话题
Stack Overflow Blog
Stack Overflow Blog
Scott Helme
Scott Helme
C
CERT Recently Published Vulnerability Notes
Jina AI
Jina AI
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
F
Fortinet All Blogs

博客园 - Hicome

CentOS6 安装svn Nagios的配置文件 ZT 创建 PHP 测试页 ZT 命令行手工备份Ubuntu系统的方法 还原Ubuntu系统备份的方法 ZT SHELL编程实例+条件判断总结 ZT DELL服务器结合nagios硬件监控、报警 ZT CentOS下内存使用率查看 ZT 怎样压缩swf文件? ZT 使用NDOUtils将Nagios监控信息存入数据库 ZT 电脑自动重启的原因几处理方法 ZT 通过rpm包安装、配置及卸载mysql ZT DVD+R与DVD-R有什么区别 ZT CentOS 5.5安装apache2.2.17 ZT CentOS 卸载apache ZT Trac 下设置发邮件问题 Centos 下PHP的卸载与安装 ZT mysql的一些操作命令 Nginx负载均衡 ZT 【M8】使用的一些小技巧 电话,短信,联系人,音乐等功能
swf文件格式解析入门(文件头解析)ZT
Hicome · 2011-05-13 · via 博客园 - Hicome

这里是使用as3语言来对swf文件做解析,其它语言可以参考。

一,准备工作
从Adobe官网下载一份swf文件格式说明文档
http://www.adobe.com/content/dam/Adobe/en/devnet/swf/pdf/swf_file_format_spec_v10.pdf
avm2虚拟机说明文档
http://www.adobe.com/content/dam/Adobe/en/devnet/actionscript/articles/avm2overview.pdf

采用flash builder新建一个项目。
// 嵌入测试的swf资源
[Embed (source = "../testswf/test.swf", mimeType = "application/octet-stream")]
private var content:Class;

// 初始化字节对象
var bytes:ByteArray = new content() as ByteArray;
// 设置为主机字节序
bytes.endian = Endian.LITTLE_ENDIAN;

二,开始解析工作
swf文件格式为:[header][FileAttributes tag][Tag][Tag]...[Endtag]
我们首先来解析header部分,如果这个部分会解析了,下面就很顺利了。
由于以上的文档都是flash player 9.0的时候写的,有部分10的特性没写在里面。
解析的时候如果遇到未知的类型,可以网上查查

1,解析文件头
swf文件是采用主机字节序

SWF File Header
Field           Type            Comment
Signature       UI8             Signature byte:
                                “F” 未压缩
                                “C” 压缩
Signature       UI8             固定为“W”
Signature       UI8             固定为“S”
Version         UI8             版本号 (如: 0x06 表示swf6)
FileLength      UI32            该swf文件的长度,单位:字节
FrameSize       RECT            swf的舞台大小,单位:twips 1px = 20twips
FrameRate       UI16            帧率,这里总共有16位,只有后面8位有效
FrameCount      UI16            总帧数

先读取3个字节的文件头
var sign:String = bytes.readUTFBytes(3);
if (sign != 'CWS' && sign != 'FWS')
    throw new Error ("文件头错误");
读取文件版本
version = bytes.readByte();
读取文件长度
fileLength = bytes.readInt();

如果文件签名是CWS,即是压缩过的,则需要进行解压缩
解压缩是从FrameSize这个地方开始到文件末尾
if (sign == 'CWS'){
    var tempBytes:ByteArray = new ByteArray();
    tempBytes.writeBytes(bytes, bytes.position);
    tempBytes.uncompress();
    
    var temp:int = bytes.position;
    bytes.length = bytes.position;
    bytes.writeBytes(tempBytes);
    tempBytes.length = 0;
    bytes.position = temp;
}

然后读取FrameSize

Bit Values 格式
Type        Comment
SB[nBits]   有符号位值 (nBits表示用多少位来存储这个值)
UB[nBits]   无符号位值 (nBits表示用多少位来存储这个值)

RECT 格式
Field       Type        Comment
Nbits       UB[5]       Bits used for each subsequentfield
Xmin        SB[Nbits]   x minimum position for rectangle in twips
Xmax        SB[Nbits]   x maximum position for rectangle in twips
Ymin        SB[Nbits]   y minimum position for rectangle in twips
Ymax        SB[Nbits]   y maximum position forrectangle in twips

第一个Nbits为5位长度的UB,这个值就是下面的[Nbits]值
这里就需要先写个函数,读取指定字节长度的值
注意:这里的单位都是twips 1px = 20twips
舞台的宽=Xmax-Xmin
舞台的高=Ymax-Ymin

/**
* 读取一定长度的位 
* 无符号的

* @param bytes 二进制序列
* @param bitStartPosition 开始读取的位置,从0开始算
* @param bitLength     读取长度
* @return 无符号数字

*/     
public static function readUBits(bytes:ByteArray, bitStartPosition:int, bitLength:int):uint
{
    var bitBuffer:int;
    var bitCursor:int;
    
    var remainLength:int;
    var result:uint=0;
    
    bitCursor= bitStartPosition % 8;
    bytes.position = bitStartPosition / 8;
    
    if (bitCursor == 0)
    {
        bitBuffer = bytes.readUnsignedByte();
        bitCursor = 8;
    }else{
        bitBuffer = bytes.readUnsignedByte();
        bitBuffer = bitBuffer & (0xFF >> bitCursor);
        bitCursor = 8 - bitCursor;
    }
    
    while(bytes.bytesAvailable > 0)
    {
        remainLength = bitLength - bitCursor;
        if (remainLength > 0){
            result = result | (bitBuffer << remainLength);
            bitLength -= bitCursor;
            bitBuffer = bytes.readUnsignedByte();
            bitCursor = 8;
        }else{
            result = result | (bitBuffer >>-remainLength);
            return result;
        }
    }
    
    return 0;
}


/**
* 读取一定长度的位 
* 有符号的

* @param bytes 二进制序列
* @param bitStartPosition 开始读取的位置,从0开始算
* @param bitLength 读取长度
* @return 有符号数字

*/     
public static function readSBits(bytes:ByteArray, bitStartPosition:int, bitLength:int):int{
    
    var result:int = readUBits(bytes, bitStartPosition, bitLength);
    
    var offset:int = (32 - bitLength);
    // 补齐符号位
    result = ((result << offset) >> offset);
    
    return result;
}


/**
* 读取rect结构

* @param bytes
* @param rect 如果传入,则使用该对象
* @return 

*/     
public static function readRect(bytes:ByteArray, rect:Rect = null):Rect
{
    if (rect == null)
        rect = new Rect();
    
    var start:int = bytes.position* 8;
    var length:uint = readUBits(bytes, start, 5);
    
    rect.xMinTwips = readSBits(bytes, start + 5, length);
    rect.xMaxTwips = readSBits(bytes, start + 5 + length, length);
    rect.yMinTwips = readSBits(bytes, start + 5 + length * 2, length);
    rect.yMaxTwips = readSBits(bytes, start + 5 + length*3, length);
    
    return rect;
}


然后读取帧率
bytes.position++;// 帧率后8位有效,跳过1个字节(8位)
frameRate = bytes.readByte();

读取总帧数
totalFrames = bytes.readShort();

文件头就解析完成了 

  转自:http://hi.baidu.com/rendong/blog/item/d6b9aad3dbd46425960a16e7.html