izb*_*izb 5 flash actionscript bytecode actionscript-3 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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
其编译类似于:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是'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
}
}
Run Code Online (Sandbox Code Playgroud)
你在这里感兴趣的是instance_info [0].这是类的运行时实例的定义,这里将是RedCircle.实例具有各种类型的特征数组.RedCircle有一种Trait_Method特征(moveit),这意味着特征引用了方法(2).
因此,如果跳到method_body_info [1](RedCircle的构造函数),您可以在字节323看到调用getProperty时索引为4.
102 0x66 (323) getproperty
index: 4 (moveit)
Run Code Online (Sandbox Code Playgroud)
这是对多个名称常量池的引用.
multiname_info[4]{
kind (225): CONSTANT_QName
multiname_kind_QNAME{
ns (225): 5
name (226): 7 ("moveit")
}
}
Run Code Online (Sandbox Code Playgroud)
在调用方法时,它会在实例的特征中查找名称索引.
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
}
}
Run Code Online (Sandbox Code Playgroud)
然后调用相关方法.
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
}
Run Code Online (Sandbox Code Playgroud)
一个简化的答案,但我希望它能解决一些问题.