1 / 45

SWF Binary Hacks ~ eval のいばら道 ~

SWF Binary Hacks ~ eval のいばら道 ~. Shibuya.JS Technical Talk#3 – Shibuya.es 竹迫 良範 <takesako@shibuya.pl>. はじめに. 謝罪. 今日 Flex2 SDK を インストールしたばかりです 嘘言ってたらごめんなさい. eval の発音について. eval イーヴァル の検索結果 約 4 件 eval イヴァル の検索結果 約 11 件 eval エヴァル の検索結果 約 12 件 eval イーバル の検索結果 約 13 件

finley
Download Presentation

SWF Binary Hacks ~ eval のいばら道 ~

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. SWF Binary Hacks~ evalのいばら道 ~ Shibuya.JS Technical Talk#3 – Shibuya.es 竹迫 良範 <takesako@shibuya.pl>

  2. はじめに

  3. 謝罪 今日 Flex2 SDK を インストールしたばかりです 嘘言ってたらごめんなさい

  4. eval の発音について • eval イーヴァル の検索結果 約 4件 • eval イヴァル の検索結果 約 11 件 • eval エヴァル の検索結果 約 12 件 • eval イーバル の検索結果 約 13 件 • eval イバル の検索結果 約 13 件 • eval エバル の検索結果 約 28件 ※某G調査機関による調べによる

  5. JavaScriptでフォント名一覧を取得する3つの方法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. (1) Dialog Helper Object でフォント名一覧取得 <OBJECT id="dlgHelper" CLASSID="clsid:3050f819-98b5-11cf-bb82-00aa00bdce0b" width="0px" height="0px"> </OBJECT> 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. ※動作するブラウザが激しくIEに限定される

  8. (2) LiveConnect で Javaアプレットを操作 java.awt.GraphicsEnvironment#getAllFonts() 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から操作

  9. LiveConnectとは? • できること • JavaのオブジェクトをJavaScriptから操作できる • その逆も • 動作環境 • Netscape3以降(JavaScript1.1)の仕様 • Firefox, Opera で動作 • 使用できる条件 • Javaアプレットの実行が許可されているとき

  10. (3) Flash の TextField.getFontList() を利用 var user_fonts = TextField.getFontList(); user_fonts.sort(); getURL('javascript:fontList("‘ + escape(user_fonts) + ‘“)’, '_self'); こんな感じで .asファイルを作って getFontList.swf を作る

  11. でも、いちいち swfファイルを作るの面倒だよなぁ… Flash(ActionScript)で eval 使えたっけ?

  12. SWF Binary Hacks~ evalのいばら道 ~ 斜め下から始める 初めてのFlash

  13. FlashProxy.swf でFlash関数を動的実行 • Collection & Copy - JavaScript用Flashプロキシ、Javascript Sound Kit (id:brazilさん作) • http://d.hatena.ne.jp/brazil/20060726/1153884951 <script type="text/javascript"> 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 の関数を動的に呼び出すことができる

  14. 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(); } }

  15. お、Flashでも evalできる?

  16. なんか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 クラスのメソッド)

  17. 次のバージョンでは eval 自体廃止されちゃうし

  18. JavaScript から Flash の スタティック関数を evalっぽく実行したい!

  19. 例えば Ruby の場合… • 3つのeval関数があるのに! 1. ふつうの eval 2. Object#instance_eval 3. Module#module_eval/class_eval → 空前のメタプログラミング期ブーム

  20. それ Flashy.swf でできるよ

  21. それFlashy.swf 使えばできるよ • JavascriptからFlashの任意の静的関数を呼び出すことができる • <object id=“flashy” data=“Flashy.swf” /> <script language="JavaScript"> var flash = document.getElementById('flashy'); flash.setStatic('flash.system.IME.enabled', true); // IME オン </script> Kazuho@Cybozu Labs: JavaScript から Flash の便利な機能を使う方法 http://labs.cybozu.co.jp/blog/kazuho/archives/2007/03/flashy.php

  22. Flashy.as のソースコード(奥一穂さん) スタティック関数の呼び出しを動的に (インスタンスを直接生成できない abstract クラスのメソッドも呼べる) 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); } } }

  23. Flashの関数を呼ぶだけじゃなくASのコードを直接実行してみたいFlashの関数を呼ぶだけじゃなくASのコードを直接実行してみたい eval使えないけど、どうする???

  24. JavaScript で SWF を動的生成すればできるよ! <body><embed width="0px" height="0px" type="application/x-shockwave-flash" flashvars="param=val" src="data:application/x-shockwave-flash;base64, Q1dTCbwDAAB42l1SQW/TMBS23a5uu5VtGqqGEFKlTaqE1CbtDmhVFzG1KxoHiuCCkCbqOm5j5iaR4y7dATEu/AROO8PP4IzEoTvwBzhx4R9wwE7G2mFF8nufv+/zy3uegexPAO58BmAbgu7mPQDA+61vEIC2dEetF91eZTYRftTS2UHVUypsWVYcx/V4rx7IsdXY39+37KbVbNY0oxad+4rMan60U3USgy6LqOSh4oFfMTkZBlN1UK1eu7r0xjScSpFYutRigk2YryKrUW9oI5e2RoGcEOWQMBScEmNnzWqRF9DTmJyx2kiQyGtbC6LRKK4Ecw7dYMgqPcFmlWblcKFP2CnFkN1Foc7SbxKjrtNgYoUycKdU1zTSVol4WWIswulQ8Mhj0pn6p34Qp1csUMOhkhEV3Gb8w8y5IP54SsbMOXqWnN3kSY1EMadp248se89q7qVFGKxt/dfra0SPzwHdjV+ZNuigj5dfXhf1YJOFwKc3KIl+X95/t6nh78Uel5HqcEkFA1/vftCYYY8kmbAG2AB1gC4u/mCgw9Ulainpfd3lUSjIee5lKLli+bEkocdpVBiyMfd7XIiiK0mcSjDzXQPliet2PC7cXH/4llG1llqxMzP79SOzdbUtUVS3r9RNb0ipm8e+YpJQxc9YipRvnXcC/RC5z+RKGZYz26i8CkoYIoyyGK5gmMMQY5jHsIBhEWfXMCphdAej9QxYXhCiQibpAkQQZiHQCcwXMnP7iYayqFBszO3KBfoxPwYn6CkCOrwaZWqwn4V6333+cLfdX8nosJ8DJ/iqj6EWIu2V35nbDAzy9qBgD4r2YNUerNkDpL9X4EGyPEPd2DKXLw/msc7/AuHTEs4="></embed></body>

  25. URI data:スキームでGIF画像を動的に生成 • GIF画像をbase64でエンコード(RFC2397) <img id="icon_here"> <script> var data = ‘data:image/gif;base64,’+ ‘R0lGODlhAAEwAMQAAJ2M5Me98GRK1DoYyYBr3PHv・・・(中略)・・・Pe99XO81Y50auc6PBkZEgpzbmt7HJa2I57CffgnMNqmWHAWNBwwGsKpKsrmJqltOOV69nuYxSkqpoTata18rWtrr1rTIIAQA7'; var icon_elem = document.getElementById("icon_here"); icon_elem.src = data; </script> http://www.kawa.net/works/js/data-scheme/base64.html Firefox, Opera で動作 残念ながら IE では動作しませんが・・・

  26. GIF  SWF

  27. SWFファイルフォーマットの仕様書 • Adobe Player Licensing から入手可能 • http://www.adobe.com/licensing/developer/ • メールアドレス(Adobe ID)を登録 • ライセンスに同意する必要がある • Flash6以降の情報のみ • Alexis' SWF Reference • http://sswf.sourceforge.net/SWFalexref.html • Flash6以前の情報についても書いてある • 2001年からの蓄積

  28. Alexis' SWF Reference http://sswf.sourceforge.net/SWFalexref.html : : : :

  29. SWF File Header, SWF Tags… struct swf_header { unsigned char f_magic[3]; 'FWS' or 'CWS' unsigned char f_version; unsigned long f_file_length; } struct swf_header_movie { swf_rect f_frame_size; unsigned short fixed f_frame_rate; unsigned short f_frame_count; }; struct swf_csmtextsettings { swf_tag f_tag; /* 74 */ unsigned short f_text_id_ref; unsigned f_use_flag_type : 2; unsigned f_grid_fit : 3; unsigned f_reserved : 3; long float f_thickness; long float f_sharpness; unsigned char f_reserved; };

  30. SWFファイルを DISアセンブル しながら勉強したい…

  31. swfdumpコマンドで DISアセンブル • SWFTOOLS の swfdump コマンドを使うとSWFファイルの内容をダンプすることができる http://www.swftools.org/documentation.html > 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 ( 0 bytes) action: Not ( 2 bytes) action: If 418

  32. swfdumpはアクションレコードの抽出が苦手 : (    8 bytes) action: unknown[8e] (remainder of 8 bytes:"\0\0\0\2)\0p\0") : アクションレコードの抽出に失敗 … orz

  33. 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

  34. Sothink SWF Decompiler (試用期間30日) http://www.sothink.com/product/flashdecompiler/

  35. DISアセンブル結果(Sothink SWF Decompiler)

  36. しかし、 URIデータスキームに 埋め込みのSWFは Flash Player 9 では動かない…orz Flash Player 8 では動いたのに(><)

  37. Flash上で動く ECMAScriptの処理系があればいいじゃね? Flash Lite 職人である鴨志田さんに聞いてみると そういう処理系があるらしい!

  38. ScriptEngine.swf の特徴 • バイトコードインタプリタ • 一旦スクリプトをバイトコード的なものに変換してから独自VM上で実行 • ECMA-262 3rd Editionにほぼ準拠 • +いくつかの拡張(コルーチンなど) • ActionScript1 的な感じで記述が可能 • 詳しくはWebで • http://www.be-interactive.org/?itemid=6 • http://www.be-interactive.org/?itemid=194

  39. Xelf(ゼルフ)の開発者 –新藤さん(高校3年生) 名前の由来:Flexの逆でxleF http://bcnranking.jp/it_junior/21-00012742.html ゲームを製作しやすくしようプロジェクトの一環として、ECMAScript +αの処理系をFlash(AS)上に実装 期待age

  40. まとめ

  41. 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

  42. ご清聴ありがとうございました Special Thanks to: CybozuLabs 奥さん、鴨志田さん

More Related