Download presentation
Presentation is loading. Please wait.
Published byくうしょう はらしない Modified 約 8 年前
1
SWF Binary Hacks ~ eval のいばら道 ~ Shibuya.JS Technical Talk#3 – Shibuya.es 竹迫 良範
2
2 はじめに
3
3 謝罪 今日 Flex2 SDK を インストールしたばかり です 嘘言ってたらごめんなさ い
4
4 eval の発音について eval イーヴァルの検索結果 約 4 件 eval イヴァルの検索結果 約 11 件 eval エヴァル の検索結果 約 12 件 eval イーバルの検索結果 約 13 件 eval イバルの検索結果 約 13 件 eval エバルの検索結果 約 28 件 ※某 G 調査機関による調べによる
5
JavaScript でフォント名一覧を 取得する 3 つの方法 (1) IE 限定 (2) LiveConnect (3) Flash 利用 TAKESAKO @ Yet another CybozuLabs http://labs.cybozu.co.jp/blog/takesako/2007/03/javascript_getallfonts.html
6
6 (1) Dialog Helper Object でフォント名一覧取 得 <OBJECT id="dlgHelper " CLASSID="clsid:3050f819-98b5-11cf-bb82-00aa00bdce0b" width="0px" height="0px"> function getAllFontsByDialogHelper() { var fontslist = ''; try { for (var i = 1; i < dlgHelper.fonts.count; i++) { fontslist += dlgHelper.fonts(i) + '\n'; } catch(e) { fontslist = 'sorry, could not get fonts list.'; } return fontslist; }
7
7
8
8 ※動作するブラウザが激しく IE に限定される
9
9 (2) LiveConnect で Java アプレットを操作 function getAllFontsByLiveConnect() { var fontslist = ''; try { var fonts = java.awt.GraphicsEnvironment. getLocalGraphicsEnvironment().getAllFonts(); for (var i = 0; i < fonts.length; i++) { fontslist += fonts[i].getFontName() + '\n'; } catch(e) { fontslist = 'sorry, could not get fonts list.'; } return fontslist; } LiveConnect - Netscape3 以降の仕様 ( JavaScript1.1 ) - Firefox, Opera で動作 Java のオブジェクトを JavaScript から操 作 java.awt.GraphicsEnvironment#getAllFonts()
10
10 LiveConnect とは? できること Java のオブジェクトを JavaScript から操作できる その逆も 動作環境 Netscape3 以降( JavaScript1.1 )の仕様 Firefox, Opera で動作 使用できる条件 Java アプレットの実行が許可されているとき
11
11 (3) Flash の TextField.getFontList() を利用 var user_fonts = TextField.getFontList(); user_fonts.sort(); getURL('javascript:fontList("‘ + escape(user_fonts) + ‘“)’, '_self'); こんな感じで.as ファイルを作って getFontList.swf を作る
12
でも、いちいち swf ファイルを 作るの面倒だよなぁ … Flash ( ActionScript )で eval 使えたっけ?
13
13 SWF Binary Hacks ~ eval のいばら道 ~ 斜め下から始める 初めての Flash 斜め下から始める 初めての Flash
14
14 FlashProxy.swf で Flash 関数を動的実行 Collection & Copy - JavaScript 用 Flash プロキ シ、 Javascript Sound Kit ( id:brazil さん作) http://d.hatena.ne.jp/brazil/20060726/1153884951 Sound.methods = "loadSound start stop getId3 getPan setPan getTransform setTransform getVolume setVolume getDuration setDuration getPosition setPosition getBytesLoaded getBytesTotal".split(" "); function Sound(){ return new FlashProxy("Sound", Sound.methods); } var sound = new Sound(); : みたいな感じで JavaScript から Flash の関数を動的に呼び出すことができる
15
15 FlashProxy.as のソースコード( id:brazil さ ん) import flash.external.ExternalInterface; class FlashProxy{ static var proxy; var target; function FlashProxy() { this.target = new (eval(_root.className)); ExternalInterface.addCallback("dispatch", this, dispatch); ExternalInterface.addCallback("addListener", this, addListener); } function dispatch(prop, args) { var obj = this.target[prop]; if (obj instanceof Function) { return obj.apply(this.target, args); } return obj; } function addListener(event) { this.target[event] = function(){ ExternalInterface.call("FlashProxy.onTrigger", _root.id, event, arguments); } static function main(mc) { proxy = new FlashProxy(); }
16
16 お、 Flash で も eval できる?
17
17
18
18 なんか Flash にはいろいろ制限があるみたい import flash.external.ExternalInterface; class FlashProxy{ static var proxy; var target; function FlashProxy() { this.target = new (eval(_root.className)); ExternalInterface.addCallback("dispatch", this, dispatch); ExternalInterface.addCallback("addListener", this, addListener); } function dispatch(prop, args) { var obj = this.target[prop]; if (obj instanceof Function) { return obj.apply(this.target, args); } return obj; } function addListener(event) { this.target[event] = function(){ ExternalInterface.call("FlashProxy.onTrigger", _root.id, event, arguments); } static function main(mc) { proxy = new FlashProxy(); } この方法だと TextField.getAllFonts() や System.setClipboard みたいな スタティック関数の呼び出しができな い (インスタンスを直接生成できない abstract クラスのメソッド)
19
19 次のバージョンでは eval 自体廃止されちゃうし
20
20 JavaScript から Flash の スタティック関数を eval っぽく実行したい!
21
21 例えば Ruby の場合 … 3つの eval 関数があるのに! 1. ふつうの eval 2. Object#instance_eval 3. Module#module_eval/class_eval → 空前のメタプログラミング期ブーム
22
22 それ Flashy.swf でできるよ
23
23 それ Flashy.swf 使えばできるよ Javascript から Flash の任意の静的関数を 呼び出すことができる var flash = document.getElementById('flashy'); flash.setStatic('flash.system.IME.enabled', true); // IME オン Kazuho@Cybozu Labs: JavaScript から Flash の便利な機能を使う方法 http://labs.cybozu.co.jp/blog/kazuho/archives/2007/03/flashy.php
24
24 Flashy.as のソースコード(奥一穂さん) package { import flash.display.*; import flash.external.ExternalInterface; import flash.utils.getDefinitionByName; public class Flashy extends Sprite { public function Flashy() { ExternalInterface.addCallback("getClass", getClass); ExternalInterface.addCallback("getStatic", getStatic); ExternalInterface.addCallback("setStatic", setStatic); ExternalInterface.addCallback("callStatic", callStatic); } public function getClass(expr:String):Object { return getDefinitionByName(expr); } public function getStatic(expr:String):Object { var m:Object = expr.match(/^(.*)\.(.*?)$/); return this.getClass(m[1])[m[2]]; } public function setStatic(expr:String, value:Object):void { var m:Object = expr.match(/^(.*)\.(.*?)$/); this.getClass(m[1])[m[2]] = value; } public function callStatic(expr:String, args:Array):Object { var m:Object = expr.match(/^(.*)\.(.*?)$/); return this.getClass(m[1])[m[2]].apply(m[1], args); } スタティック関数の呼び出しを動的に (インスタンスを直接生成できない abstract クラスのメソッドも呼べ る)
25
Flash の関数を呼ぶだけじゃなく AS のコードを直接実行してみたい eval 使えないけど、どうする???
26
26 JavaScript で SWF を動的生成すればできる よ! <embed width="0px" height="0px" type="application/x-shockwave-flash" flashvars= " param=val" src="data:application/x-shockwave-flash;base64, Q1dTCbwDAAB42l1SQW/TMBS23a5uu5VtGqqGEFKlTaqE1CbtDmhVFzG1KxoHi uCCkCbqOm5j5iaR4y7dATEu/AROO8PP4IzEoTvwBzhx4R9wwE7G2mFF8nufv+ /zy3uegexPAO58BmAbgu7mPQDA+61vEIC2dEetF91eZTYRftTS2UHVUypsWVY cx/V4rx7IsdXY39+37KbVbNY0oxad+4rMan60U3USgy6LqOSh4oFfMTkZBlN1 UK1eu7r0xjScSpFYutRigk2YryKrUW9oI5e2RoGcEOWQMBScEmNnzWqRF9DTm Jyx2kiQyGtbC6LRKK4Ecw7dYMgqPcFmlWblcKFP2CnFkN1Foc7SbxKjrtNgYo UycKdU1zTSVol4WWIswulQ8Mhj0pn6p34Qp1csUMOhkhEV3Gb8w8y5IP54Ssb MOXqWnN3kSY1EMadp248se89q7qVFGKxt/dfra0SPzwHdjV+ZNuigj5dfXhf1 YJOFwKc3KIl+X95/t6nh78Uel5HqcEkFA1/vftCYYY8kmbAG2AB1gC4u/mCgw 9Ulainpfd3lUSjIee5lKLli+bEkocdpVBiyMfd7XIiiK0mcSjDzXQPliet2PC 7cXH/4llG1llqxMzP79SOzdbUtUVS3r9RNb0ipm8e+YpJQxc9YipRvnXcC/RC 5z+RKGZYz26i8CkoYIoyyGK5gmMMQY5jHsIBhEWfXMCphdAej9QxYXhCiQibp AkQQZiHQCcwXMnP7iYayqFBszO3KBfoxPwYn6CkCOrwaZWqwn4V6333+cLfdX 8nosJ8DJ/iqj6EWIu2V35nbDAzy9qBgD4r2YNUerNkDpL9X4EGyPEPd2DKXLw /msc7/AuHTEs4=">
27
27 URI data: スキームで GIF 画像を動的に生成 GIF 画像を base64 でエンコード( RFC2397 ) var data = ‘data:image/gif;base64,’+ ‘R0lGODlhAAEwAMQAAJ2M5Me98GRK1DoYyYBr3PHv ・・・(中 略)・・・ Pe99XO81Y50auc6PBkZEgpzbmt7HJa2I57CffgnMNqmWHAWNBwwGsKp KsrmJqltOOV69nuYxSkqpoTata18rWtrr1rTIIAQA7'; var icon_elem = document.getElementById("icon_here"); icon_elem.src = data; 残念ながら IE では動作しませんが・・・ Firefox, Opera で動作 http://www.kawa.net/works/js/data-scheme/base64.html
28
28 GIF SWF
29
29 SWF ファイルフォーマットの仕様書 Adobe Player Licensing から入手可能 http://www.adobe.com/licensing/developer/ メールアドレス( Adobe ID )を登録 ライセンスに同意する必要がある Flash6 以降の情報のみ Alexis' SWF Reference http://sswf.sourceforge.net/SWFalexref.html Flash6 以前の情報についても書いてある 2001 年からの蓄積
30
30 Alexis' SWF Reference http://sswf.sourceforge.net/SWFalexref.html ::::
31
31 SWF File Header, SWF Tags … struct swf_header { unsigned charf_magic[3];'FWS' or 'CWS' unsigned charf_version; unsigned longf_file_length; } struct swf_header_movie { swf_rectf_frame_size; unsigned short fixedf_frame_rate; unsigned shortf_frame_count; }; struct swf_csmtextsettings { swf_tagf_tag;/* 74 */ unsigned shortf_text_id_ref; unsignedf_use_flag_type : 2; unsignedf_grid_fit : 3; unsignedf_reserved : 3; long floatf_thickness; long floatf_sharpness; unsigned charf_reserved; };
32
32 SWF ファイルを DIS アセンブル しながら勉強したい …
33
33 swfdump コマンドで DIS アセンブル SWFTOOLS の swfdump コマンドを使うと SWF ファイルの内容をダンプすることができ る > swfdump --full FlashProxy.swf [HEADER] File version: 8 [HEADER] File is zlib compressed. Ratio: 63% [HEADER] File size: 796 (Depacked) [HEADER] Frame rate: 20.000000 [HEADER] Frame count: 1 [HEADER] Movie width: 450.00 [HEADER] Movie height: 325.00 [009] 3 SETBACKGROUNDCOLOR (ff/ff/ff) [027] 4 DEFINESPRITE defines id 20480 [000] 0 END [038] 21 EXPORTASSETS exports 20480 as "__Packages.MTASC" [03b] 643 DOINITACTION adds information to id 20480 ( 206 bytes) action: Constantpool(22 entries) String:"FlashProxy" String:"_global" String:"target" String:"_root" String:"className" String:"dispatch" String:"flash" String:"external" String:"ExternalInterface" String:"addCallback" String:"addListener" String:"prototype" String:"Function" String:"apply" String:"event" String:"arguments" String:"id" String:"FlashProxy.onTrigger" String:"call" String:"main" String:"proxy" String:"ASSetPropFlags" ( 2 bytes) action: Push Lookup:0 ("FlashProxy") ( 0 bytes) action: GetVariable ( 0 bytes) action: Not ( 2 bytes) action: If 418 http://www.swftools.org/documentation.html
34
34 swfdump はアクションレコードの抽出が苦手 : ( 8 bytes) action: unknown[8e] (remainder of 8 bytes:"\0\0\0\2)\0p\0") : アクションレコードの抽出に失敗 … orz
35
35 SWF::Parser (CPAN) なら・・・ dumpswf.plx dumpswf.plx Flash.swf > Flash.pl Flash.swf そのものを生成する Perl スクリプト「 Flash.pl 」を生成 http://www.nmt.ne.jp/~ysas/butaperl/swf/Parser.sjis.pod.html http://search.cpan.org/~YSAS/SWF-File/lib/SWF/Parser.pm
36
36 Sothink SWF Decompiler (試用期間 30 日) http://www.sothink.com/product/flashdecompiler/
37
37 DIS アセンブル結果( Sothink SWF Decompiler )
38
38 しかし、 URI データスキームに 埋め込みの SWF は Flash Player 9 では動かない …orz Flash Player 8 では動いたのに(><)
39
Flash 上で動く ECMAScript の処理系 があればいいじゃね? Flash Lite 職人である鴨志田さんに聞いてみると そういう処理系があるらしい!
40
40
41
41 ScriptEngine.swf の特徴 バイトコードインタプリタ 一旦スクリプトをバイトコード的なものに変換し てから独自 VM 上で実行 ECMA-262 3rd Edition にほぼ準拠 +いくつかの拡張(コルーチンなど) ActionScript1 的な感じで記述が可能 詳しくは Web で http://www.be-interactive.org/?itemid=6 http://www.be-interactive.org/?itemid=194
42
42 Xelf (ゼルフ)の開発者 – 新藤さん(高校 3 年 生) 名前の由来: Flex の逆で xleF ゲームを製作しやすくし ようプロジェクトの一環 として、 ECMAScript + α の処理系を Flash(AS) 上に 実装 http://bcnranking.jp/it_junior/21-00012742.html 期待 age
43
43 まとめ
44
44 Flash で eval っぽいことをするには? JavaScript でできないことをプラグインで Java アプレット + LiveConnect ( IE では使えな い) Flash 使えばいろいろできる(クロスブラウザ) JavaScript から Flash のコードを実行したい ActionScript で任意の関数を呼ぶ方法 FlashProxy.swf ( id:brazil さん) Flashy.swf (奥一穂さん) SWF ファイルの動的生成( URI データスキーム) Flash Player 9 以降ではもう使えない技 … orz Flash 上で動く ECMAScript + α の処理系あるよ これ最強! 新藤さん GJ
45
45 ご清聴ありがとうございました Special Thanks to: CybozuLabs 奥さん、鴨志田さん
Similar presentations
© 2024 slidesplayer.net Inc.
All rights reserved.