05-28-2008, 12:59 PM
|
#1
|
|
Registered User
Join Date: Mar 2006
Posts: 10
|
How to Get a list of library sybmols's names from a loaded SWF ?
Hi, everybody
Is there a way to get listed all class names of classes or definitions of loaded swf file ?
This is my project :
*1) I have a main swf file that loads other external swf files , lets say "dynamically loaded library swf files" : this is working nickel.
*2) the main swf have to instanciate some objects defined inside these loaded swf files : this is working well unless we know the linkage name of the object, or lets say it's class name.
*3) I need the main swf to instanciate every exported symbol (class) in side the loaded swf.
now the problem : How to retreive a list of exported library symbols or class names from a loaded swf
there is not instances of these classes inside the loaded swf to use them to retreive the class name.
Thanks for your effort.
|
|
|
05-30-2008, 09:21 PM
|
#2
|
|
Registered User
Join Date: Mar 2006
Posts: 10
|
Any comment !
may what i'm looking for seems to be confusing, but your comments are welcome. Any reply may help
I still waiting, anyway
|
|
|
05-30-2008, 09:37 PM
|
#3
|
|
six eyes
Join Date: Jan 2003
Location: San Francisco, CA (USA)
Posts: 7,875
|
I'm not sure its possible. I'm not saying you can't but I don't think there's anything that serves that to you once the SWF is loaded.
|
|
|
05-31-2008, 11:59 PM
|
#4
|
|
Registered User
Join Date: Mar 2006
Posts: 10
|
What about decompiling , then ...
thanks Senocular
What about "SWF decompiling algorithms" (dont let adobe know what we are talkig about )
I think it would be possible to manipulate BytesArray of loaded files to hack something ; Sothink swf decompiler did it well, but How to implement a sush algorithme.
Any idea !
|
|
|
06-01-2008, 09:00 AM
|
#5
|
|
flash veteran
Join Date: May 2005
Location: Belgium
Posts: 914
|
I think the easiest will be to provide each class with a name property and let them register to some kind of ClassRegister, then the main swf file can retrieve the list from the ClassRegister class.
|
|
|
06-01-2008, 12:34 PM
|
#6
|
|
Holosuit User
Join Date: Oct 2006
Location: Tel Aviv
Posts: 4,299
|
Actually, if you manage to unzip the loaded movie, than it's simple, all the class declarations are in it's header section in plain text... and, if you could find a way to get the actual bytes Loader will use to create the instance of loaded SWF (Loader unzips it anyway), than it'd a piece of cake =)
|
|
|
06-01-2008, 05:57 PM
|
#7
|
|
Registered User
Join Date: Mar 2006
Posts: 10
|
Thnx for replying
In fact, I was looking for some thing much simpler. and tought it is as simple as calling
Code:
Loader.contentLoaderInfo.getListedAllYourLibrarySymbols()
but the real world seems to be "not simple"
I think decompiling is the right way unless adobe implements the above method (hoping in AS4  )
So while waiting for some Decompressing and decompiling piece of code writen in AS3, I 'll use the below solution for my project (just to go faster )
in side every swf files I'll declare a function that return an array with all exported library sombols' names, and calling it from the main swf
the name of this function is supposed to be the same in every swf (lets say Interface)
Code:
Class myDocumentClass extends MovieClip{
public function getSymbolsNames(){
return(["myAnyClass","myIntro","myButton","etc"])
}
}
this is not the best solution, so if you have a best one , you'r welcome
what do you think ?
|
|
|
06-01-2008, 10:33 PM
|
#8
|
|
Holosuit User
Join Date: Oct 2006
Location: Tel Aviv
Posts: 4,299
|
Seems like I've done it =)
Here's the code + attached tested SWF (note, you'll have to have flex 3 SDK to compile it, somehow my Flash didn't want to recognize LoaderInfo.bytes property even though I've updated playerglobal.swc. Anyway, this property exists since fp v. 115...
So, here we go:
ActionScript Code:
package
{
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;
import flash.display.LoaderInfo;
import flash.utils.ByteArray;
/**
* ...
* @author wvxvw
*/
public class TryGetBytes
{
private var _ba:ByteArray;
private var _loader:Loader;
private var _hex:Array = [
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
'', '', '', '', '', '', '', '', '', '', '', '', ' ', '!', '"', '#', '$', '%', '&', '\'',
'(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';',
'<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\/', ']', '^', '_', '`', 'a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
'y', 'z', '{', '|', '}', '~'
];
public function TryGetBytes()
{
_loader = new Loader;
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, handleComplete);
_loader.load(new URLRequest('test.swf'));
}
private function handleComplete(evt:Event):void {
_ba = _loader.contentLoaderInfo.bytes;
_ba.position = 0;
trace(_ba.bytesAvailable);
var str:String = "";
var rb:int;
for (var i:int = 0; i < _ba.length; i++)
{
rb = _ba.readByte();
if (rb > 31 && rb <= 126) {
str += _hex[rb];
} else {
str += ' ';
}
if (str.length % 16 == 0 && str.length > 15)
{
str += '\r';
}
}
trace("from ascii "+str);
}
}
}
And this is the output I've got by running it:
Code:
Build succeeded
Done (0)
337
from ascii FWS Q x p
D C
Scene
1
. Test f
lash.display Sp
rite Object fla
sh.events Event
Dispatcher Disp
layObject Inter
activeObject Di
splayObjectCont
ainer
0G 0 I
G # 0e `
0` 0` 0` 0` 0`
0` X h G
? Tes
t @
So, using some advanced logistics  You may get the names of all the classes you have in the loaded SWF =)
ActionScript Code:
package
{
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;
import flash.display.LoaderInfo;
import flash.utils.ByteArray;
/**
* ...
* @author wvxvw
*/
public class TryGetBytes
{
private var _ba:ByteArray;
private var _loader:Loader;
private var _hex:Array = [
'', '', '', '\n', '\n', '\n', '\n', '\n', '\n', '\t', '\n', '\t', '\r\n', '\r', '', '', '', '', '', '',
'', '', '', '', '', '', '', '', '', '', '', '', ' ', '!', '"', '#', '$', '%', '&', '\'',
'(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';',
'<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\/', ']', '^', '_', '`', 'a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
'y', 'z', '{', '|', '}', '~'
];
private var _classNames:Array;
private var _packageNames:Array;
public var loadedClasses:Array;
public function TryGetBytes()
{
_loader = new Loader;
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, handleComplete);
_loader.load(new URLRequest('test.swf'));
}
private function handleComplete(evt:Event):void {
_classNames = [];
_packageNames = [];
_ba = _loader.contentLoaderInfo.bytes;
_ba.position = 0;
trace(_ba.bytesAvailable);
var str:String = "";
var packageName:String = "";
var isPackage:Boolean = false;
var rb:int;
var i:int;
var isClassDeclaration:Boolean = false;
var tcl:Class;
mainLoop:for (i = 0; i < _ba.length; i++)
{
rb = _ba.readByte();
if (rb <= 126) {
if (rb == 4) {
isClassDeclaration = true;
str = '';
}
if (isClassDeclaration) {
if ((rb == 0 && _classNames.length) || str == 'MainTimeline') {
if (str.length && str != 'MainTimeline') {
if (_classNames.indexOf(str) < 0) _classNames.push(str);
}
break mainLoop;
}
}
if (rb < 37 || rb == 34 || rb == 37 || rb == 58) rb = -1;
switch(rb) {
case -1: // end ClassName;
if (!isClassDeclaration) break;
if (!str.length) break;
if (isPackage) {
isPackage = false;
if (_packageNames.indexOf(str) < 0) _packageNames.push(str);
} else {
if (_classNames.indexOf(str) < 0) _classNames.push(str);
}
str = '';
break;
case 46: // isPackage
isPackage = true;
str += _hex[rb];
break;
default:
if (/[\w|\d|\.]/.test(_hex[rb]))
{
str += _hex[rb];
}
break;
}
}
}
loadedClasses = [];
for (i = 0; i < _classNames.length; i++) {
for (var j:int = 0; j < _packageNames.length; j++) {
if (_loader.contentLoaderInfo.applicationDomain.hasDefinition(_packageNames[j]+'.'+_classNames[i])) {
loadedClasses.push(_packageNames[j]+'.'+_classNames[i]);
}
}
}
trace("from ascii\r>>> Classes:\r"+loadedClasses.join('\r'));
}
}
}
Ok, here I've tried to improve the recognition of classes and packages... but, the problem is I can't understand the dependancies in separating one definition from another... it definately should be integers 0x03..0x1F (may be all non alphanumeric symbols acxept for some it needs to recognize package names, intrfaces etc...), but I can't get the reason for putting once 0x09 and other time 0x0A... The same way I've discovered that 0x01 (or 0x01 0x16 0x01) should signal the end of class definition part... but I may be wrong here too... and public properties are also listed together with class definitions, but, still, I can't see the way to figure out when it's a property, and when it's a class...
But, anyway, it works =)
Last edited by wvxvw; 06-02-2008 at 07:53 AM.
Reason: some improvements :P
|
|
|
| Thread Tools |
|
|
| Display Modes |
Rate This Thread |
Hybrid Mode
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT. The time now is 02:52 AM.
///
|
|