new tests for FQNs and namespaces, using pluginpath config

This commit is contained in:
honfika@gmail.com
2015-10-23 10:52:44 +02:00
parent f977c1c381
commit cbb3b1bff2
15 changed files with 227 additions and 20 deletions

View File

@@ -61,7 +61,6 @@ import java.util.Set;
*/
public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple {
//private final int executionLimit = 30000;
@Override
public void actionListParsed(ActionList actions, SWF swf) {
@@ -118,7 +117,7 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple {
MethodBody bodybefore = body;
body = bodybefore.clone();
setReg = getFirstRegisterSetter(assignmentRef, classIndex, isStatic, scriptIndex, abc, body, ignoredRegs, ignoredRegGets);
//System.err.println("setreg " + setReg + " ass:" + assignment);
//System.err.println("setreg " + setReg + " ass:" + assignmentRef.getVal());
if (setReg < 0) {
break;
}

View File

@@ -17,6 +17,7 @@
package com.jpexs.decompiler.flash.abc.types;
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
import com.jpexs.decompiler.flash.configuration.Configuration;
import java.util.HashMap;
import java.util.Map;
@@ -26,5 +27,11 @@ import java.util.Map;
*/
public class ConvertData {
public int deobfuscationMode;
public Map<TraitSlotConst, AssignedValue> assignedValues = new HashMap<>();
public ConvertData() {
deobfuscationMode = Configuration.autoDeobfuscate.get() ? (Configuration.deobfuscationOldMode.get() ? 0 : 1) : -1;
}
}

View File

@@ -30,6 +30,7 @@ import com.jpexs.decompiler.flash.abc.types.traits.Traits;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter;
import com.jpexs.decompiler.flash.helpers.NulWriter;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.decompiler.flash.types.annotations.SWFField;
@@ -294,7 +295,7 @@ public final class MethodBody implements Cloneable {
@Override
public Void call() throws InterruptedException {
try (Statistics s1 = new Statistics("MethodBody.convert")) {
MethodBody converted = convertMethodBody(path, isStatic, scriptIndex, classIndex, abc, trait, scopeStack, initializerType != GraphTextWriter.TRAIT_INSTANCE_INITIALIZER, fullyQualifiedNames, initTraits);
MethodBody converted = convertMethodBody(convertData, path, isStatic, scriptIndex, classIndex, abc, trait, scopeStack, initializerType != GraphTextWriter.TRAIT_INSTANCE_INITIALIZER, fullyQualifiedNames, initTraits);
HashMap<Integer, String> localRegNames = getLocalRegNames(abc);
List<GraphTargetItem> convertedItems1;
try (Statistics s = new Statistics("AVM2Code.toGraphTargetItems")) {
@@ -365,13 +366,13 @@ public final class MethodBody implements Cloneable {
return writer;
}
public MethodBody convertMethodBody(String path, boolean isStatic, int scriptIndex, int classIndex, ABC abc, Trait trait, ScopeStack scopeStack, boolean isStaticInitializer, List<DottedChain> fullyQualifiedNames, List<Traits> initTraits) throws InterruptedException {
public MethodBody convertMethodBody(ConvertData convertData, String path, boolean isStatic, int scriptIndex, int classIndex, ABC abc, Trait trait, ScopeStack scopeStack, boolean isStaticInitializer, List<DottedChain> fullyQualifiedNames, List<Traits> initTraits) throws InterruptedException {
MethodBody body = clone();
AVM2Code code = body.getCode();
code.markMappedOffsets();
code.fixJumps(path, body);
if (Configuration.autoDeobfuscate.get()) {
if (convertData.deobfuscationMode != -1) {
try {
code.removeTraps(trait, method_info, body, abc, scriptIndex, classIndex, isStatic, path);
} catch (ThreadDeath | InterruptedException ex) {
@@ -390,6 +391,23 @@ public final class MethodBody implements Cloneable {
return body;
}
public String toSource() {
ConvertData convertData = new ConvertData();
convertData.deobfuscationMode = -1;
try {
convert(convertData, "", ScriptExportMode.AS, false, method_info, 0, 0, abc, null, new ScopeStack(), 0, new NulWriter(), new ArrayList<>(), new ArrayList<>(), true);
HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), false);
writer.indent().indent().indent();
toString("", ScriptExportMode.AS, abc, null, writer, new ArrayList<>());
writer.unindent().unindent().unindent();
return writer.toString();
} catch (InterruptedException ex) {
Logger.getLogger(MethodBody.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
@Override
public MethodBody clone() {
try {

View File

@@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.types.MethodBody;
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
import com.jpexs.decompiler.flash.action.ActionList;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.Path;
@@ -53,9 +54,18 @@ public class SWFDecompilerPlugin {
public static void loadPlugins() {
try {
File f = new File(SWFDecompilerPlugin.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
File dir = f.getAbsoluteFile().getParentFile().getParentFile();
File pluginPath = new File(Path.combine(dir.getPath(), "plugins")).getCanonicalFile();
File pluginPath = null;
String pluginPathConfig = Configuration.pluginPath.get();
if (pluginPathConfig != null && !pluginPathConfig.isEmpty()) {
pluginPath = new File(pluginPathConfig);
}
if (pluginPath == null || !pluginPath.exists()) {
File f = new File(SWFDecompilerPlugin.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
File dir = f.getAbsoluteFile().getParentFile().getParentFile();
pluginPath = new File(Path.combine(dir.getPath(), "plugins")).getCanonicalFile();
}
if (pluginPath.exists()) {
System.out.println("Loading plugins from " + pluginPath.getPath());
File[] files = pluginPath.listFiles();

View File

@@ -17,6 +17,7 @@
package com.jpexs.decompiler.flash;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.ScriptPack;
import com.jpexs.decompiler.flash.abc.types.ConvertData;
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
import com.jpexs.decompiler.flash.configuration.Configuration;
@@ -32,6 +33,7 @@ import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
@@ -91,6 +93,23 @@ public class ActionScript3Test extends ActionScriptTestBase {
assertEquals(actualResult, expectedResult);
}
private void decompileScriptPack(String path, String expectedResult) {
ScriptPack scriptPack = abc.findScriptPackByPath(path, Arrays.asList(abc));
assertTrue(scriptPack != null);
HighlightedTextWriter writer = null;
try {
List<Traits> ts = new ArrayList<>();
ts.add(abc.instance_info.get(clsIndex).instance_traits);
writer = new HighlightedTextWriter(new CodeFormatting(), false);
scriptPack.toSource(writer, abc.script_info.get(scriptPack.scriptIndex).traits.traits, new ConvertData(), ScriptExportMode.AS, false);
} catch (InterruptedException ex) {
fail();
}
String actualResult = cleanPCode(writer.toString());
expectedResult = cleanPCode(expectedResult);
assertEquals(actualResult, expectedResult);
}
@Test
public void testHello() {
decompileMethod("testHello", "trace(\"hello\");\r\n", false);
@@ -934,6 +953,172 @@ public class ActionScript3Test extends ActionScriptTestBase {
+ "}\r\n", false);
}
//@Test
public void testMyPackage1TestClass() {
decompileScriptPack("classes.mypackage1.TestClass", "package classes.mypackage1\n"
+ "{\n"
+ " import classes.mypackage2.TestInterface;\n"
+ " import classes.mypackage2.TestClass;\n"
+ " \n"
+ " public class TestClass extends Object implements TestInterface\n"
+ " {\n"
+ " \n"
+ " public function TestClass()\n"
+ " {\n"
+ " super();\n"
+ " }\n"
+ " \n"
+ " public function testCall() : String\n"
+ " {\n"
+ " trace(\"pkg1hello\");\n"
+ " return \"pkg1hello\";\n"
+ " }\n"
+ " \n"
+ " public function testMethod1() : void\n"
+ " {\n"
+ " var a:classes.mypackage1.TestInterface = this;\n"
+ " a.testMethod1();\n"
+ " var b:classes.mypackage2.TestInterface = this;\n"
+ " b = new classes.mypackage2.TestClass();\n"
+ " }\n"
+ " \n"
+ " public function testMethod2() : void\n"
+ " {\n"
+ " var a:classes.mypackage1.TestInterface = this;\n"
+ " a.testMethod1();\n"
+ " var b:classes.mypackage2.TestInterface = this;\n"
+ " b = new classes.mypackage2.TestClass();\n"
+ " }\n"
+ " }\n"
+ "}");
}
//@Test
public void testMyPackage1TestClass2() {
decompileScriptPack("classes.mypackage1.TestClass2", "package classes.mypackage1\n"
+ "{\n"
+ " import classes.mypackage2.TestClass;\n"
+ " import classes.mypackage3.TestClass;\n"
+ " \n"
+ " public class TestClass2 extends Object\n"
+ " {\n"
+ " \n"
+ " public function TestClass2()\n"
+ " {\n"
+ " super();\n"
+ " }\n"
+ " \n"
+ " public function testCall() : *\n"
+ " {\n"
+ " var a:classes.mypackage1.TestClass = null;\n"
+ " var b:classes.mypackage2.TestClass = null;\n"
+ " var c:classes.mypackage3.TestClass = null;\n"
+ " a = new classes.mypackage1.TestClass();\n"
+ " b = new classes.mypackage2.TestClass();\n"
+ " c = new classes.mypackage3.TestClass();\n"
+ " var res:String = a.testCall() + b.testCall() + c.testCall() + this.testCall2() + myNamespace::testCall3();\n"
+ " trace(res);\n"
+ " return res;\n"
+ " }\n"
+ " \n"
+ " myNamespace function testCall2() : String\n"
+ " {\n"
+ " return \"1\";\n"
+ " }\n"
+ " \n"
+ " myNamespace function testCall3() : String\n"
+ " {\n"
+ " return myNamespace::testCall2();\n"
+ " }\n"
+ " \n"
+ " public function testCall2() : String\n"
+ " {\n"
+ " return \"2\";\n"
+ " }\n"
+ " }\n"
+ "}");
}
//@Test
public void testMyPackage1TestInterface() {
decompileScriptPack("classes.mypackage1.TestInterface", "package classes.mypackage1\n"
+ "{\n"
+ " import classes.mypackage2.TestInterface;\n"
+ " \n"
+ " public interface TestInterface extends classes.mypackage2.TestInterface\n"
+ " {\n"
+ " \n"
+ " function testMethod1() : void;\n"
+ " }\n"
+ "}");
}
@Test
public void testMyPackage1MyNamespace() {
decompileScriptPack("classes.mypackage1.myNamespace", "package classes.mypackage1\n"
+ "{\n"
+ " public namespace myNamespace = \"https://www.free-decompiler.com/flash/test/namespace\";\n"
+ "}");
}
@Test
public void testMyPackage2TestClass() {
decompileScriptPack("classes.mypackage2.TestClass", "package classes.mypackage2\n"
+ "{\n"
+ " public class TestClass extends Object implements TestInterface\n"
+ " {\n"
+ " \n"
+ " public function TestClass()\n"
+ " {\n"
+ " super();\n"
+ " }\n"
+ " \n"
+ " public function testCall() : String\n"
+ " {\n"
+ " trace(\"pkg2hello\");\n"
+ " return \"pkg2hello\";\n"
+ " }\n"
+ " \n"
+ " public function testMethod2() : void\n"
+ " {\n"
+ " }\n"
+ " }\n"
+ "}");
}
@Test
public void testMyPackage2TestInterface() {
decompileScriptPack("classes.mypackage2.TestInterface", "package classes.mypackage2\n"
+ "{\n"
+ " public interface TestInterface\n"
+ " {\n"
+ " \n"
+ " function testMethod2() : void;\n"
+ " }\n"
+ "}");
}
@Test
public void testMyPackage3TestClass() {
decompileScriptPack("classes.mypackage3.TestClass", "package classes.mypackage3\n"
+ "{\n"
+ " public class TestClass extends Object\n"
+ " {\n"
+ " \n"
+ " public function TestClass()\n"
+ " {\n"
+ " super();\n"
+ " }\n"
+ " \n"
+ " public function testCall() : String\n"
+ " {\n"
+ " trace(\"pkg3hello\");\n"
+ " return \"pkg3hello\";\n"
+ " }\n"
+ " }\n"
+ "}");
}
@Test
public void testOptionalParameters() {
String methodName = "testOptionalParameters";

View File

@@ -1146,9 +1146,6 @@ public class Main {
public static void main(String[] args) throws IOException {
clearTemp();
//String pluginPath = Configuration.pluginPath.get();
//if (pluginPath != null && !pluginPath.isEmpty()) {
//}
try {
SWFDecompilerPlugin.loadPlugins();

View File

@@ -260,7 +260,6 @@ config.description.textExportExportFontFace = Embed font files in SVG using font
config.name.lzmaFastBytes = LZMA fast bytes (valid values: 5-255)
config.description.lzmaFastBytes = Fast bytes parameter of the LZMA encoder
#temporary setting, do not translate it
config.name.pluginPath = Plugin Path
config.description.pluginPath = -

View File

@@ -260,7 +260,6 @@ config.description.textExportExportFontFace = Incrusta els fitxers de tipografie
config.name.lzmaFastBytes = Bytes r\u00e0pids LZMA (v\u00e0lors valids: 5-255)
config.description.lzmaFastBytes = Par\u00e0metre de bytes r\u00e0pids del codificador LZMA
#temporary setting, do not translate it
config.name.pluginPath = Cam\u00ed de l'Extensi\u00f3
config.description.pluginPath = -

View File

@@ -260,7 +260,6 @@ config.description.textExportExportFontFace = Vkl\u00e1dat soubory p\u00edsem do
config.name.lzmaFastBytes = LZMA fast bytes (platn\u00e9 hodnoty: 5-255)
config.description.lzmaFastBytes = Parametr fast bytes LZMA enkoderu
#temporary setting, do not translate it
config.name.pluginPath = Plugin Path
config.description.pluginPath = -

View File

@@ -260,7 +260,6 @@ config.description.textExportExportFontFace = Incrustar archivos de fuente en el
config.name.lzmaFastBytes = Bytes r\u00e1pidos de LZMA (valores v\u00e1lidos: 5-255)
config.description.lzmaFastBytes = Par\u00e1metro de bytes r\u00e1pidos del codificador LZMA
#temporary setting, do not translate it
config.name.pluginPath = Directorio de Plugin
config.description.pluginPath = -

View File

@@ -260,7 +260,6 @@ config.description.textExportExportFontFace = Embarquer le style de police de ca
config.name.lzmaFastBytes = LZMA fast bytes (valeurs permises : 5-255)
config.description.lzmaFastBytes = Param\u00e8tre vitesse des octets de l'encodeur LZMA
#temporary setting, do not translate it
config.name.pluginPath = Plugin Path
config.description.pluginPath = -

View File

@@ -260,7 +260,6 @@ config.description.textExportExportFontFace = Bet\u0171t\u00edpus f\u00e1jlok be
config.name.lzmaFastBytes = LZMA fast bytes (\u00e9rv\u00e9nyes \u00e9rt\u00e9kek: 5-255)
config.description.lzmaFastBytes = Az LZMA t\u00f6m\u00f6r\u00edt\u0151 "Fast bytes" param\u00e9tere
#temporary setting, do not translate it
config.name.pluginPath = Plugin Path
config.description.pluginPath = -

View File

@@ -260,7 +260,6 @@ config.description.textExportExportFontFace = Incorpora font in SVG utilizzando
config.name.lzmaFastBytes = Byte LZMA veloci (valori validi: 5-255)
config.description.lzmaFastBytes = Parametro byte veloci del codificatore LZMA
#temporary setting, do not translate it
config.name.pluginPath = Percorso Plugin
config.description.pluginPath = -

View File

@@ -263,7 +263,6 @@ config.description.lzmaFastBytes = Parametr fast bytes kodera LZMA
config.name.showMethodBodyId = Poka\u017c id korpusu metody
config.description.showMethodBodyId = Pokazuje id korpusu metody dla importu linii polece\u0144
#temporary setting, do not translate it
config.name.pluginPath = Plugin Path
config.description.pluginPath = -

View File

@@ -260,7 +260,6 @@ config.description.textExportExportFontFace = B\u00e4dda in typsnitssfiler i SVG
config.name.lzmaFastBytes = LZMA snabba bytes (Giltiga v\u00e4rden: 5-255)
config.description.lzmaFastBytes = Snabb bytes parameter av LZMA kodare
#temporary setting, do not translate it
config.name.pluginPath = Plugin S\u00f6kv\u00e4g
config.description.pluginPath = -