How are methods found in AVM2 bytecode?

天涯浪子 提交于 2019-12-04 09:19:25

I'm not sure why your decompiler shows the method as (anonymous).

Here is a dump of the 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
        }
 }

What you're interested in here is instance_info[0]. This is the definition of a run-time instance of a class, which would be RedCircle here. Instances have an array of Traits of various types. RedCircle has one trait (moveit) of kind Trait_Method which means the trait has a reference to a method (2).

So if you skip to method_body_info[1] (the constructor of RedCircle) you can see at byte 323 that getProperty is called with an index of 4.

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

Which is a reference to the multiname constant pool.

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

When it comes to calling the method it looks up the name index in the traits for the instance.

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
    }
}

Then calls the relevant method.

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
}

A somewhat simplified answer, but I hope it clears up a few issues.

i'm exploring as3swf and as3abc libs exactly at this current moment) and getlex is mentioned twice in as3abc lib:

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);
        }

and:

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

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

so as i understand it's just a keyword inside AVM2. and more closely about your question: i think here:

getlex(flash.events.Event);
getproperty(ENTER_FRAME);
getlex(internal .moveit);

callpropvoid(addEventListener, 2);

we can see a kind of adding an event listener (or maybe i'm just crazy) and one more thing to mention: your former moveit function is the only one that accepts Event as a parameter so it's not hard to call exactly it. And by the way: how did you get inside AVM2? maybe the function is so internal that it's name is visible only if you are an entity in this class ;)?
and here's a link to some avm2 bytecode from adobe

Turns out that the method names are multinames stored in the class traits; a problem compounded by the fact that I was looking for the trait names in the string table, not the multiname table. Oops.

Seems though, that the method name field is redundant in the ABC file.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!