2011年10月5日 星期三

使用 embed text 保護敏感字串

若有段敏感字串,不希望當 swf 被反組譯之後被看到,可透過 embed text 的作法將之編為 ByteArray,就不是明碼了,可增加被破解的困難度。



這不是甚麼新技術,可直接參考前人的文章

How to embed a text file in Flash

因被問起,所以實作此範例,步驟如下:


首先,一般專案,可能會將 KEY 定義在程式碼中:

TestEmbedText.as

package
{
 import flash.display.Sprite;
 
 public class TestEmbedText extends Sprite
 {
  private const KEY:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  
  public function TestEmbedText()
  {
   trace(KEY);
  }
 }
}

經過以下的混淆:

secure.bat

set SECURE_SWF_HOME=E:\Program Files (x86)\secureSWF_v3pro_win_build5762
set PROJECT=E:\works_test\TestEmbedText

java -jar "%SECURE_SWF_HOME%\secureSWF.jar" %PROJECT%/bin-debug/TestEmbedText.swf %PROJECT%/bin-debug -p:most_aggressive -v:10

pause

其實反組譯後的檔案,還是可以清楚看到 KEY 的字串內容,只不過他不見得知道那是一個 KEY,但有心人仍可猜:

混淆後的 TestEmbedText.swf 反組譯

package 
{
    import TestEmbedText.*;
    import flash.display.*;

    public class TestEmbedText extends Sprite
    {
        private const _20case:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

        public function TestEmbedText()
        {
            ;
            var _loc_1:Boolean = null;
            var _loc_2:Boolean = null;
            if (_loc_2 || _loc_1)
            {
            }
            if (_loc_2 || _loc_1)
            {
                do
                {
                    
                    return;
                    ;
                    default xml namespace = this;
                    _loc_2 = null / ((false - 1) <= true) << NaN;
                    
                    if (!(_loc_1 && this))
                    {
                    }while (true)
                    
                    trace(this._20case);
                }
                ;
            }
            do
            {
                
                do
                {
                    
                }while (true)
            }while (true)
            return;
        }// end function

    }
}

所以要改用以下做法,首先,將敏感資料放在一個文字檔中:

key.txt

ABCDEFGHIJKLMNOPQRSTUVWXYZ

建立一個類別,繼承自 ByteArray,並且此類別 embed 外部文字檔:

Key.as

package
{
 import flash.utils.ByteArray;
 
 [Embed(source="key.txt", mimeType="application/octet-stream")]
 public class Key extends ByteArray
 {
 }
}

主程式改成建立上述類別的 instance,透過 toString() 取得 ByteArray 內容:

TestEmbedText2.as

package
{
 import flash.display.Sprite;
 
 public class TestEmbedText2 extends Sprite
 {
  private const key:Key = new Key();
  
  public function TestEmbedText2()
  {
   trace(key.toString());
  }
 }
}

編譯出來的 swf,可以先直接反組譯看看,可以發現就已經看不到敏感字串:

混淆前的 TestEmbedText2.swf 中的 Key 類別

package 
{
    import flash.utils.*;

    public class Key extends ByteArray
    {

        public function Key()
        {
            return;
        }// end function

    }
}

當然以下的動作也可以不用做了,不過還是來混淆一下:

secure2.bat

set SECURE_SWF_HOME=E:\Program Files (x86)\secureSWF_v3pro_win_build5762
set PROJECT=E:\works_test\TestEmbedText

java -jar "%SECURE_SWF_HOME%\secureSWF.jar" %PROJECT%/bin-debug/TestEmbedText2.swf %PROJECT%/bin-debug -p:most_aggressive -v:10

pause

混淆後的 swf 反組譯之後,當然只是讓 Key 類別更難閱讀,仍然看不到明碼:

混淆後的 TestEmbedText2.swf 中的 Key 類別

package 
{
    import flash.utils.*;

    public class _20case extends ByteArray
    {

        public function _20case()
        {
            var _loc_1:Boolean = true;
            ;
            var _loc_2:* = _loc_3 in typeof(true) | _loc_1;
            if (_loc_1)
            {
            }
            ;
            if (!_loc_2)
            {
                do
                {
                    
                    return;
                    
                    ;
                    if (!(null === _loc_1 << _loc_1 & (NaN - 1) > null))
                    {
                    }
                }
            }while (true)
            return;
        }// end function

    }
}

完成!

沒有留言: