| 1 |
package{ |
|---|
| 2 |
import flash.errors.EOFError; |
|---|
| 3 |
import flash.events.Event; |
|---|
| 4 |
import flash.events.IOErrorEvent; |
|---|
| 5 |
import flash.net.URLRequest; |
|---|
| 6 |
import flash.net.URLStream; |
|---|
| 7 |
|
|---|
| 8 |
import flash.utils.ByteArray; |
|---|
| 9 |
import org.libspark.disassemble.SwfStream; |
|---|
| 10 |
import org.libspark.disassemble.ByteStream; |
|---|
| 11 |
import org.libspark.disassemble.abc.ClassPrinter; |
|---|
| 12 |
import flash.events.*; |
|---|
| 13 |
public class Controller extends EventDispatcher { |
|---|
| 14 |
// listener用の定数 |
|---|
| 15 |
static public var LOAD : String = 'LOAD'; |
|---|
| 16 |
static public var INFO : String = 'INFO'; |
|---|
| 17 |
|
|---|
| 18 |
private var frame_ : Array = []; |
|---|
| 19 |
private var info_ : Object; |
|---|
| 20 |
|
|---|
| 21 |
private var stream : URLStream; |
|---|
| 22 |
|
|---|
| 23 |
public function get frame():Array{ |
|---|
| 24 |
return frame_; |
|---|
| 25 |
} |
|---|
| 26 |
|
|---|
| 27 |
public function get info():Object{ |
|---|
| 28 |
return info_; |
|---|
| 29 |
} |
|---|
| 30 |
|
|---|
| 31 |
|
|---|
| 32 |
// リスナの呼び出し |
|---|
| 33 |
private function notify(type : String):void{ |
|---|
| 34 |
this.dispatchEvent(new Event(type)); |
|---|
| 35 |
} |
|---|
| 36 |
|
|---|
| 37 |
/** |
|---|
| 38 |
* SWFの逆アセンブル。 |
|---|
| 39 |
*/ |
|---|
| 40 |
public function disassemble(path : String) : void{ |
|---|
| 41 |
this.reset(); |
|---|
| 42 |
stream = new URLStream(); |
|---|
| 43 |
stream.addEventListener(Event.COMPLETE, onComplete); |
|---|
| 44 |
|
|---|
| 45 |
var req:URLRequest = new URLRequest(path); |
|---|
| 46 |
stream.load(req); |
|---|
| 47 |
} |
|---|
| 48 |
|
|---|
| 49 |
private function onComplete(e : Event) : void { |
|---|
| 50 |
var bytes:ByteArray = new ByteArray(); |
|---|
| 51 |
stream.readBytes(bytes); |
|---|
| 52 |
stream.close(); |
|---|
| 53 |
|
|---|
| 54 |
var swf:SwfStream = new SwfStream(bytes); |
|---|
| 55 |
swf.seekToBody(); |
|---|
| 56 |
try { |
|---|
| 57 |
for (;;) { |
|---|
| 58 |
this.dispatchEvent(new ProgressEvent(ProgressEvent.PROGRESS, |
|---|
| 59 |
false,false, |
|---|
| 60 |
swf.position,swf.length)); |
|---|
| 61 |
|
|---|
| 62 |
var byte:uint = swf.readShort(); |
|---|
| 63 |
var tag:uint = byte >>> 6; |
|---|
| 64 |
var length:uint = byte & 0x3f; |
|---|
| 65 |
if (length == 0x3f) { |
|---|
| 66 |
length = swf.readInt(); |
|---|
| 67 |
} |
|---|
| 68 |
switch (tag) { |
|---|
| 69 |
case 82: |
|---|
| 70 |
var tagStart:uint = swf.position; |
|---|
| 71 |
swf.readUnsignedInt(); |
|---|
| 72 |
for (; swf.readByte() != 0x00; ) {} |
|---|
| 73 |
var abcBytes:ByteArray = new ByteArray(); |
|---|
| 74 |
swf.readBytes(abcBytes, 0, length - (swf.position - tagStart)); |
|---|
| 75 |
frame_.push({label:'abc',tag:'abc',data: new ClassPrinter(abcBytes).parse()}); |
|---|
| 76 |
swf.seek(length); |
|---|
| 77 |
break; |
|---|
| 78 |
|
|---|
| 79 |
default: |
|---|
| 80 |
frame_.push({label:'???',tag:tag,length:length}); |
|---|
| 81 |
swf.seek(length); |
|---|
| 82 |
break; |
|---|
| 83 |
} |
|---|
| 84 |
} |
|---|
| 85 |
}catch (e:VerifyError) { |
|---|
| 86 |
trace(e.getStackTrace()); |
|---|
| 87 |
}catch (e:EOFError) { |
|---|
| 88 |
trace(e); |
|---|
| 89 |
} |
|---|
| 90 |
this.notify(LOAD); |
|---|
| 91 |
} |
|---|
| 92 |
|
|---|
| 93 |
private function reset():void{ |
|---|
| 94 |
this.frame_ = []; |
|---|
| 95 |
} |
|---|
| 96 |
|
|---|
| 97 |
public function showInfo(item : Object):void{ |
|---|
| 98 |
this.info_ = item; |
|---|
| 99 |
this.notify(INFO); |
|---|
| 100 |
} |
|---|
| 101 |
} |
|---|
| 102 |
} |
|---|