mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-05-22 18:25:51 +00:00
further as2/3 execution fixes
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. */
|
||||
package com.jpexs.decompiler.flash;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Runtime;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2RuntimeInfo;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.exceptions.AVM2ExecutionException;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodBody;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.tags.DoABC2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.fail;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ActionScript3ExecuteTest {
|
||||
|
||||
private SWF swf;
|
||||
|
||||
private ABC abc;
|
||||
|
||||
@BeforeClass
|
||||
public void init() throws IOException, InterruptedException {
|
||||
//Main.initLogging(false);
|
||||
swf = new SWF(new BufferedInputStream(new FileInputStream("testdata/run_as3/run.swf")), false);
|
||||
/*try (InputStream is = new BufferedInputStream(new FileInputStream("testdata/run_as3/run.swf"))) {
|
||||
swf = new SWF(is, false);
|
||||
}*/
|
||||
DoABC2Tag tag = null;
|
||||
for (Tag t : swf.tags) {
|
||||
if (t instanceof DoABC2Tag) {
|
||||
tag = (DoABC2Tag) t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assertNotNull(tag);
|
||||
this.abc = tag.getABC();
|
||||
Configuration.autoDeobfuscate.set(false);
|
||||
Configuration.decompile.set(true);
|
||||
Configuration.registerNameFormat.set("_loc%d_");
|
||||
Configuration.showMethodBodyId.set(false);
|
||||
}
|
||||
|
||||
//@Test
|
||||
public void testRun() throws IOException, InterruptedException {
|
||||
MethodBody body = abc.findBodyByClassAndName("Run", "run");
|
||||
Object result;
|
||||
try {
|
||||
result = body.getCode().execute(new HashMap<>(), abc.constants, new AVM2RuntimeInfo(AVM2Runtime.ADOBE_FLASH, 19, true));
|
||||
assertEquals(result, "Test");
|
||||
} catch (AVM2ExecutionException ex) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddMethod() throws IOException, InterruptedException {
|
||||
int classId = abc.findClassByName("Run");
|
||||
MethodBody runBody = abc.findBodyByClassAndName("Run", "runInstance");
|
||||
runBody.max_stack = 10;
|
||||
|
||||
AVM2Code ccode = new AVM2Code();
|
||||
ccode.code = new ArrayList<>();
|
||||
List<AVM2Instruction> code = ccode.code;
|
||||
code.add(new AVM2Instruction(0, AVM2Instructions.GetLocal0, null));
|
||||
code.add(new AVM2Instruction(0, AVM2Instructions.PushScope, null));
|
||||
code.add(new AVM2Instruction(0, AVM2Instructions.PushString, new int[]{abc.constants.getStringId("", true)}));
|
||||
|
||||
for (int testMethodId = 1; testMethodId < 10; testMethodId++) {
|
||||
AVM2Code ccode2 = new AVM2Code();
|
||||
ccode2.code = new ArrayList<>();
|
||||
List<AVM2Instruction> code2 = ccode2.code;
|
||||
code2.add(new AVM2Instruction(0, AVM2Instructions.GetLocal0, null));
|
||||
code2.add(new AVM2Instruction(0, AVM2Instructions.PushScope, null));
|
||||
code2.add(new AVM2Instruction(0, AVM2Instructions.PushString, new int[]{abc.constants.getStringId(testMethodId + ""/* + "\r\n"*/, true)}));
|
||||
code2.add(new AVM2Instruction(0, AVM2Instructions.ReturnValue, null));
|
||||
|
||||
boolean isStatic = testMethodId % 2 == 0;
|
||||
int multinameId = addMethod(classId, "test" + testMethodId, isStatic, ccode2);
|
||||
if (isStatic) {
|
||||
code.add(new AVM2Instruction(0, AVM2Instructions.FindPropertyStrict, new int[]{multinameId}));
|
||||
} else {
|
||||
code.add(new AVM2Instruction(0, AVM2Instructions.GetLocal0, null));
|
||||
}
|
||||
|
||||
code.add(new AVM2Instruction(0, AVM2Instructions.CallProperty, new int[]{multinameId, 0}));
|
||||
code.add(new AVM2Instruction(0, AVM2Instructions.Add, null));
|
||||
code.add(new AVM2Instruction(0, AVM2Instructions.PushString, new int[]{abc.constants.getStringId("\r\n", true)}));
|
||||
code.add(new AVM2Instruction(0, AVM2Instructions.Add, null));
|
||||
}
|
||||
|
||||
code.add(new AVM2Instruction(0, AVM2Instructions.ReturnValue, null));
|
||||
runBody.setCode(ccode);
|
||||
runBody.markOffsets();
|
||||
}
|
||||
|
||||
private int addMethod(int classId, String name, boolean isStatic, AVM2Code code) {
|
||||
TraitMethodGetterSetter methodTrait = abc.addMethod(classId, name, isStatic);
|
||||
MethodInfo methodInfo = abc.method_info.get(methodTrait.method_info);
|
||||
MethodBody methodBody = methodInfo.getBody();
|
||||
methodBody.max_stack = 10;
|
||||
methodBody.max_regs = 10;
|
||||
methodBody.init_scope_depth = 3;
|
||||
methodBody.max_scope_depth = 10;
|
||||
|
||||
methodBody.setCode(code);
|
||||
methodBody.markOffsets();
|
||||
|
||||
return methodTrait.name_index;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user