5

私は ABC バイトコードをいじっていて、誰かが私の混乱を解消してくれることを期待していました。クリップをステージに配置する単純なフラッシュ ファイルと、各フレームの位置を更新するための小さなスクリプトがあります。コードは次のようになります。

package
{
     import flash.display.MovieClip;     
     import flash.events.Event;

     public class RedCircle extends MovieClip
     {
          public function RedCircle()
          {
               this.addEventListener(Event.ENTER_FRAME, moveit);
          }

          function moveit(e:Event)
          {
               this.x -=1;
          }
     }
}

次のようなものにコンパイルされます。

protected package protected RedCircle
{
    class RedCircle extends flash.display.MovieClip
    {
        static () : Void
        {
            getlocal_0();
            pushscope();
            returnvoid();
        }



        RedCircle () : Void
        {
            getlocal_0();
            pushscope();
            getlocal_0();
            constructsuper(0);
            getlocal_0();
            getlex(flash.events.Event);
            getproperty(ENTER_FRAME);
            getlex(internal .moveit);       // ###1
            callpropvoid(addEventListener, 2);
            returnvoid();
        }



        function (anonymous) (flash.events.Event param1) : Void // ###2
        {
            getlocal_0();
            pushscope();
            getlocal_0();
            getlocal_0();
            getproperty(x);
            decrement();
            setproperty(x);
            returnvoid();
        }
    }
}

私の質問は、「getlex」操作がどのように機能するかです (###1 でマークしました)。クラスの「moveit」メソッドを参照するマルチネームが渡されます。残念ながら、メソッド情報の「名前」フィールドは、コンパイラによって使用されることはないようです。すべてのメソッドの名前は空の文字列です (上の ###2 の名前のない関数として示されています)。

Flash Player はマルチネームを名前のないメソッドにどのようにリンクしますか? AVM2 仕様では、これに対する規定はないようです。

sothink のような市販の逆コンパイラがメソッド名を判別できるため、それが可能であることはわかっています。彼らがどのようにそれを行うのか、またはコードがどのように機能するのかはわかりません。

4

3 に答える 3

5

逆コンパイラがメソッドを (匿名) として表示する理由がわかりません。

abcData のダンプは次のとおりです。

abcFile{
minor_version (17): 16
major_version (19): 46
constant_pool{
    int_count (21): 0
        [0]: zero (not included in abcFile)
    uint_count (22): 0
        [0]: zero (not included in abcFile)
    double_count (23): 0
        [0]: NaN (not included in abcFile)
    string_count (24): 17
        string_info[0]{
            name: * (not included in abcFile)
        }
        string_info[1]{
            size (25): 12
            name (26): "flash.events"
        }
        string_info[2]{
            size (38): 5
            name (39): "Event"
        }
        string_info[3]{
            size (44): 0
            name (45): ""
        }
        string_info[4]{
            size (45): 9
            name (46): "RedCircle"
        }
        string_info[5]{
            size (55): 13
            name (56): "flash.display"
        }
        string_info[6]{
            size (69): 9
            name (70): "MovieClip"
        }
        string_info[7]{
            size (79): 6
            name (80): "moveit"
        }
        string_info[8]{
            size (86): 11
            name (87): "ENTER_FRAME"
        }
        string_info[9]{
            size (98): 16
            name (99): "addEventListener"
        }
        string_info[10]{
            size (115): 1
            name (116): "x"
        }
        string_info[11]{
            size (117): 6
            name (118): "Object"
        }
        string_info[12]{
            size (124): 15
            name (125): "EventDispatcher"
        }
        string_info[13]{
            size (140): 13
            name (141): "DisplayObject"
        }
        string_info[14]{
            size (154): 17
            name (155): "InteractiveObject"
        }
        string_info[15]{
            size (172): 22
            name (173): "DisplayObjectContainer"
        }
        string_info[16]{
            size (195): 6
            name (196): "Sprite"
        }
        namespace_count (202): 6
            namespace_info[0]{
                kind: * (not included in abcFile)
            }
            namespace_info[1]{
                kind (203): CONSTANT_PackageNamespace
                name (204): 1
            }
            namespace_info[2]{
                kind (205): CONSTANT_PackageNamespace
                name (206): 3
            }
            namespace_info[3]{
                kind (207): CONSTANT_PackageNamespace
                name (208): 5
            }
            namespace_info[4]{
                kind (209): CONSTANT_ProtectedNamespace
                name (210): 4
            }
            namespace_info[5]{
                kind (211): CONSTANT_PackageInternalNs
                name (212): 3
            }
        ns_set_count (213): 0
            ns_set_info[0]{
                ns: 0 (not included in abcFile)
            }
        multiname_count (214): 14
            multiname_info[0]{
                kind: 0 (not included in abcFile)
            }
            multiname_info[1]{
                kind (216): CONSTANT_QName
                multiname_kind_QNAME{
                    ns (216): 1
                    name (217): 2 ("Event")
                }
            }
            multiname_info[2]{
                kind (219): CONSTANT_QName
                multiname_kind_QNAME{
                    ns (219): 2
                    name (220): 4 ("RedCircle")
                }
            }
            multiname_info[3]{
                kind (222): CONSTANT_QName
                multiname_kind_QNAME{
                    ns (222): 3
                    name (223): 6 ("MovieClip")
                }
            }
            multiname_info[4]{
                kind (225): CONSTANT_QName
                multiname_kind_QNAME{
                    ns (225): 5
                    name (226): 7 ("moveit")
                }
            }
            multiname_info[5]{
                kind (228): CONSTANT_QName
                multiname_kind_QNAME{
                    ns (228): 2
                    name (229): 8 ("ENTER_FRAME")
                }
            }
            multiname_info[6]{
                kind (231): CONSTANT_QName
                multiname_kind_QNAME{
                    ns (231): 2
                    name (232): 9 ("addEventListener")
                }
            }
            multiname_info[7]{
                kind (234): CONSTANT_QName
                multiname_kind_QNAME{
                    ns (234): 2
                    name (235): 10 ("x")
                }
            }
            multiname_info[8]{
                kind (237): CONSTANT_QName
                multiname_kind_QNAME{
                    ns (237): 2
                    name (238): 11 ("Object")
                }
            }
            multiname_info[9]{
                kind (240): CONSTANT_QName
                multiname_kind_QNAME{
                    ns (240): 1
                    name (241): 12 ("EventDispatcher")
                }
            }
            multiname_info[10]{
                kind (243): CONSTANT_QName
                multiname_kind_QNAME{
                    ns (243): 3
                    name (244): 13 ("DisplayObject")
                }
            }
            multiname_info[11]{
                kind (246): CONSTANT_QName
                multiname_kind_QNAME{
                    ns (246): 3
                    name (247): 14 ("InteractiveObject")
                }
            }
            multiname_info[12]{
                kind (249): CONSTANT_QName
                multiname_kind_QNAME{
                    ns (249): 3
                    name (250): 15 ("DisplayObjectContainer")
                }
            }
            multiname_info[13]{
                kind (252): CONSTANT_QName
                multiname_kind_QNAME{
                    ns (252): 3
                    name (253): 16 ("Sprite")
                }
            }
    }
    method_count (254): 4
        method_info[0]{
            param_count (255): 0
            return_type (256): 0
            name (257): 0
            flags (258): 0
                NEED_ARGUMENTS (0x01): false
                NEED_ACTIVATION (0x02): false
                NEED_REST (0x04): false
                HAS_OPTIONAL (0x08): false
                SET_DXNS (0x40): false
                HAS_PARAM_NAMES (0x80): false
        }
        method_info[1]{
            param_count (259): 0
            return_type (260): 0
            name (261): 0
            flags (262): 0
                NEED_ARGUMENTS (0x01): false
                NEED_ACTIVATION (0x02): false
                NEED_REST (0x04): false
                HAS_OPTIONAL (0x08): false
                SET_DXNS (0x40): false
                HAS_PARAM_NAMES (0x80): false
        }
        method_info[2]{
            param_count (263): 1
            return_type (264): 0
            param_type[0] (265): 1
            name (266): 0
            flags (267): 0
                NEED_ARGUMENTS (0x01): false
                NEED_ACTIVATION (0x02): false
                NEED_REST (0x04): false
                HAS_OPTIONAL (0x08): false
                SET_DXNS (0x40): false
                HAS_PARAM_NAMES (0x80): false
        }
        method_info[3]{
            param_count (268): 0
            return_type (269): 0
            name (270): 0
            flags (271): 0
                NEED_ARGUMENTS (0x01): false
                NEED_ACTIVATION (0x02): false
                NEED_REST (0x04): false
                HAS_OPTIONAL (0x08): false
                SET_DXNS (0x40): false
                HAS_PARAM_NAMES (0x80): false
        }
    metadata_count (272): 0
    class_count (273): 1
        instance_info[0]{
            name (274): 2 (RedCircle)
            super_name (275): 3 (MovieClip)
            flags (276): 9
                CONSTANT_ClassSealed (0x01): true
                CONSTANT_ClassFinal (0x02): false
                CONSTANT_ClassInterface (0x04): false
                CONSTANT_ClassProtectedNs (0x08): true
            protectedNs (277): 4
            intrf_count (278): 0
            iinit (279): 1
            trait_count (280): 1
                traits_info[0]{
                    name (281): 4 (moveit)
                    kind (282): Trait_Method
                    ATTR_Final (0x1): false
                    ATTR_Override (0x2): false
                    ATTR_Metadata (0x4): false
                    trait_method{
                        disp_id (283): 0
                        method (284): 2
                    }
                }
        }
        class_info[0]{
            cinit (285): 0
            trait_count (286): 0
        }
    script_count (287): 1
        init (288): 3
            trait_count (289): 1
                traits_info[0]{
                    name (290): 2 (RedCircle)
                    kind (291): Trait_Class
                    ATTR_Metadata (0x4): false
                    trait_class{
                        slot_id (292): 1
                        classi (293): 0
                    }
                }
    method_body_count (294): 4
        method_body_info[0]{
            method (295): 0
            max_stack (296): 1
            local_count (297): 1
            init_scope_depth (298): 9
            max_scope_depth (299): 10
            code_length (300): 3
                208 0xD0 (301) getlocal_0
                48 0x30 (302) pushscope
                71 0x47 (303) returnvoid

            exception_count (304): 0
            trait_count (305): 0
        }
        method_body_info[1]{
            method (306): 1
            max_stack (307): 3
            local_count (308): 1
            init_scope_depth (309): 10
            max_scope_depth (310): 11
            code_length (311): 17
                208 0xD0 (312) getlocal_0
                48 0x30 (313) pushscope
                208 0xD0 (314) getlocal_0
                73 0x49 (315) constructsuper
                    arg_count: 0
                208 0xD0 (317) getlocal_0
                96 0x60 (318) getlex
                    index: 1 (Event)
                102 0x66 (320) getproperty
                    index: 5 (ENTER_FRAME)
                208 0xD0 (322) getlocal_0
                102 0x66 (323) getproperty
                    index: 4 (moveit)
                79 0x4F (325) callpropvoid
                    index: 6 (addEventListener)
                    arg_count: 2
                71 0x47 (328) returnvoid

            exception_count (329): 0
            trait_count (330): 0
        }
        method_body_info[2]{
            method (331): 2
            max_stack (332): 3
            local_count (333): 2
            init_scope_depth (334): 10
            max_scope_depth (335): 11
            code_length (336): 10
                208 0xD0 (337) getlocal_0
                48 0x30 (338) pushscope
                208 0xD0 (339) getlocal_0
                208 0xD0 (340) getlocal_0
                102 0x66 (341) getproperty
                    index: 7
                147 0x93 (343) decrement
                97 0x61 (344) setproperty
                    index: 7
                71 0x47 (346) returnvoid

            exception_count (347): 0
            trait_count (348): 0
        }
        method_body_info[3]{
            method (349): 3
            max_stack (350): 2
            local_count (351): 1
            init_scope_depth (352): 1
            max_scope_depth (353): 9
            code_length (354): 39
                208 0xD0 (355) getlocal_0
                48 0x30 (356) pushscope
                101 0x65 (357) getscopeobject
                    index: 0
                96 0x60 (359) getlex
                    index: 8
                48 0x30 (361) pushscope
                96 0x60 (362) getlex
                    index: 9
                48 0x30 (364) pushscope
                96 0x60 (365) getlex
                    index: 10
                48 0x30 (367) pushscope
                96 0x60 (368) getlex
                    index: 11
                48 0x30 (370) pushscope
                96 0x60 (371) getlex
                    index: 12
                48 0x30 (373) pushscope
                96 0x60 (374) getlex
                    index: 13
                48 0x30 (376) pushscope
                96 0x60 (377) getlex
                    index: 3
                48 0x30 (379) pushscope
                96 0x60 (380) getlex
                    index: 3
                88 0x58 (382) newclass
                    index: 0
                29 0x1D (384) popscope
                29 0x1D (385) popscope
                29 0x1D (386) popscope
                29 0x1D (387) popscope
                29 0x1D (388) popscope
                29 0x1D (389) popscope
                29 0x1D (390) popscope
                104 0x68 (391) initproperty
                    index: 2
                71 0x47 (393) returnvoid

            exception_count (394): 0
            trait_count (395): 0
        }
 }

ここで注目するのは、instance_info[0] です。これはクラスのランタイム インスタンスの定義であり、ここでは RedCircle になります。インスタンスには、さまざまなタイプの Traits の配列があります。RedCircle には、Trait_Method という種類の Trait (moveit) が 1 つあります。これは、Trait がメソッドへの参照を持っていることを意味します (2)。

したがって、method_body_info[1] (RedCircle のコンストラクター) にスキップすると、バイト 323 で getProperty がインデックス 4 で呼び出されていることがわかります。

102 0x66 (323) getproperty
                   index: 4 (moveit)

マルチネーム定数プールへの参照です。

multiname_info[4]{
    kind (225): CONSTANT_QName
    multiname_kind_QNAME{
        ns (225): 5
        name (226): 7 ("moveit")
    }
}

メソッドの呼び出しに関しては、インスタンスの特性で名前インデックスを検索します。

traits_info[0]{
    name (281): 4 (moveit)
    kind (282): Trait_Method
    ATTR_Final (0x1): false
    ATTR_Override (0x2): false
    ATTR_Metadata (0x4): false
    trait_method{
        disp_id (283): 0
        method (284): 2
    }
}

次に、関連するメソッドを呼び出します。

method_info[2]{
    param_count (263): 1
    return_type (264): 0
    param_type[0] (265): 1
    name (266): 0
    flags (267): 0
        NEED_ARGUMENTS (0x01): false
        NEED_ACTIVATION (0x02): false
        NEED_REST (0x04): false
        HAS_OPTIONAL (0x08): false
        SET_DXNS (0x40): false
        HAS_PARAM_NAMES (0x80): false
}

method_body_info[2]{
    method (331): 2
    max_stack (332): 3
    local_count (333): 2
    init_scope_depth (334): 10
    max_scope_depth (335): 11
    code_length (336): 10
        208 0xD0 (337) getlocal_0
        48 0x30 (338) pushscope
        208 0xD0 (339) getlocal_0
        208 0xD0 (340) getlocal_0
        102 0x66 (341) getproperty
                           index: 7 (x)
        147 0x93 (343) decrement
        97 0x61 (344) setproperty
                           index: 7 (x)
        71 0x47 (346) returnvoid
    exception_count (347): 0
    trait_count (348): 0
}

やや単純化された答えですが、いくつかの問題が解決されることを願っています。

于 2010-11-04T09:28:09.077 に答える
0

メソッド名は、クラスの特性に格納されているマルチネームであることがわかります。マルチネームテーブルではなく、文字列テーブルで特性名を探していたという事実によって、問題が悪化しました。おっとっと。

ただし、ABC ファイルではメソッド名フィールドが冗長になっているようです。

于 2010-11-04T10:37:32.483 に答える
0

私はちょうどこの瞬間に as3swf と as3abc ライブラリを調べています) そして getlex は as3abc lib で 2 回言及されています:

package com.codeazur.as3abc.factories
    public function create(code:int):AbstractOperation
        switch (code) {//in real life this switch block is really huge
             case Opcodes.GetLex:    return new MultinameOperation(code);
        }

と:

package com.codeazur.as3abc.data.bytecode
public class Opcodes

public static const GetLex:uint = 0x60;
_opNames[ GetLex ] = "GetLex";

私が理解しているように、それはAVM2内の単なるキーワードです。あなたの質問についてもっと詳しく:私はここだと思います:

getlex (flash.events.Event);
getproperty(ENTER_FRAME);
getlex (内部 .moveit);

callpropvoid(addEventListener, 2);

一種のイベント リスナーを追加していることがわかります (または、私は単に頭がおかしいかもしれません)。もう 1 つ言及する必要があります。以前のmoveit関数は、パラメーターとして受け入れる唯一の関数であるEventため、正確に呼び出すことは難しくありません。ところで、どうやって AVM2 に入ったのですか? おそらく、関数は非常に内部的であるため、このクラスのエンティティである場合にのみ名前が表示されます;)?
そして、これはadobeからのavm2バイトコードへのリンクです

于 2010-11-03T21:26:29.940 に答える