2009年12月23日 星期三

擾亂器 與 ApplicationDomain

遇到一個 擾亂器 與 ApplicationDomain 的問題。

以下是測試程式的步驟:

1. ApplicationDomainTest.swf 載入 ExternalSWF.swf
2. 取得 ExternalSWF.swf 中的 ExternalSWF 類別
3. 因為 ExternalSWF 實作 ISwf2 介面,所以 ApplicationDomainTest 可以透過對 ISwf2 的認識,而執行 doA(ISwf1) 將自己當作參數帶入。
4. 當 ExternalSWF 的 doA(ISwf1) 被執行時,可以透過對 ISwf1 的認識,而執行 ApplicationDomainTest 的 doA(ISwf2)。
5. ApplicationDomainTest 的 doA(ISwf2) 被執行時,會在畫面上顯示 "success" 文字。

在這個例子中,ApplicationDomainTest.swf 的 ApplicationDomain 中,存有 ApplicationDomainTest、ISwf1、ISwf2;而 ExternalSWF.swf 的 ApplicationDomain 中,存有 ExternalSWF、ISwf1、ISwf2;關鍵就在於兩個 ApplicationDomain 中都認識相同的 interface,是否會共用!

設定方法就在 ApplicationDomainTest 要載入 ExternalSWF.swf 時所用的 Loader 的 ApplicationDomain 是哪一種。相關官方說明可以參考:
http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000327.html

以下是完整程式碼:

package {
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLRequest;
import flash.system.ApplicationDomain;
import flash.system.LoaderContext;
import flash.text.TextField;

import my_interface.ISwf1;
import my_interface.ISwf2;

public class ApplicationDomainTest extends Sprite implements ISwf1
{
private var ldr:Loader;

public function ApplicationDomainTest()
{
var ad:ApplicationDomain;
ad = ApplicationDomain.currentDomain;
//ad = new ApplicationDomain(ApplicationDomain.currentDomain);

ldr = new Loader();
var req:URLRequest = new URLRequest("ExternalSWF.swf");
var ldrContext:LoaderContext = new LoaderContext(false, ad);
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
ldr.load(req, ldrContext); 
}

private function completeHandler(event:Event):void
{
var Cls:Class = ldr.contentLoaderInfo.applicationDomain.getDefinition("ExternalSWF") as Class;
var instance:ISwf2 = event.target.content as ISwf2;
instance.doA(this);
}

public function doA(obj:ISwf2):void{
trace("ApplicationDomainTest", this, "doA()", obj);

var txt:TextField = new TextField();
txt.text = "success";
addChild(txt);
}
}
}


package
{
import flash.display.Sprite;

import my_interface.ISwf1;
import my_interface.ISwf2;

public class ExternalSWF extends Sprite implements ISwf2
{
public function ExternalSWF()
{
super();
}

public function doA(obj:ISwf1):void{
trace("ExternalSWF", this, "doA()", obj);

obj.doA(this);
}  
}
}


package my_interface
{
public interface ISwf1
{
function doA(obj:ISwf2):void
}
}


package my_interface
{
public interface ISwf2
{
function doA(obj:ISwf1):void
}
}


正常執行 ApplicationDomainTest.swf 的畫面:



如果是在 Flex Builder 開發環境的話,還可以在輸出視窗看到以下訊息:

[SWF] D:\works\ApplicationDomainTest\bin-debug\ExternalSWF.swf - 1,567 bytes after decompression
ExternalSWF [object ExternalSWF] doA() [object ApplicationDomainTest]
ApplicationDomainTest [object ApplicationDomainTest] doA() [object ExternalSWF]
[SWF] D:\works\ApplicationDomainTest\bin-debug\ApplicationDomainTest.swf - 2,516 bytes after decompression

不過,問題出在,若是我欲將 ApplicationDomainTest.swf 進行擾亂的話,就糟糕了,我使用的是 secureSWF v3.4 Pro build 4047,擾亂時我有特地將 my_interface 這個 package 下的 interface 都排除,目的是讓兩個不同 ApplicationDomain 中的 ISwf1, ISwf2 都還長得一模一樣。



不過很可惜的是,執行 ApplicationDomainTest.swf 的畫面:



在 ExternalSWF 的 doA() 中,對於收到的參數 (實作 ISwf1 的 ApplicationDomainTest),找不到屬性 my_interface:ISwf1::doA。但是若我們來 trace(obj["doA"]) 的話,該 function 是存在的,若使用 describeType() 來看的話,也可以看到該物件擁有 doA()。

如果使用 decompiler 反組譯,甚至也還可以看到 ApplicationDomainTest.swf 中仍有 doA(ISwf2) 呢:



所以我猜測,被擾亂過後的 ApplicationDomainTest.swf,有某種防禦機制,不一定是 ApplicationDomain 改變了,但是卻至少使得 ExternalSWF 無法辨識出在 ApplicationDomainTest 的 ApplicationDomain 中的 ISwf1。

我正在繼續尋求解決方法,或是 secureSWF 軟體的設定方法,來解決問題~

===============================================

[2009-12-24-12-47]

最後,因為仍找不出 ExternalSWF.swf 中要如何認識 ApplicationDomainTest.swf 中的類別,所以只好調整作法,也是調整成比較好的作法。

原作法:
在 ExternalSWF.swf 中,會叫用 ApplicationDomainTest.swf 中的類別、物件 作事情。

調整後的作法:
在 ExternalSWF.swf 中,送出事件,ApplicationDomainTest.swf 收到事件後,再叫用相關類別、物件 作事情。

3 則留言:

HsiangTing 提到...

你好,本公司急徵Flash Programmer/Developer人才協助製作8至10個Flash game. 所有的圖片美工,聲音及音效皆會提供,需於二月9日前完成。此作品需適用於網頁瀏覽器且最終檔案需為exe檔,另希望此作品完成檔愈小愈好。有合作興趣者可來信索取範例,並請寄相關作品至以下信箱。如果有認識合適的人才,也請不吝幫忙介紹,謝謝。

HsiangTing 提到...

不好意思,忘了留聯絡方式。
請寄相關作品至karenmurray@mug.ie。
謝謝

誼--無境閣 提到...
作者已經移除這則留言。