首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在AVM2字节码中找到方法?

如何在AVM2字节码中找到方法?
EN

Stack Overflow用户
提问于 2010-11-04 00:33:39
回答 3查看 2.5K关注 0票数 5

我一直在尝试使用ABC字节码,希望有人能为我澄清一个困惑之处。我有一个简单的flash文件,它将一个剪辑放在舞台上,并有一个小脚本来更新它在每一帧上的位置。代码看起来像这样:

代码语言:javascript
复制
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;
          }
     }
}

它编译成类似这样的内容:

代码语言:javascript
复制
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‘方法的多名称。不幸的是,方法信息中的'name‘字段似乎从未被编译器使用过。所有方法的名称都是空字符串(上面显示为###2中的未命名函数)。

flash player如何将多名称链接到未命名的方法?在AVM2规范中似乎没有这方面的规定。

我知道这是可能的,因为像sothink这样的商业反编译器会设法确定方法名称。我只是不确定他们是如何做到这一点的,或者代码是如何工作的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-11-04 17:28:09

我不知道为什么你的反编译器会把这个方法显示为(匿名)。

下面是abcData的转储文件:

代码语言:javascript
复制
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。这是一个类的运行时实例的定义,在这里应该是RedCircle。实例有一系列不同类型的特征。RedCircle有一个Trait_Method类型的特征(moveit),这意味着该特征引用了一个方法(2)。

所以如果你跳到method_body_info,1,你可以看到在323字节,getProperty被调用,索引为4。

代码语言:javascript
复制
102 0x66 (323) getproperty
                   index: 4 (moveit)

它是对多名称常量池的引用。

代码语言:javascript
复制
multiname_info[4]{
    kind (225): CONSTANT_QName
    multiname_kind_QNAME{
        ns (225): 5
        name (226): 7 ("moveit")
    }
}

当涉及到调用该方法时,它会在实例的特征中查找名称索引。

代码语言:javascript
复制
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
    }
}

然后调用相关的方法。

代码语言:javascript
复制
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
}

这是一个比较简单的答案,但我希望它能澄清一些问题。

票数 5
EN

Stack Overflow用户

发布于 2010-11-04 05:26:30

我现在正在探索as3swf和as3abc库),as3abc库中提到了两次:

代码语言:javascript
复制
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);
        }

和:

代码语言:javascript
复制
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);

代码语言:javascript
复制
           callpropvoid(addEventListener, 2);

(内部.moveit);getlex

我们可以看到添加了一种事件侦听器(或者可能我只是疯了),还有一件事要提一下:您以前的moveit函数是唯一一个接受Event作为参数的函数,所以准确地调用它并不难。顺便问一下:你是如何进入AVM2的?也许这个函数是如此内部,以至于它的名称只有当你是这个类中的一个实体时才可见;)?

and here's a link to some avm2 bytecode from adobe

票数 0
EN

Stack Overflow用户

发布于 2010-11-04 18:37:32

原来,方法名是存储在类特征中的多个名称;我在字符串表中查找特征名称,而不是在多名称表中查找,这使问题变得更加复杂。糟了。

但是,在ABC文件中,方法名字段似乎是多余的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4089291

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档