SWF変換を行う前にSWFのSDKを熟読する必要がある。
Adobeサイトで公開されている事は知っているが、今までまともに読んだことが無かった。
ググってみると、偶然に知り合った
yoyaさんのサイトが山のように出てくる。
どうやら、最近まあまあ流行っているらしいFlash変換エンジンの技術の入り口に立てたようである。
SWFデータのdump
yoyaさんのブログを見ると載っているソースコードを利用して、local環境でSWFファイルの内容をdumpして見てみたいと思う。
ライブラリと実行プログラムの2つが必要なので、下記を作成
dump.php
yoyaさんのソースですが、冒頭の箇所はswfファイル指定できるように改造しています。
<?php
/**
* reference : http://labs.gree.jp/blog/2010/08/631/
* write : yoya
* [sample]
* php dump.php [target-swf-file(*hoge.swf)]
**/
if(!$argv[1]){
echo "error".PHP_EOL;
exit();
}
$swfFile = $argv[1];
require_once "BitReader.php";
$swfdata = file_get_contents($swfFile);
$reader = new BitReader;
$reader->input($swfdata);
/* SWF Header */
echo 'Signature: '.$reader->getData(3).PHP_EOL;
echo 'Version: '.$reader->getUI8().PHP_EOL;
echo 'FileLength: '.$reader->getUI32LE().PHP_EOL;
echo 'FrameSize: '.PHP_EOL;
$NBits = $reader->getUIBits(5);
echo "\tXmin: ".($reader->getUIBits($NBits) / 20).PHP_EOL;
echo "\tXmax: ".($reader->getUIBits($NBits) / 20).PHP_EOL;
echo "\tYmin: ".($reader->getUIBits($NBits) / 20).PHP_EOL;
echo "\tYmax: ".($reader->getUIBits($NBits) / 20).PHP_EOL;
$reader->byteAlign();
echo 'FrameRate: '.($reader->getUI16LE() / 0x100).PHP_EOL;
echo 'FrameCount: '.$reader->getUI16LE().PHP_EOL;
/* SWF Tags */
echo 'Tag:'.PHP_EOL;
while (true) {
$tagAndLength = $reader->getUI16LE();
$type = $tagAndLength >> 6;
$length = $tagAndLength & 0x3f;
if ($length == 0x3f) {
$length = $reader->getUI32LE();
}
echo "\ttype: $type length: $length".PHP_EOL;
$contents = $reader->getData($length);
if ($type == 0) { // END Tag
break;
}
}
exit(0);
BitReader.php
yoyaさんのライブラリをそのまま掲載しています。
SWFバイナリ編集のススメ第一回
<?php
class BitReader {
var $_data; // input_data
var $_byte_offset;
var $_bit_offset;
function input($data) {
$this->_data = $data;
$this->_byte_offset = 0;
$this->_bit_offset = 0;
}
function byteAlign() {
if ($this->_bit_offset > 0) {
$this->_byte_offset ++;
$this->_bit_offset = 0;
}
}
function getData($length) {
$this->byteAlign();
$data = substr($this->_data, $this->_byte_offset, $length);
$data_len = strlen($data);
$this->_byte_offset += $data_len;
return $data;
}
function getUI8() {
$this->byteAlign();
$value = @ord($this->_data{$this->_byte_offset});
$this->_byte_offset += 1;
return $value;
}
function getUI16LE() {
$this->byteAlign();
$ret = @unpack('v', substr($this->_data, $this->_byte_offset, 2));
$this->_byte_offset += 2;
return $ret[1];
}
function getUI32LE() {
$this->byteAlign();
$ret = @unpack('V', substr($this->_data, $this->_byte_offset, 4));
$this->_byte_offset += 4;
return $ret[1];
}
function getUIBit() {
$value = @ord($this->_data{$this->_byte_offset});
$value = 1 & ($value >> (7 - $this->_bit_offset));
$this->_bit_offset ++;
if (8 <= $this->_bit_offset) {
$this->_byte_offset++;
$this->_bit_offset = 0;
}
return $value;
}
function getUIBits($width) {
$value = 0;
for ($i = 0 ; $i < $width ; $i++) {
$value <<= 1;
$value |= $this->getUIBit();
}
return $value;
}
function getImage() {
$this->byteAlign();
$ret = @unpack('v', substr($this->_data, $this->_byte_offset, 2));
return $this->_byte_offset;
}
}
実行
$ php dump.php hoge.swf
Signature: FWS
Version: 4
FileLength: 7031
FrameSize:
Xmin: 0
Xmax: 240
Ymin: 0
Ymax: 240
FrameRate: 10
FrameCount: 40
Tag:
type: 9 length: 3
type: 21 length: 2276
type: 2 length: 52
type: 26 length: 10
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 26 length: 7
type: 1 length: 0
type: 26 length: 7
type: 1 length: 0
type: 26 length: 7
type: 1 length: 0
type: 26 length: 7
type: 1 length: 0
type: 26 length: 7
type: 1 length: 0
type: 26 length: 7
type: 1 length: 0
type: 26 length: 4
type: 1 length: 0
type: 26 length: 7
type: 1 length: 0
type: 26 length: 7
type: 1 length: 0
type: 26 length: 7
type: 1 length: 0
type: 26 length: 7
type: 1 length: 0
type: 26 length: 7
type: 1 length: 0
type: 26 length: 7
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 26 length: 8
type: 1 length: 0
type: 28 length: 2
type: 21 length: 4090
type: 22 length: 94
type: 26 length: 6
type: 1 length: 0
type: 0 length: 0
Tag-typeがたくさん表示されるが、SWFは上部の固定HEADER部分とコンテンツ内容でもあるTag部分の2ブロック構成なのである。
Header詳細
Headerは非常に簡単な構成で、バイナリファイルとしてもアドレス固定なので、分解はし易いと思います。
Signature
「FWS」と「CWS」の2パターンしか存在せず、分かりやすい情報です。
SWFをパブリッシュする時に「圧縮」オプション設定がされているかどうかの判別用です。
圧縮されている場合はTag部分が圧縮されているので解凍処理を行なってから分析しなければいけないので、CWSは面倒くさいとおぼえておきましょう。
FWS:非圧縮
CWS:圧縮
Version
Flash-version
FileLength
データ長
FrameSize
SWFの画面サイズ
Xmin: 0
Xmax: 240
Ymin: 0
Ymax: 240
FrameRate
指定されたフレームレート
FrameCount
フレーム数
Tags
画像や動画、音声などの情報や、フレームやshape情報、ActionScript情報などが格納されているので、ここの中を整理することで、SWFの解析ができるという事なんですね。
各種link
Adobe SWF SDK
Flash SWF バイナリ
他にも有志はたくさんいますが、上記サイトでかなり深いところまで勉強できます。
※yoyaさんのソースコードにはお世話になっています。
0 件のコメント:
コメントを投稿