PDA

Просмотр полной версии : Инъекция опкода в тело метода


DEVORON
22.05.2018, 14:41
[решено]

Используя библиотеку org.as3commons.bytecode изменяю в классе TestClass тело метода

public function exe():void
{

}

Пытаюсь добавить внутрь него следующую инструкцию
classProxy.exe(arguments);

Пока удалось добавить
classProxy.exe();

Следующим образом


public function injectOpcodesIntoMethod(abcFile:AbcFile):void
{
for (var classIndex:int = 0; classIndex < abcFile.instanceInfo.length; ++classIndex)
{
var instance:InstanceInfo = abcFile.instanceInfo[classIndex];
var item:TraitInfo;
for each (item in instance.traits)
{
if (item is MethodTrait)
{
var methodTrait:MethodTrait = item as MethodTrait;


if (String(methodTrait.traitMultiname) == "QName[Namespace[public]:exe]")
{
var opcodes:Vector.<Op> = methodTrait.traitMethod.methodBody.opcodes;

var qn1:QualifiedName = new QualifiedName("classProxy", LNamespace.PUBLIC);
var op1:Op = new Op(Opcode.getlex, [qn1]);
var nk:NamespaceKind = NamespaceKind.determineKind(22);
var ln:LNamespace = new LNamespace(nk, "");

var qn2:QualifiedName = new QualifiedName(methodTrait.traitMethod.methodName, ln);
var op2:Op = new Op(Opcode.callpropvoid, [qn2, 0]);

opcodes.splice(2, 0, op1, op2);
break;
}

}
}
}
}

Если попытаться вывести classProxy.exe(arguments); в виде опкодов через декомпил, то получаем

callpropvoid Multiname("exe",[PrivateNamespace("TestClass"),ProtectedNamespace("TestClass"),StaticProtectedNs("TestClass"),StaticProtectedNs("flash.display:Sprite"),StaticProtectedNs("flash.display:DisplayObjectContainer"),StaticProtectedNs("flash.display:InteractiveObject"),StaticProtectedNs("flash.display:DisplayObject"),StaticProtectedNs("flash.events:EventDispatcher"),StaticProtectedNs("Object"),PackageNamespace(""),PackageInternalNs(""),PrivateNamespace("FilePrivateNS:TestClass"),Namespace("http://adobe.com/AS3/2006/builtin")])

словом, невероятно длинную запись аргумента arguments.

Если кто-нибудь работал с этой библиотекой или может подсказать, как иначе внедрить внутрь метода конструкцию вида classProxy.exe(arguments);, очень прошу)

Добавлено через 8 часов 49 минут
UPD. У меня не получилось сделать

classProxy.exe(arguments);

Но удалось встроить rest-параметр и передать его в вызываемом методе. Для решения сойдёт.

public function exe(... rest) : void
{
classProxy.exe(rest);
}

Код такой, если кому нужно будет.

var opcodes:Vector.<Op> = methodTrait.traitMethod.methodBody.opcodes;

var testFlags:uint = 0;
testFlags = MethodFlag.addFlag(testFlags, MethodFlag.HAS_PARAM_NAMES);
testFlags = MethodFlag.addFlag(testFlags, MethodFlag.NEED_REST);
methodTrait.traitMethod.flags = testFlags;


var qn1:QualifiedName = new QualifiedName("classProxy", LNamespace.PUBLIC);
var op1:Op = new Op(Opcode.getlex, [qn1]);
var nk:NamespaceKind = NamespaceKind.determineKind(22);
var ln:LNamespace = new LNamespace(nk, "");

var qn2:QualifiedName = new QualifiedName(methodTrait.traitMethod.methodName, ln);

var op2:Op = new Op(Opcode.callpropvoid, [qn2, 1]);

var op3:Op = new Op(Opcode.getlocal_1);


opcodes2.splice(2, 0, op1, op5, op2);

Тему можно считать закрытой)