flash – 如何在AVM2字节码中找到方法?
我一直在玩ABC字节码,并希望有人可以为我解决一个混乱点.我有一个简单的Flash文件,可以在舞台上放置一个剪辑,并有一个小脚本来更新它在每个帧上的位置.代码看起来像:
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’方法的multiname.不幸的是,方法信息中的’name’字段似乎永远不会被编译器使用.所有方法都将空字符串作为其名称(在上面显示为### 2处的未命名函数). Flash播放器如何将多个名称链接到未命名的方法?在AVM2规范中似乎没有这方面的规定. 我知道这是可能的,因为像sothink这样的商业反编译器会设法确定方法名称.我只是不确定他们是如何做到的,或者代码是如何工作的. 解决方法
我不确定为什么你的反编译器将该方法显示为(匿名).
这是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.实例具有各种类型的特征数组. RedCircle有一种Trait_Method特征(moveit),这意味着特征引用了方法(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 } 一个简化的答案,但我希望它能解决一些问题. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |