如何在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这样的商业反编译器会设法确定方法名称。我只是不确定他们是如何做到的,或者代码是如何工作的。
没有找到相关结果
已邀请:
3 个回复
浆错
你在这里感兴趣的是instance_info [0]。这是类的运行时实例的定义,这里将是RedCircle。实例具有各种类型的特征数组。 RedCircle有一种Trait_Method特征(moveit),这意味着特征引用了方法(2)。 因此,如果跳到method_body_info [1](RedCircle的构造函数),您可以在字节323看到调用getProperty时索引为4。
这是对多个名称常量池的引用。
在调用方法时,它会在实例的特征中查找名称索引。
然后调用相关方法。
一个简化的答案,但我希望它能解决一些问题。
旅牢斯讲
和:
所以据我所知它只是AVM2中的一个关键字。并且更密切地关注你的问题:我想在这里: getlex(对象类型:flash.events.Event); 的getProperty(ENTER_FRAME); getlex(内部.moveit); callpropvoid(addEventListener,2); 我们可以看到一种添加事件监听器(或者我只是疯了)还有一件事需要提及:你以前的
函数是唯一一个接受
作为参数的函数,因此不难调用它。顺便说一句:你是如何进入AVM2的?也许这个函数是如此内部,只有当你是这个类中的实体时,它的名字才是可见的;)? 这里是adobe的一些avm2字节码的链接
伞腹